97 lines
3 KiB
JavaScript
97 lines
3 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
"use strict";
|
|
|
|
/**
|
|
* Get the source text offset equivalent to a given line/column pair.
|
|
*
|
|
* @param {Debugger.Source} source
|
|
* @param {number} line The 1-based line number.
|
|
* @param {number} column The 0-based column number.
|
|
* @returns {number} The codepoint offset into the source's text.
|
|
*/
|
|
function findSourceOffset(source, line, column) {
|
|
const offsets = getSourceLineOffsets(source);
|
|
const offset = offsets[line - 1];
|
|
|
|
if (offset) {
|
|
// Make sure that columns that technically don't exist in the line text
|
|
// don't cause the offset to wrap to the next line.
|
|
return Math.min(offset.start + column, offset.textEnd);
|
|
}
|
|
|
|
return line < 0 ? 0 : offsets[offsets.length - 1].end;
|
|
}
|
|
exports.findSourceOffset = findSourceOffset;
|
|
|
|
const NEWLINE = /(\r?\n|\r|\u2028|\u2029)/g;
|
|
const SOURCE_OFFSETS = new WeakMap();
|
|
/**
|
|
* Generate and cache line information for a given source to track what
|
|
* text offsets mark the start and end of lines. Each entry in the array
|
|
* represents a line in the source text.
|
|
*
|
|
* @param {Debugger.Source} source
|
|
* @returns {Array<{ start, textEnd, end }>}
|
|
* - start - The codepoint offset of the start of the line.
|
|
* - textEnd - The codepoint offset just after the last non-newline character.
|
|
* - end - The codepoint offset of the end of the line. This will be
|
|
* be the same as the 'start' value of the next offset object,
|
|
* and this includes the newlines for the line itself, where
|
|
* 'textEnd' excludes newline characters.
|
|
*/
|
|
function getSourceLineOffsets(source) {
|
|
const cached = SOURCE_OFFSETS.get(source);
|
|
if (cached) {
|
|
return cached;
|
|
}
|
|
|
|
const { text } = source;
|
|
|
|
const lines = text.split(NEWLINE);
|
|
|
|
const offsets = [];
|
|
let offset = 0;
|
|
for (let i = 0; i < lines.length; i += 2) {
|
|
const line = lines[i];
|
|
const start = offset;
|
|
|
|
// Calculate the end codepoint offset.
|
|
let end = offset;
|
|
// eslint-disable-next-line no-unused-vars
|
|
for (const c of line) {
|
|
end++;
|
|
}
|
|
const textEnd = end;
|
|
|
|
if (i + 1 < lines.length) {
|
|
end += lines[i + 1].length;
|
|
}
|
|
|
|
offsets.push(Object.freeze({ start, textEnd, end }));
|
|
offset = end;
|
|
}
|
|
Object.freeze(offsets);
|
|
|
|
SOURCE_OFFSETS.set(source, offsets);
|
|
return offsets;
|
|
}
|
|
|
|
/**
|
|
* Given a target actor and a source platform internal ID,
|
|
* return the related SourceActor ID.
|
|
|
|
* @param TargetActor targetActor
|
|
* The Target Actor from which this source originates.
|
|
* @param String id
|
|
* Platform Source ID
|
|
* @return String
|
|
* The SourceActor ID
|
|
*/
|
|
function getActorIdForInternalSourceId(targetActor, id) {
|
|
const actor = targetActor.sourcesManager.getSourceActorByInternalSourceId(id);
|
|
return actor ? actor.actorID : null;
|
|
}
|
|
exports.getActorIdForInternalSourceId = getActorIdForInternalSourceId;
|