dbg-source.js (3040B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 /** 8 * Get the source text offset equivalent to a given line/column pair. 9 * 10 * @param {Debugger.Source} source 11 * @param {number} line The 1-based line number. 12 * @param {number} column The 0-based column number. 13 * @returns {number} The codepoint offset into the source's text. 14 */ 15 function findSourceOffset(source, line, column) { 16 const offsets = getSourceLineOffsets(source); 17 const offset = offsets[line - 1]; 18 19 if (offset) { 20 // Make sure that columns that technically don't exist in the line text 21 // don't cause the offset to wrap to the next line. 22 return Math.min(offset.start + column, offset.textEnd); 23 } 24 25 return line < 0 ? 0 : offsets[offsets.length - 1].end; 26 } 27 exports.findSourceOffset = findSourceOffset; 28 29 const NEWLINE = /(\r?\n|\r|\u2028|\u2029)/g; 30 const SOURCE_OFFSETS = new WeakMap(); 31 /** 32 * Generate and cache line information for a given source to track what 33 * text offsets mark the start and end of lines. Each entry in the array 34 * represents a line in the source text. 35 * 36 * @param {Debugger.Source} source 37 * @returns {Array<{ start, textEnd, end }>} 38 * - start - The codepoint offset of the start of the line. 39 * - textEnd - The codepoint offset just after the last non-newline character. 40 * - end - The codepoint offset of the end of the line. This will be 41 * be the same as the 'start' value of the next offset object, 42 * and this includes the newlines for the line itself, where 43 * 'textEnd' excludes newline characters. 44 */ 45 function getSourceLineOffsets(source) { 46 const cached = SOURCE_OFFSETS.get(source); 47 if (cached) { 48 return cached; 49 } 50 51 const { text } = source; 52 53 const lines = text.split(NEWLINE); 54 55 const offsets = []; 56 let offset = 0; 57 for (let i = 0; i < lines.length; i += 2) { 58 const line = lines[i]; 59 const start = offset; 60 61 // Calculate the end codepoint offset. 62 let end = offset; 63 // eslint-disable-next-line no-unused-vars 64 for (const c of line) { 65 end++; 66 } 67 const textEnd = end; 68 69 if (i + 1 < lines.length) { 70 end += lines[i + 1].length; 71 } 72 73 offsets.push(Object.freeze({ start, textEnd, end })); 74 offset = end; 75 } 76 Object.freeze(offsets); 77 78 SOURCE_OFFSETS.set(source, offsets); 79 return offsets; 80 } 81 82 /** 83 * Given a target actor and a source platform internal ID, 84 * return the related SourceActor ID. 85 86 * @param TargetActor targetActor 87 * The Target Actor from which this source originates. 88 * @param String id 89 * Platform Source ID 90 * @return String 91 * The SourceActor ID 92 */ 93 function getActorIdForInternalSourceId(targetActor, id) { 94 const actor = targetActor.sourcesManager.getSourceActorByInternalSourceId(id); 95 return actor ? actor.actorID : null; 96 } 97 exports.getActorIdForInternalSourceId = getActorIdForInternalSourceId;