From 8769806b407dab89ca58e0fb9b3765d00e6faa3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20Bru=C3=ABl?= Date: Wed, 1 Apr 2015 11:03:57 +0200 Subject: [PATCH] Bug 1129784 - Implement column sliding for source mapped sources;r=jlong --- .../test/browser_dbg_pretty-print-08.js | 2 +- toolkit/devtools/server/actors/common.js | 2 +- toolkit/devtools/server/actors/script.js | 115 +++++++++--------- .../server/actors/utils/TabSources.js | 51 +++----- 4 files changed, 79 insertions(+), 91 deletions(-) diff --git a/browser/devtools/debugger/test/browser_dbg_pretty-print-08.js b/browser/devtools/debugger/test/browser_dbg_pretty-print-08.js index 50c1f1c9bb8b..3e95697a9bbd 100644 --- a/browser/devtools/debugger/test/browser_dbg_pretty-print-08.js +++ b/browser/devtools/debugger/test/browser_dbg_pretty-print-08.js @@ -21,7 +21,7 @@ function test() { const BP_LOCATION = { line: 5, - column: 11 + // column: 0 }; function findSource() { diff --git a/toolkit/devtools/server/actors/common.js b/toolkit/devtools/server/actors/common.js index 905b0b6ae2a7..9da7de7fa9e2 100644 --- a/toolkit/devtools/server/actors/common.js +++ b/toolkit/devtools/server/actors/common.js @@ -439,7 +439,7 @@ GeneratedLocation.prototype = { equals: function (other) { return this.generatedSourceActor.url == other.generatedSourceActor.url && - this.generatedLine === other.originalLine; + this.generatedLine === other.generatedLine; }, toJSON: function () { diff --git a/toolkit/devtools/server/actors/script.js b/toolkit/devtools/server/actors/script.js index a22cb62786c8..2129206a8fc3 100644 --- a/toolkit/devtools/server/actors/script.js +++ b/toolkit/devtools/server/actors/script.js @@ -2605,44 +2605,22 @@ SourceActor.prototype = { return DevToolsUtils.yieldingEach(mappings._array, m => { let mapping = { generated: { - line: m.generatedLine, - column: m.generatedColumn + line: m.originalLine, + column: m.originalColumn } }; if (m.source) { mapping.source = m.source; mapping.original = { - line: m.originalLine, - column: m.originalColumn + line: m.generatedLine, + column: m.generatedColumn }; mapping.name = m.name; } generator.addMapping(mapping); }).then(() => { generator.setSourceContent(this.url, code); - const consumer = SourceMapConsumer.fromSourceMap(generator); - - // XXX bug 918802: Monkey punch the source map consumer, because iterating - // over all mappings and inverting each of them, and then creating a new - // SourceMapConsumer is slow. - - const getOrigPos = consumer.originalPositionFor.bind(consumer); - const getGenPos = consumer.generatedPositionFor.bind(consumer); - - consumer.originalPositionFor = ({ line, column }) => { - const location = getGenPos({ - line: line, - column: column, - source: this.url - }); - location.source = this.url; - return location; - }; - - consumer.generatedPositionFor = ({ line, column }) => getOrigPos({ - line: line, - column: column - }); + let consumer = SourceMapConsumer.fromSourceMap(generator); return { code: code, @@ -2896,40 +2874,63 @@ SourceActor.prototype = { return originalLocation; } } else { - if (originalColumn === undefined) { - let loop = (actualLocation) => { - let { - originalLine: actualLine, - originalColumn: actualColumn - } = actualLocation; + let slideByColumn = (actualColumn) => { + return this.sources.getAllGeneratedLocations(new OriginalLocation( + this, + originalLine, + actualColumn + )).then((generatedLocations) => { + // Because getAllGeneratedLocations will always return the list of + // generated locations for the closest column that is greater than + // the one we are searching for if no exact match can be found, if + // the list of generated locations is empty, we've reached the end + // of the original line, and sliding continues by line. + if (generatedLocations.length === 0) { + return slideByLine(originalLine + 1); + } - return this.threadActor.sources.getAllGeneratedLocations(actualLocation) - .then((generatedLocations) => { - // Because getAllGeneratedLocations will always return the list of - // generated locations for the closest line that is greater than - // the one we are searching for if no exact match can be found, if - // the list of generated locations is empty, we've reached the end - // of the original source, and breakpoint sliding failed. - if (generatedLocations.length === 0) { - return originalLocation; - } + // If at least one script has an offset that matches one of the + // generated locations in the list, then breakpoint sliding + // succeeded. + if (this._setBreakpointAtAllGeneratedLocations(actor, generatedLocations)) { + return this.threadActor.sources.getOriginalLocation(generatedLocations[0]); + } - // If at least one script has an offset that matches one of the - // generated locations in the list, then breakpoint sliding - // succeeded. - if (this._setBreakpointAtAllGeneratedLocations(actor, generatedLocations)) { - return this.threadActor.sources.getOriginalLocation(generatedLocations[0]); - } + // Try the next column in the original source. + return slideByColumn(actualColumn + 1); + }); + }; - // Try the next line in the original source. - return loop(new OriginalLocation(this, actualLine + 1)); - }); - }; + let slideByLine = (actualLine) => { + return this.sources.getAllGeneratedLocations(new OriginalLocation( + this, + actualLine + )).then((generatedLocations) => { + // Because getAllGeneratedLocations will always return the list of + // generated locations for the closest line that is greater than + // the one we are searching for if no exact match can be found, if + // the list of generated locations is empty, we've reached the end + // of the original source, and breakpoint sliding failed. + if (generatedLocations.length === 0) { + return originalLocation; + } - return loop(new OriginalLocation(this, originalLine + 1)); + // If at least one script has an offset that matches one of the + // generated locations in the list, then breakpoint sliding + // succeeded. + if (this._setBreakpointAtAllGeneratedLocations(actor, generatedLocations)) { + return this.threadActor.sources.getOriginalLocation(generatedLocations[0]); + } + + // Try the next line in the original source. + return slideByLine(actualLine + 1); + }); + }; + + if (originalColumn !== undefined) { + return slideByColumn(originalColumn + 1); } else { - // TODO: Implement breakpoint sliding for column breakpoints - return originalLocation; + return slideByLine(originalLine + 1); } } }).then((actualLocation) => { @@ -3040,8 +3041,6 @@ SourceActor.prototype = { return lineNumber === generatedLine; }); for (let { columnNumber: column, offset } of columnToOffsetMap) { - // TODO: What we are actually interested in here is a range of - // columns, rather than a single one. if (column >= generatedColumn && column <= generatedLastColumn) { entryPoints.push({ script, offsets: [offset] }); } diff --git a/toolkit/devtools/server/actors/utils/TabSources.js b/toolkit/devtools/server/actors/utils/TabSources.js index 0495a263c378..ec19152cc3dc 100644 --- a/toolkit/devtools/server/actors/utils/TabSources.js +++ b/toolkit/devtools/server/actors/utils/TabSources.js @@ -597,40 +597,29 @@ TabSources.prototype = { originalColumn } = originalLocation; - if (originalColumn === undefined) { - let source = originalSourceActor.source || - originalSourceActor.generatedSource; + let source = originalSourceActor.source || + originalSourceActor.generatedSource; - return this.fetchSourceMap(source).then((map) => { - if (map) { - map.computeColumnSpans(); + return this.fetchSourceMap(source).then((map) => { + if (map) { + map.computeColumnSpans(); - return map.allGeneratedPositionsFor({ - source: originalSourceActor.url, - line: originalLine - }).map(({ line, column, lastColumn }) => { - return new GeneratedLocation( - this.createNonSourceMappedActor(source), - line, - column, - lastColumn - ); - }); - } + return map.allGeneratedPositionsFor({ + source: originalSourceActor.url, + line: originalLine, + column: originalColumn + }).map(({ line, column, lastColumn }) => { + return new GeneratedLocation( + this.createNonSourceMappedActor(source), + line, + column, + lastColumn + ); + }); + } - return [GeneratedLocation.fromOriginalLocation(originalLocation)]; - }); - } else { - // TODO: Some source maps have multiple mappings for the same column - return this.getGeneratedLocation(originalLocation) - .then((generatedLocation) => { - if (generatedLocation.generatedLine === null && - generatedLocation.generatedColumn === null) { - return []; - } - return [generatedLocation]; - }); - } + return [GeneratedLocation.fromOriginalLocation(originalLocation)]; + }); },