diff options
Diffstat (limited to 'devtools/server/actors/utils/dbg-source.js')
-rw-r--r-- | devtools/server/actors/utils/dbg-source.js | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/devtools/server/actors/utils/dbg-source.js b/devtools/server/actors/utils/dbg-source.js new file mode 100644 index 0000000000..9c4111dfaa --- /dev/null +++ b/devtools/server/actors/utils/dbg-source.js @@ -0,0 +1,97 @@ +/* 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; |