mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-11 16:32:59 +00:00
Bug 1131643 - Implement a Location object;r=jlong
This commit is contained in:
parent
e3c03410ef
commit
b5d64e8bb1
@ -295,6 +295,133 @@ ActorPool.prototype = {
|
||||
|
||||
exports.ActorPool = ActorPool;
|
||||
|
||||
/**
|
||||
* An OriginalLocation represents a location in an original source.
|
||||
*
|
||||
* @param SourceActor actor
|
||||
* A SourceActor representing an original source.
|
||||
* @param Number line
|
||||
* A line within the given source.
|
||||
* @param Number column
|
||||
* A column within the given line.
|
||||
* @param String name
|
||||
* The name of the symbol corresponding to this OriginalLocation.
|
||||
*/
|
||||
function OriginalLocation(actor, line, column, name) {
|
||||
this._connection = actor ? actor.conn : null;
|
||||
this._actorID = actor ? actor.actorID : undefined;
|
||||
this._line = line;
|
||||
this._column = column;
|
||||
this._name = name;
|
||||
}
|
||||
|
||||
OriginalLocation.fromGeneratedLocation = function (generatedLocation) {
|
||||
return new OriginalLocation(
|
||||
generatedLocation.generatedSourceActor,
|
||||
generatedLocation.generatedLine,
|
||||
generatedLocation.generatedColumn
|
||||
);
|
||||
};
|
||||
|
||||
OriginalLocation.prototype = {
|
||||
get originalSourceActor() {
|
||||
return this._connection ? this._connection.getActor(this._actorID) : null;
|
||||
},
|
||||
|
||||
get originalUrl() {
|
||||
let actor = this.originalSourceActor;
|
||||
let source = actor.source;
|
||||
return source ? source.url : actor._originalUrl;
|
||||
},
|
||||
|
||||
get originalLine() {
|
||||
return this._line;
|
||||
},
|
||||
|
||||
get originalColumn() {
|
||||
return this._column;
|
||||
},
|
||||
|
||||
get originalName() {
|
||||
return this._name;
|
||||
},
|
||||
|
||||
get generatedSourceActor() {
|
||||
throw new Error("Shouldn't access generatedSourceActor from an OriginalLocation");
|
||||
},
|
||||
|
||||
get generatedLine() {
|
||||
throw new Error("Shouldn't access generatedLine from an OriginalLocation");
|
||||
},
|
||||
|
||||
get generatedColumn() {
|
||||
throw new Error("Shouldn't access generatedColumn from an Originallocation");
|
||||
}
|
||||
};
|
||||
|
||||
exports.OriginalLocation = OriginalLocation;
|
||||
|
||||
/**
|
||||
* A GeneratedLocation represents a location in an original source.
|
||||
*
|
||||
* @param SourceActor actor
|
||||
* A SourceActor representing a generated source.
|
||||
* @param Number line
|
||||
* A line within the given source.
|
||||
* @param Number column
|
||||
* A column within the given line.
|
||||
*/
|
||||
function GeneratedLocation(actor, line, column) {
|
||||
this._connection = actor ? actor.conn : null;
|
||||
this._actorID = actor ? actor.actorID : undefined;
|
||||
this._line = line;
|
||||
this._column = column;
|
||||
}
|
||||
|
||||
GeneratedLocation.fromOriginalLocation = function (originalLocation) {
|
||||
return new GeneratedLocation(
|
||||
originalLocation.originalSourceActor,
|
||||
originalLocation.originalLine,
|
||||
originalLocation.originalColumn
|
||||
);
|
||||
};
|
||||
|
||||
GeneratedLocation.prototype = {
|
||||
get originalSourceActor() {
|
||||
throw new Error();
|
||||
},
|
||||
|
||||
get originalUrl() {
|
||||
throw new Error("Shouldn't access originalUrl from a GeneratedLocation");
|
||||
},
|
||||
|
||||
get originalLine() {
|
||||
throw new Error("Shouldn't access originalLine from a GeneratedLocation");
|
||||
},
|
||||
|
||||
get originalColumn() {
|
||||
throw new Error("Shouldn't access originalColumn from a GeneratedLocation");
|
||||
},
|
||||
|
||||
get originalName() {
|
||||
throw new Error("Shouldn't access originalName from a GeneratedLocation");
|
||||
},
|
||||
|
||||
get generatedSourceActor() {
|
||||
return this._connection ? this._connection.getActor(this._actorID) : null;
|
||||
},
|
||||
|
||||
get generatedLine() {
|
||||
return this._line;
|
||||
},
|
||||
|
||||
get generatedColumn() {
|
||||
return this._column;
|
||||
}
|
||||
};
|
||||
|
||||
exports.GeneratedLocation = GeneratedLocation;
|
||||
|
||||
// TODO bug 863089: use Debugger.Script.prototype.getOffsetColumn when it is
|
||||
// implemented.
|
||||
exports.getOffsetColumn = function getOffsetColumn(aOffset, aScript) {
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
const Services = require("Services");
|
||||
const { Cc, Ci, Cu, components, ChromeWorker } = require("chrome");
|
||||
const { ActorPool, getOffsetColumn } = require("devtools/server/actors/common");
|
||||
const { ActorPool, OriginalLocation, GeneratedLocation, getOffsetColumn } = require("devtools/server/actors/common");
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
const DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
|
||||
const { dbg_assert, dumpn, update, fetch } = DevToolsUtils;
|
||||
@ -75,28 +75,23 @@ function BreakpointActorMap() {
|
||||
|
||||
BreakpointActorMap.prototype = {
|
||||
/**
|
||||
* Return the number of instances of BreakpointActor in this instance of
|
||||
* BreakpointActorMap.
|
||||
* Return the number of BreakpointActors in this BreakpointActorMap.
|
||||
*
|
||||
* @returns Number
|
||||
* The number of instances of BreakpointACtor in this instance of
|
||||
* BreakpointActorMap.
|
||||
* The number of BreakpointActor in this BreakpointActorMap.
|
||||
*/
|
||||
get size() {
|
||||
return this._size;
|
||||
},
|
||||
|
||||
/**
|
||||
* Generate all instances of BreakpointActor that match the given query in
|
||||
* this instance of BreakpointActorMap.
|
||||
* Generate all BreakpointActors that match the given location in
|
||||
* this BreakpointActorMap.
|
||||
*
|
||||
* @param Object query
|
||||
* An optional object with the following properties:
|
||||
* - source (optional)
|
||||
* - line (optional, requires source)
|
||||
* - column (optional, requires line)
|
||||
* @param GeneratedLocation location
|
||||
* The location for which matching BreakpointActors should be generated.
|
||||
*/
|
||||
findActors: function* (query = {}) {
|
||||
findActors: function* (location = new GeneratedLocation()) {
|
||||
function* findKeys(object, key) {
|
||||
if (key !== undefined) {
|
||||
if (key in object) {
|
||||
@ -110,9 +105,12 @@ BreakpointActorMap.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
query.sourceActorID = query.sourceActor ? query.sourceActor.actorID : undefined;
|
||||
query.beginColumn = query.column ? query.column : undefined;
|
||||
query.endColumn = query.column ? query.column + 1 : undefined;
|
||||
let query = {
|
||||
sourceActorID: location.generatedSourceActor ? location.generatedSourceActor.actorID : undefined,
|
||||
line: location.generatedLine,
|
||||
beginColumn: location.generatedColumn ? location.generatedColumn : undefined,
|
||||
endColumn: location.generatedColumn ? location.generatedColumn + 1 : undefined
|
||||
};
|
||||
|
||||
for (let sourceActorID of findKeys(this._actors, query.sourceActorID))
|
||||
for (let line of findKeys(this._actors[sourceActorID], query.line))
|
||||
@ -123,17 +121,14 @@ BreakpointActorMap.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the instance of BreakpointActor at the given location in this
|
||||
* instance of BreakpointActorMap.
|
||||
* Return the BreakpointActor at the given location in this
|
||||
* BreakpointActorMap.
|
||||
*
|
||||
* @param Object location
|
||||
* An object with the following properties:
|
||||
* - source
|
||||
* - line
|
||||
* - column (optional)
|
||||
* @param GeneratedLocation location
|
||||
* The location for which the BreakpointActor should be returned.
|
||||
*
|
||||
* @returns BreakpointActor actor
|
||||
* The instance of BreakpointActor at the given location.
|
||||
* The BreakpointActor at the given location.
|
||||
*/
|
||||
getActor: function (location) {
|
||||
for (let actor of this.findActors(location)) {
|
||||
@ -144,24 +139,22 @@ BreakpointActorMap.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the given instance of BreakpointActor to the given location in this
|
||||
* instance of BreakpointActorMap.
|
||||
* Set the given BreakpointActor to the given location in this
|
||||
* BreakpointActorMap.
|
||||
*
|
||||
* @param Object location
|
||||
* An object with the following properties:
|
||||
* - source
|
||||
* - line
|
||||
* - column (optional)
|
||||
* @param GeneratedLocation location
|
||||
* The location to which the given BreakpointActor should be set.
|
||||
*
|
||||
* @param BreakpointActor actor
|
||||
* The instance of BreakpointActor to be set to the given location.
|
||||
* The BreakpointActor to be set to the given location.
|
||||
*/
|
||||
setActor: function (location, actor) {
|
||||
let { sourceActor, line, column } = location;
|
||||
let { generatedSourceActor, generatedLine, generatedColumn } = location;
|
||||
|
||||
let sourceActorID = sourceActor.actorID;
|
||||
let beginColumn = column ? column : 0;
|
||||
let endColumn = column ? column + 1 : Infinity;
|
||||
let sourceActorID = generatedSourceActor.actorID;
|
||||
let line = generatedLine;
|
||||
let beginColumn = generatedColumn ? generatedColumn : 0;
|
||||
let endColumn = generatedColumn ? generatedColumn + 1 : Infinity;
|
||||
|
||||
if (!this._actors[sourceActorID]) {
|
||||
this._actors[sourceActorID] = [];
|
||||
@ -179,21 +172,19 @@ BreakpointActorMap.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete the instance of BreakpointActor from the given location in this
|
||||
* instance of BreakpointActorMap.
|
||||
* Delete the BreakpointActor from the given location in this
|
||||
* BreakpointActorMap.
|
||||
*
|
||||
* @param Object location
|
||||
* An object with the following properties:
|
||||
* - source
|
||||
* - line
|
||||
* - column (optional)
|
||||
* @param GeneratedLocation location
|
||||
* The location from which the BreakpointActor should be deleted.
|
||||
*/
|
||||
deleteActor: function (location) {
|
||||
let { sourceActor, line, column } = location;
|
||||
let { generatedSourceActor, generatedLine, generatedColumn } = location;
|
||||
|
||||
let sourceActorID = sourceActor.actorID;
|
||||
let beginColumn = column ? column : 0;
|
||||
let endColumn = column ? column + 1 : Infinity;
|
||||
let sourceActorID = generatedSourceActor.actorID;
|
||||
let line = generatedLine;
|
||||
let beginColumn = generatedColumn ? generatedColumn : 0;
|
||||
let endColumn = generatedColumn ? generatedColumn + 1 : Infinity;
|
||||
|
||||
if (this._actors[sourceActorID]) {
|
||||
if (this._actors[sourceActorID][line]) {
|
||||
@ -742,9 +733,10 @@ ThreadActor.prototype = {
|
||||
}
|
||||
packet.why = aReason;
|
||||
|
||||
let loc = this.sources.getFrameLocation(aFrame);
|
||||
this.sources.getOriginalLocation(loc).then(aOrigPosition => {
|
||||
if (!aOrigPosition.sourceActor) {
|
||||
let generatedLocation = this.sources.getFrameLocation(aFrame);
|
||||
this.sources.getOriginalLocation(generatedLocation)
|
||||
.then((originalLocation) => {
|
||||
if (!originalLocation.originalSourceActor) {
|
||||
// The only time the source actor will be null is if there
|
||||
// was a sourcemap and it tried to look up the original
|
||||
// location but there was no original URL. This is a strange
|
||||
@ -759,9 +751,9 @@ ThreadActor.prototype = {
|
||||
}
|
||||
|
||||
packet.frame.where = {
|
||||
source: aOrigPosition.sourceActor.form(),
|
||||
line: aOrigPosition.line,
|
||||
column: aOrigPosition.column
|
||||
source: originalLocation.originalSourceActor.form(),
|
||||
line: originalLocation.originalLine,
|
||||
column: originalLocation.originalColumn
|
||||
};
|
||||
resolve(onPacket(packet))
|
||||
.then(null, error => {
|
||||
@ -806,9 +798,9 @@ ThreadActor.prototype = {
|
||||
_makeOnEnterFrame: function ({ pauseAndRespond }) {
|
||||
return aFrame => {
|
||||
const generatedLocation = this.sources.getFrameLocation(aFrame);
|
||||
let { sourceActor } = this.synchronize(this.sources.getOriginalLocation(
|
||||
let { originalSourceActor } = this.synchronize(this.sources.getOriginalLocation(
|
||||
generatedLocation));
|
||||
let url = sourceActor.url;
|
||||
let url = originalSourceActor.url;
|
||||
|
||||
return this.sources.isBlackBoxed(url)
|
||||
? undefined
|
||||
@ -821,9 +813,9 @@ ThreadActor.prototype = {
|
||||
// onPop is called with 'this' set to the current frame.
|
||||
|
||||
const generatedLocation = thread.sources.getFrameLocation(this);
|
||||
const { sourceActor } = thread.synchronize(thread.sources.getOriginalLocation(
|
||||
const { originalSourceActor } = thread.synchronize(thread.sources.getOriginalLocation(
|
||||
generatedLocation));
|
||||
const url = sourceActor.url;
|
||||
const url = originalSourceActor.url;
|
||||
|
||||
if (thread.sources.isBlackBoxed(url)) {
|
||||
return undefined;
|
||||
@ -882,15 +874,15 @@ ThreadActor.prototype = {
|
||||
// 2.2. The source we are in is black boxed.
|
||||
|
||||
// Cases 2.1 and 2.2
|
||||
if (newLocation.url == null
|
||||
|| thread.sources.isBlackBoxed(newLocation.url)) {
|
||||
if (newLocation.originalUrl == null
|
||||
|| thread.sources.isBlackBoxed(newLocation.originalUrl)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Cases 1.1, 1.2 and 1.3
|
||||
if (this !== startFrame
|
||||
|| startLocation.url !== newLocation.url
|
||||
|| startLocation.line !== newLocation.line) {
|
||||
|| startLocation.originalUrl !== newLocation.originalUrl
|
||||
|| startLocation.originalLine !== newLocation.originalLine) {
|
||||
return pauseAndRespond(this);
|
||||
}
|
||||
|
||||
@ -1288,16 +1280,16 @@ ThreadActor.prototype = {
|
||||
form.depth = i;
|
||||
frames.push(form);
|
||||
|
||||
let promise = this.sources.getOriginalLocation({
|
||||
sourceActor: this.sources.createNonSourceMappedActor(frame.script.source),
|
||||
line: form.where.line,
|
||||
column: form.where.column
|
||||
}).then((aOrigLocation) => {
|
||||
let sourceForm = aOrigLocation.sourceActor.form();
|
||||
let promise = this.sources.getOriginalLocation(new GeneratedLocation(
|
||||
this.sources.createNonSourceMappedActor(frame.script.source),
|
||||
form.where.line,
|
||||
form.where.column
|
||||
)).then((originalLocation) => {
|
||||
let sourceForm = originalLocation.originalSourceActor.form();
|
||||
form.where = {
|
||||
source: sourceForm,
|
||||
line: aOrigLocation.line,
|
||||
column: aOrigLocation.column
|
||||
line: originalLocation.originalLine,
|
||||
column: originalLocation.originalColumn
|
||||
};
|
||||
form.source = sourceForm;
|
||||
});
|
||||
@ -1903,9 +1895,9 @@ ThreadActor.prototype = {
|
||||
// Don't pause if we are currently stepping (in or over) or the frame is
|
||||
// black-boxed.
|
||||
const generatedLocation = this.sources.getFrameLocation(aFrame);
|
||||
const { sourceActor } = this.synchronize(this.sources.getOriginalLocation(
|
||||
const { originalSourceActor } = this.synchronize(this.sources.getOriginalLocation(
|
||||
generatedLocation));
|
||||
const url = sourceActor ? sourceActor.url : null;
|
||||
const url = originalSourceActor ? originalSourceActor.url : null;
|
||||
|
||||
return this.sources.isBlackBoxed(url) || aFrame.onStep
|
||||
? undefined
|
||||
@ -2039,8 +2031,8 @@ ThreadActor.prototype = {
|
||||
let source = this.sources.createNonSourceMappedActor(aScript.source);
|
||||
for (let bpActor of this.breakpointActorMap.findActors({ sourceActor: source })) {
|
||||
// Limit the search to the line numbers contained in the new script.
|
||||
if (bpActor.generatedLocation.line >= aScript.startLine
|
||||
&& bpActor.generatedLocation.line <= endLine) {
|
||||
if (bpActor.generatedLocation.generatedLine >= aScript.startLine
|
||||
&& bpActor.generatedLocation.generatedLine <= endLine) {
|
||||
source.setBreakpointForActor(bpActor);
|
||||
}
|
||||
}
|
||||
@ -2751,12 +2743,14 @@ SourceActor.prototype = {
|
||||
* @returns Object
|
||||
* The RDP response.
|
||||
*/
|
||||
_setBreakpointAtColumn: function (scripts, location, actor) {
|
||||
_setBreakpointAtColumn: function (scripts, generatedLocation, actor) {
|
||||
// Debugger.Script -> array of offset mappings
|
||||
const scriptsAndOffsetMappings = new Map();
|
||||
|
||||
for (let script of scripts) {
|
||||
this._findClosestOffsetMappings(location, script, scriptsAndOffsetMappings);
|
||||
this._findClosestOffsetMappings(generatedLocation,
|
||||
script,
|
||||
scriptsAndOffsetMappings);
|
||||
}
|
||||
|
||||
for (let [script, mappings] of scriptsAndOffsetMappings) {
|
||||
@ -2832,18 +2826,13 @@ SourceActor.prototype = {
|
||||
* A condition for the breakpoint.
|
||||
*/
|
||||
setBreakpoint: function (originalLine, originalColumn, condition) {
|
||||
let originalLocation = {
|
||||
sourceActor: this,
|
||||
line: originalLine,
|
||||
column: originalColumn
|
||||
};
|
||||
|
||||
let originalLocation = new OriginalLocation(this, originalLine, originalColumn);
|
||||
return this.threadActor.sources.getGeneratedLocation(originalLocation)
|
||||
.then(generatedLocation => {
|
||||
let actor = this._getOrCreateBreakpointActor(originalLocation,
|
||||
generatedLocation,
|
||||
condition);
|
||||
return generatedLocation.sourceActor.setBreakpointForActor(actor);
|
||||
return generatedLocation.generatedSourceActor.setBreakpointForActor(actor);
|
||||
});
|
||||
},
|
||||
|
||||
@ -2857,13 +2846,13 @@ SourceActor.prototype = {
|
||||
*/
|
||||
setBreakpointForActor: function (actor) {
|
||||
let originalLocation = actor.originalLocation;
|
||||
let generatedLocation = {
|
||||
sourceActor: this,
|
||||
line: actor.generatedLocation.line,
|
||||
column: actor.generatedLocation.column
|
||||
};
|
||||
let generatedLocation = new GeneratedLocation(
|
||||
this,
|
||||
actor.generatedLocation.generatedLine,
|
||||
actor.generatedLocation.generatedColumn
|
||||
);
|
||||
|
||||
let { line: generatedLine, column: generatedColumn } = generatedLocation;
|
||||
let { generatedLine, generatedColumn } = generatedLocation;
|
||||
|
||||
// Find all scripts matching the given location. We will almost always have
|
||||
// a `source` object to query, but multiple inline HTML scripts are all
|
||||
@ -2889,13 +2878,13 @@ SourceActor.prototype = {
|
||||
// handler.
|
||||
scripts = scripts.filter((script) => !actor.hasScript(script));
|
||||
|
||||
let actualLocation;
|
||||
let actualGeneratedLocation;
|
||||
|
||||
// If generatedColumn is something other than 0, assume this is a column
|
||||
// breakpoint and do not perform breakpoint sliding.
|
||||
if (generatedColumn) {
|
||||
this._setBreakpointAtColumn(scripts, generatedLocation, actor);
|
||||
actualLocation = generatedLocation;
|
||||
actualGeneratedLocation = generatedLocation;
|
||||
} else {
|
||||
let result;
|
||||
if (actor.scripts.size === 0) {
|
||||
@ -2925,53 +2914,49 @@ SourceActor.prototype = {
|
||||
}
|
||||
|
||||
if (result.line !== generatedLine) {
|
||||
actualLocation = {
|
||||
sourceActor: generatedLocation.sourceActor,
|
||||
line: result.line,
|
||||
column: generatedLocation.column
|
||||
};
|
||||
actualGeneratedLocation = new GeneratedLocation(
|
||||
generatedLocation.generatedSourceActor,
|
||||
result.line,
|
||||
generatedLocation.generatedColumn
|
||||
);
|
||||
|
||||
// Check whether we already have a breakpoint actor for the actual
|
||||
// location. If we do have an existing actor, then the actor we created
|
||||
// above is redundant and must be destroyed. If we do not have an existing
|
||||
// actor, we need to update the breakpoint store with the new location.
|
||||
|
||||
let existingActor = this.breakpointActorMap.getActor(actualLocation);
|
||||
let existingActor = this.breakpointActorMap.getActor(actualGeneratedLocation);
|
||||
if (existingActor) {
|
||||
actor.onDelete();
|
||||
this.breakpointActorMap.deleteActor(generatedLocation);
|
||||
actor = existingActor;
|
||||
} else {
|
||||
actor.generatedLocation = actualLocation;
|
||||
actor.generatedLocation = actualGeneratedLocation;
|
||||
this.breakpointActorMap.deleteActor(generatedLocation);
|
||||
this.breakpointActorMap.setActor(actualLocation, actor);
|
||||
this.breakpointActorMap.setActor(actualGeneratedLocation, actor);
|
||||
setBreakpointOnEntryPoints(this.threadActor, actor, result.entryPoints);
|
||||
}
|
||||
} else {
|
||||
setBreakpointOnEntryPoints(this.threadActor, actor, result.entryPoints);
|
||||
actualLocation = generatedLocation;
|
||||
actualGeneratedLocation = generatedLocation;
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve().then(() => {
|
||||
if (actualLocation.sourceActor.source) {
|
||||
return this.threadActor.sources.getOriginalLocation({
|
||||
sourceActor: actualLocation.sourceActor,
|
||||
line: actualLocation.line,
|
||||
column: actualLocation.column
|
||||
});
|
||||
if (actualGeneratedLocation.generatedSourceActor.source) {
|
||||
return this.threadActor.sources.getOriginalLocation(actualGeneratedLocation);
|
||||
} else {
|
||||
return actualLocation;
|
||||
return OriginalLocation.fromGeneratedLocation(actualGeneratedLocation);
|
||||
}
|
||||
}).then((actualLocation) => {
|
||||
}).then((actualOriginalLocation) => {
|
||||
let response = { actor: actor.actorID };
|
||||
if (actualLocation.sourceActor.url !== originalLocation.sourceActor.url ||
|
||||
actualLocation.line !== originalLocation.line)
|
||||
if (actualOriginalLocation.originalSourceActor.url !== originalLocation.originalSourceActor.url ||
|
||||
actualOriginalLocation.originalLine !== originalLocation.originalLine)
|
||||
{
|
||||
response.actualLocation = {
|
||||
source: actualLocation.sourceActor.form(),
|
||||
line: actualLocation.line,
|
||||
column: actualLocation.column
|
||||
source: actualOriginalLocation.originalSourceActor.form(),
|
||||
line: actualOriginalLocation.originalLine,
|
||||
column: actualOriginalLocation.originalColumn
|
||||
};
|
||||
}
|
||||
return response;
|
||||
@ -3019,7 +3004,7 @@ SourceActor.prototype = {
|
||||
aScript,
|
||||
aScriptsAndOffsetMappings) {
|
||||
let offsetMappings = aScript.getAllColumnOffsets()
|
||||
.filter(({ lineNumber }) => lineNumber === aTargetLocation.line);
|
||||
.filter(({ lineNumber }) => lineNumber === aTargetLocation.generatedLine);
|
||||
|
||||
// Attempt to find the current closest offset distance from the target
|
||||
// location by grabbing any offset mapping in the map by doing one iteration
|
||||
@ -3028,13 +3013,13 @@ SourceActor.prototype = {
|
||||
let closestDistance = Infinity;
|
||||
if (aScriptsAndOffsetMappings.size) {
|
||||
for (let mappings of aScriptsAndOffsetMappings.values()) {
|
||||
closestDistance = Math.abs(aTargetLocation.column - mappings[0].columnNumber);
|
||||
closestDistance = Math.abs(aTargetLocation.generatedColumn - mappings[0].columnNumber);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (let mapping of offsetMappings) {
|
||||
let currentDistance = Math.abs(aTargetLocation.column - mapping.columnNumber);
|
||||
let currentDistance = Math.abs(aTargetLocation.generatedColumn - mapping.columnNumber);
|
||||
|
||||
if (currentDistance > closestDistance) {
|
||||
continue;
|
||||
@ -3329,23 +3314,17 @@ ObjectActor.prototype = {
|
||||
};
|
||||
}
|
||||
|
||||
const generatedLocation = {
|
||||
sourceActor: this.threadActor.sources.createNonSourceMappedActor(this.obj.script.source),
|
||||
line: this.obj.script.startLine,
|
||||
// TODO bug 901138: use Debugger.Script.prototype.startColumn.
|
||||
column: 0
|
||||
};
|
||||
|
||||
return this.threadActor.sources.getOriginalLocation(generatedLocation)
|
||||
.then(({ sourceActor, line, column }) => {
|
||||
|
||||
return {
|
||||
from: this.actorID,
|
||||
source: sourceActor.form(),
|
||||
line: line,
|
||||
column: column
|
||||
};
|
||||
});
|
||||
return this.threadActor.sources.getOriginalLocation(new GeneratedLocation(
|
||||
this.threadActor.sources.createNonSourceMappedActor(this.obj.script.source),
|
||||
this.obj.script.startLine,
|
||||
0 // TODO bug 901138: use Debugger.Script.prototype.startColumn
|
||||
)).then((originalLocation) => {
|
||||
return {
|
||||
source: originalLocation.originalSourceActor.form(),
|
||||
line: originalLocation.originalLine,
|
||||
column: originalLocation.originalColumn
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
@ -4573,11 +4552,11 @@ FrameActor.prototype = {
|
||||
form.this = threadActor.createValueGrip(this.frame.this);
|
||||
form.arguments = this._args();
|
||||
if (this.frame.script) {
|
||||
var loc = this.threadActor.sources.getFrameLocation(this.frame);
|
||||
var generatedLocation = this.threadActor.sources.getFrameLocation(this.frame);
|
||||
form.where = {
|
||||
source: loc.sourceActor.form(),
|
||||
line: loc.line,
|
||||
column: loc.column
|
||||
source: generatedLocation.generatedSourceActor.form(),
|
||||
line: generatedLocation.generatedLine,
|
||||
column: generatedLocation.generatedColumn
|
||||
};
|
||||
}
|
||||
|
||||
@ -4714,10 +4693,10 @@ BreakpointActor.prototype = {
|
||||
hit: function (aFrame) {
|
||||
// Don't pause if we are currently stepping (in or over) or the frame is
|
||||
// black-boxed.
|
||||
let loc = this.threadActor.sources.getFrameLocation(aFrame);
|
||||
let { sourceActor } = this.threadActor.synchronize(
|
||||
this.threadActor.sources.getOriginalLocation(loc));
|
||||
let url = sourceActor.url;
|
||||
let generatedLocation = this.threadActor.sources.getFrameLocation(aFrame);
|
||||
let { originalSourceActor } = this.threadActor.synchronize(
|
||||
this.threadActor.sources.getOriginalLocation(generatedLocation));
|
||||
let url = originalSourceActor.url;
|
||||
|
||||
if (this.threadActor.sources.isBlackBoxed(url)
|
||||
|| aFrame.onStep
|
||||
@ -5558,13 +5537,13 @@ ThreadSources.prototype = {
|
||||
*/
|
||||
getFrameLocation: function (aFrame) {
|
||||
if (!aFrame || !aFrame.script) {
|
||||
return { sourceActor: null, line: null, column: null };
|
||||
}
|
||||
return {
|
||||
sourceActor: this.createNonSourceMappedActor(aFrame.script.source),
|
||||
line: aFrame.script.getOffsetLine(aFrame.offset),
|
||||
column: getOffsetColumn(aFrame.offset, aFrame.script)
|
||||
return new GeneratedLocation();
|
||||
}
|
||||
return new GeneratedLocation(
|
||||
this.createNonSourceMappedActor(aFrame.script.source),
|
||||
aFrame.script.getOffsetLine(aFrame.offset),
|
||||
getOffsetColumn(aFrame.offset, aFrame.script)
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -5574,53 +5553,52 @@ ThreadSources.prototype = {
|
||||
* sure to that it works properly, reusing source maps if already
|
||||
* fetched. Use this from any actor that needs sourcemapping.
|
||||
*/
|
||||
getOriginalLocation: function ({ sourceActor, line, column }) {
|
||||
let source = sourceActor.source;
|
||||
let url = source ? source.url : sourceActor._originalUrl;
|
||||
getOriginalLocation: function (generatedLocation) {
|
||||
let {
|
||||
generatedSourceActor,
|
||||
generatedLine,
|
||||
generatedColumn
|
||||
} = generatedLocation;
|
||||
let source = generatedSourceActor.source;
|
||||
let url = source ? source.url : generatedSourceActor._originalUrl;
|
||||
|
||||
// In certain scenarios the source map may have not been fetched
|
||||
// yet (or at least tied to this Debugger.Source instance), so use
|
||||
// `fetchSourceMap` instead of `getSourceMap`. This allows this
|
||||
// function to be called from anywere (across debuggers) and it
|
||||
// should just automatically work.
|
||||
return this.fetchSourceMap(source).then(sm => {
|
||||
if (sm) {
|
||||
return this.fetchSourceMap(source).then(map => {
|
||||
if (map) {
|
||||
let {
|
||||
source: sourceUrl,
|
||||
line: sourceLine,
|
||||
column: sourceCol,
|
||||
name: sourceName
|
||||
} = sm.originalPositionFor({
|
||||
line: line,
|
||||
column: column == null ? Infinity : column
|
||||
source: originalUrl,
|
||||
line: originalLine,
|
||||
column: originalColumn,
|
||||
name: originalName
|
||||
} = map.originalPositionFor({
|
||||
line: generatedLine,
|
||||
column: generatedColumn == null ? Infinity : generatedColumn
|
||||
});
|
||||
|
||||
return {
|
||||
// Since the `Debugger.Source` instance may come from a
|
||||
// different `Debugger` instance (any actor can call this
|
||||
// method), we can't rely on any of the source discovery
|
||||
// setup (`_discoverSources`, etc) to have been run yet. So
|
||||
// we have to assume that the actor may not already exist,
|
||||
// and we might need to create it, so use `source` and give
|
||||
// it the required parameters for a sourcemapped source.
|
||||
sourceActor: (!sourceUrl) ? null : this.source({
|
||||
originalUrl: sourceUrl,
|
||||
// Since the `Debugger.Source` instance may come from a
|
||||
// different `Debugger` instance (any actor can call this
|
||||
// method), we can't rely on any of the source discovery
|
||||
// setup (`_discoverSources`, etc) to have been run yet. So
|
||||
// we have to assume that the actor may not already exist,
|
||||
// and we might need to create it, so use `source` and give
|
||||
// it the required parameters for a sourcemapped source.
|
||||
return new OriginalLocation(
|
||||
originalUrl ? this.source({
|
||||
originalUrl: originalUrl,
|
||||
generatedSource: source
|
||||
}),
|
||||
url: sourceUrl,
|
||||
line: sourceLine,
|
||||
column: sourceCol,
|
||||
name: sourceName
|
||||
};
|
||||
}) : null,
|
||||
originalLine,
|
||||
originalColumn,
|
||||
originalName
|
||||
);
|
||||
}
|
||||
|
||||
// No source map
|
||||
return resolve({
|
||||
sourceActor: sourceActor,
|
||||
url: url,
|
||||
line: line,
|
||||
column: column
|
||||
});
|
||||
return OriginalLocation.fromGeneratedLocation(generatedLocation);
|
||||
});
|
||||
},
|
||||
|
||||
@ -5633,34 +5611,40 @@ ThreadSources.prototype = {
|
||||
* the tables this function uses; thus, it won't know that S's original
|
||||
* source URLs map to S until P is resolved.
|
||||
*/
|
||||
getGeneratedLocation: function ({ sourceActor, line, column }) {
|
||||
getGeneratedLocation: function (originalLocation) {
|
||||
let { originalSourceActor } = originalLocation;
|
||||
|
||||
// Both original sources and normal sources could have sourcemaps,
|
||||
// because normal sources can be pretty-printed which generates a
|
||||
// sourcemap for itself. Check both of the source properties to make it work
|
||||
// for both kinds of sources.
|
||||
let source = sourceActor.generatedSource || sourceActor.source;
|
||||
let source = originalSourceActor.source || originalSourceActor.generatedSource;
|
||||
|
||||
// See comment about `fetchSourceMap` in `getOriginalLocation`.
|
||||
return this.fetchSourceMap(source).then(sm => {
|
||||
if (sm) {
|
||||
let { line: genLine, column: genColumn } = sm.generatedPositionFor({
|
||||
source: sourceActor.url,
|
||||
line: line,
|
||||
column: column == null ? Infinity : column
|
||||
return this.fetchSourceMap(source).then((map) => {
|
||||
if (map) {
|
||||
let {
|
||||
originalLine,
|
||||
originalColumn
|
||||
} = originalLocation;
|
||||
|
||||
let {
|
||||
line: generatedLine,
|
||||
column: generatedColumn
|
||||
} = map.generatedPositionFor({
|
||||
source: originalSourceActor.url,
|
||||
line: originalLine,
|
||||
column: originalColumn == null ? Infinity : originalColumn
|
||||
});
|
||||
|
||||
return {
|
||||
sourceActor: this.createNonSourceMappedActor(source),
|
||||
line: genLine,
|
||||
column: genColumn
|
||||
};
|
||||
return new GeneratedLocation(
|
||||
this.createNonSourceMappedActor(source),
|
||||
generatedLine,
|
||||
generatedColumn
|
||||
);
|
||||
}
|
||||
|
||||
return resolve({
|
||||
sourceActor: sourceActor,
|
||||
line: line,
|
||||
column: column
|
||||
});
|
||||
return GeneratedLocation.fromOriginalLocation(originalLocation);
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -8,7 +8,7 @@ const { Cu } = require("chrome");
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
const { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
|
||||
const Debugger = require("Debugger");
|
||||
const { getOffsetColumn } = require("devtools/server/actors/common");
|
||||
const { GeneratedLocation, getOffsetColumn } = require("devtools/server/actors/common");
|
||||
const promise = require("promise");
|
||||
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
@ -339,25 +339,25 @@ TracerActor.prototype = {
|
||||
if (aFrame.script) {
|
||||
let sources = this._parent.threadActor.sources;
|
||||
|
||||
sourceMappedLocation = yield sources.getOriginalLocation({
|
||||
sourceActor: sources.createNonSourceMappedActor(aFrame.script.source),
|
||||
url: aFrame.script.source.url,
|
||||
line: aFrame.script.startLine,
|
||||
sourceMappedLocation = yield sources.getOriginalLocation(new GeneratedLocation(
|
||||
sources.createNonSourceMappedActor(aFrame.script.source),
|
||||
aFrame.script.startLine,
|
||||
// We should return the location of the start of the script, but
|
||||
// Debugger.Script does not provide complete start locations (bug
|
||||
// 901138). Instead, return the current offset (the location of the
|
||||
// first statement in the function).
|
||||
column: getOffsetColumn(aFrame.offset, aFrame.script)
|
||||
});
|
||||
getOffsetColumn(aFrame.offset, aFrame.script)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if (this._requestsForTraceType.name) {
|
||||
if (sourceMappedLocation && sourceMappedLocation.name) {
|
||||
packet.name = sourceMappedLocation.name;
|
||||
if (sourceMappedLocation && sourceMappedLocation.originalName) {
|
||||
packet.name = sourceMappedLocation.originalName;
|
||||
} else {
|
||||
packet.name = name;
|
||||
}
|
||||
packet.name = name;
|
||||
}
|
||||
|
||||
if (this._requestsForTraceType.location) {
|
||||
@ -365,10 +365,9 @@ TracerActor.prototype = {
|
||||
// Don't copy sourceMappedLocation directly because it
|
||||
// contains a reference to the source actor
|
||||
packet.location = {
|
||||
url: sourceMappedLocation.url,
|
||||
line: sourceMappedLocation.line,
|
||||
column: sourceMappedLocation.column,
|
||||
name: sourceMappedLocation.name
|
||||
url: sourceMappedLocation.originalUrl,
|
||||
line: sourceMappedLocation.originalLine,
|
||||
column: sourceMappedLocation.originalColumn
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -21,13 +21,13 @@ function run_test()
|
||||
function test_get_actor() {
|
||||
let bpStore = new BreakpointActorMap();
|
||||
let location = {
|
||||
sourceActor: { actor: 'actor1' },
|
||||
line: 3
|
||||
generatedSourceActor: { actor: 'actor1' },
|
||||
generatedLine: 3
|
||||
};
|
||||
let columnLocation = {
|
||||
sourceActor: { actor: 'actor2' },
|
||||
line: 5,
|
||||
column: 15
|
||||
generatedSourceActor: { actor: 'actor2' },
|
||||
generatedLine: 5,
|
||||
generatedColumn: 15
|
||||
};
|
||||
|
||||
// Shouldn't have breakpoint
|
||||
@ -59,9 +59,9 @@ function test_set_actor() {
|
||||
// Breakpoint with column
|
||||
let bpStore = new BreakpointActorMap();
|
||||
let location = {
|
||||
sourceActor: { actor: 'actor1' },
|
||||
line: 10,
|
||||
column: 9
|
||||
generatedSourceActor: { actor: 'actor1' },
|
||||
generatedLine: 10,
|
||||
generatedColumn: 9
|
||||
};
|
||||
bpStore.setActor(location, {});
|
||||
do_check_true(!!bpStore.getActor(location),
|
||||
@ -69,8 +69,8 @@ function test_set_actor() {
|
||||
|
||||
// Breakpoint without column (whole line breakpoint)
|
||||
location = {
|
||||
sourceActor: { actor: 'actor2' },
|
||||
line: 103
|
||||
generatedSourceActor: { actor: 'actor2' },
|
||||
generatedLine: 103
|
||||
};
|
||||
bpStore.setActor(location, {});
|
||||
do_check_true(!!bpStore.getActor(location),
|
||||
@ -81,9 +81,9 @@ function test_delete_actor() {
|
||||
// Breakpoint with column
|
||||
let bpStore = new BreakpointActorMap();
|
||||
let location = {
|
||||
sourceActor: { actor: 'actor1' },
|
||||
line: 10,
|
||||
column: 9
|
||||
generatedSourceActor: { actor: 'actor1' },
|
||||
generatedLine: 10,
|
||||
generatedColumn: 9
|
||||
};
|
||||
bpStore.setActor(location, {});
|
||||
bpStore.deleteActor(location);
|
||||
@ -92,8 +92,8 @@ function test_delete_actor() {
|
||||
|
||||
// Breakpoint without column (whole line breakpoint)
|
||||
location = {
|
||||
sourceActor: { actor: 'actor2' },
|
||||
line: 103
|
||||
generatedSourceActor: { actor: 'actor2' },
|
||||
generatedLine: 103
|
||||
};
|
||||
bpStore.setActor(location, {});
|
||||
bpStore.deleteActor(location);
|
||||
@ -103,14 +103,14 @@ function test_delete_actor() {
|
||||
|
||||
function test_find_actors() {
|
||||
let bps = [
|
||||
{ sourceActor: { actor: "actor1" }, line: 10 },
|
||||
{ sourceActor: { actor: "actor1" }, line: 10, column: 3 },
|
||||
{ sourceActor: { actor: "actor1" }, line: 10, column: 10 },
|
||||
{ sourceActor: { actor: "actor1" }, line: 23, column: 89 },
|
||||
{ sourceActor: { actor: "actor2" }, line: 10, column: 1 },
|
||||
{ sourceActor: { actor: "actor2" }, line: 20, column: 5 },
|
||||
{ sourceActor: { actor: "actor2" }, line: 30, column: 34 },
|
||||
{ sourceActor: { actor: "actor2" }, line: 40, column: 56 }
|
||||
{ generatedSourceActor: { actor: "actor1" }, generatedLine: 10 },
|
||||
{ generatedSourceActor: { actor: "actor1" }, generatedLine: 10, generatedColumn: 3 },
|
||||
{ generatedSourceActor: { actor: "actor1" }, generatedLine: 10, generatedColumn: 10 },
|
||||
{ generatedSourceActor: { actor: "actor1" }, generatedLine: 23, generatedColumn: 89 },
|
||||
{ generatedSourceActor: { actor: "actor2" }, generatedLine: 10, generatedColumn: 1 },
|
||||
{ generatedSourceActor: { actor: "actor2" }, generatedLine: 20, generatedColumn: 5 },
|
||||
{ generatedSourceActor: { actor: "actor2" }, generatedLine: 30, generatedColumn: 34 },
|
||||
{ generatedSourceActor: { actor: "actor2" }, generatedLine: 40, generatedColumn: 56 }
|
||||
];
|
||||
|
||||
let bpStore = new BreakpointActorMap();
|
||||
@ -130,8 +130,8 @@ function test_find_actors() {
|
||||
|
||||
// Breakpoints by URL
|
||||
|
||||
bpSet = new Set(bps.filter(bp => { return bp.sourceActor.actorID === "actor1" }));
|
||||
for (let bp of bpStore.findActors({ sourceActor: { actorID: "actor1" } })) {
|
||||
bpSet = new Set(bps.filter(bp => { return bp.generatedSourceActor.actorID === "actor1" }));
|
||||
for (let bp of bpStore.findActors({ generatedSourceActor: { actorID: "actor1" } })) {
|
||||
bpSet.delete(bp);
|
||||
}
|
||||
do_check_eq(bpSet.size, 0,
|
||||
@ -139,15 +139,15 @@ function test_find_actors() {
|
||||
|
||||
// Breakpoints by URL and line
|
||||
|
||||
bpSet = new Set(bps.filter(bp => { return bp.sourceActor.actorID === "actor1" && bp.line === 10; }));
|
||||
bpSet = new Set(bps.filter(bp => { return bp.generatedSourceActor.actorID === "actor1" && bp.generatedLine === 10; }));
|
||||
let first = true;
|
||||
for (let bp of bpStore.findActors({ sourceActor: { actorID: "actor1" }, line: 10 })) {
|
||||
for (let bp of bpStore.findActors({ generatedSourceActor: { actorID: "actor1" }, generatedLine: 10 })) {
|
||||
if (first) {
|
||||
do_check_eq(bp.column, undefined,
|
||||
do_check_eq(bp.generatedColumn, undefined,
|
||||
"Should always get the whole line breakpoint first");
|
||||
first = false;
|
||||
} else {
|
||||
do_check_neq(bp.column, undefined,
|
||||
do_check_neq(bp.generatedColumn, undefined,
|
||||
"Should not get the whole line breakpoint any time other than first.");
|
||||
}
|
||||
bpSet.delete(bp);
|
||||
@ -161,9 +161,9 @@ function test_duplicate_actors() {
|
||||
|
||||
// Breakpoint with column
|
||||
let location = {
|
||||
sourceActor: { actorID: "foo-actor" },
|
||||
line: 10,
|
||||
column: 9
|
||||
generatedSourceActor: { actorID: "foo-actor" },
|
||||
generatedLine: 10,
|
||||
generatedColumn: 9
|
||||
};
|
||||
bpStore.setActor(location, {});
|
||||
bpStore.setActor(location, {});
|
||||
@ -172,8 +172,8 @@ function test_duplicate_actors() {
|
||||
|
||||
// Breakpoint without column (whole line breakpoint)
|
||||
location = {
|
||||
sourceActor: { actorID: "foo-actor" },
|
||||
line: 15
|
||||
generatedSourceActor: { actorID: "foo-actor" },
|
||||
generatedLine: 15
|
||||
};
|
||||
bpStore.setActor(location, {});
|
||||
bpStore.setActor(location, {});
|
||||
|
Loading…
Reference in New Issue
Block a user