зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1518661 - Part 7: Update debugger server to use new getPossibleBreakpoints APIs. r=jlast
Making use of the new SpiderMonkey APIs for available breakpoints means that the server needs to think a lot less about where it is pausing and allows us to drop the concept of a pause points from the server entirely. It is now up to SpiderMonkey to decide where it will and will not stop when it is stepping. Differential Revision: https://phabricator.services.mozilla.com/D17665 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
b78439c9df
Коммит
241f292283
|
@ -14,19 +14,6 @@ import { getGeneratedLocation } from "../../utils/source-maps";
|
|||
import type { SourceId } from "../../types";
|
||||
import type { ThunkArgs, Action } from "../types";
|
||||
|
||||
function compressPausePoints(pausePoints) {
|
||||
const compressed = {};
|
||||
for (const line in pausePoints) {
|
||||
compressed[line] = {};
|
||||
for (const col in pausePoints[line]) {
|
||||
const { types } = pausePoints[line][col];
|
||||
compressed[line][col] = (types.break ? 1 : 0) | (types.step ? 2 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
return compressed;
|
||||
}
|
||||
|
||||
async function mapLocations(pausePoints, state, source, sourceMaps) {
|
||||
const pausePointList = convertToList(pausePoints);
|
||||
const sourceId = source.id;
|
||||
|
@ -58,17 +45,8 @@ export function setPausePoints(sourceId: SourceId) {
|
|||
return;
|
||||
}
|
||||
|
||||
let pausePoints = await parser.getPausePoints(sourceId);
|
||||
|
||||
if (isGenerated(source)) {
|
||||
const compressed = compressPausePoints(pausePoints);
|
||||
for (const sourceActor of getSourceActors(getState(), sourceId)) {
|
||||
await client.setPausePoints(sourceActor, compressed);
|
||||
}
|
||||
}
|
||||
|
||||
pausePoints = await mapLocations(
|
||||
pausePoints,
|
||||
const pausePoints = await mapLocations(
|
||||
await parser.getPausePoints(sourceId),
|
||||
getState(),
|
||||
source,
|
||||
sourceMaps
|
||||
|
|
|
@ -28,7 +28,6 @@ add_task(async function() {
|
|||
await selectSource(dbg, "simple1");
|
||||
await waitForSelectedSource(dbg, "simple1");
|
||||
|
||||
await addBreakpoint(dbg, "simple1", 1);
|
||||
await addBreakpoint(dbg, "simple1", 4);
|
||||
await addBreakpoint(dbg, "simple1", 5);
|
||||
await addBreakpoint(dbg, "simple1", 6);
|
||||
|
@ -40,14 +39,14 @@ add_task(async function() {
|
|||
// which promises get resolved. The problem seems to indicate a coverage gap
|
||||
// in waitUntilService(). Workaround this by only waiting for one dispatch,
|
||||
// though this is fragile and could break again in the future.
|
||||
let dispatched = waitForDispatch(dbg, "DISABLE_BREAKPOINT", /*3*/ 1);
|
||||
let dispatched = waitForDispatch(dbg, "DISABLE_BREAKPOINT", /*2*/ 1);
|
||||
selectContextMenuItem(dbg, selectors.breakpointContextMenu.disableOthers);
|
||||
await waitForState(dbg, state =>
|
||||
dbg.selectors.getBreakpointsList(state)
|
||||
.every(bp => (bp.location.line !== 1) === bp.disabled)
|
||||
.every(bp => (bp.location.line !== 4) === bp.disabled)
|
||||
);
|
||||
await dispatched;
|
||||
ok("breakpoint at 1 is the only enabled breakpoint");
|
||||
ok("breakpoint at 4 is the only enabled breakpoint");
|
||||
|
||||
openFirstBreakpointContextMenu(dbg);
|
||||
// select "Disable All"
|
||||
|
@ -61,23 +60,23 @@ add_task(async function() {
|
|||
|
||||
openFirstBreakpointContextMenu(dbg);
|
||||
// select "Enable Others"
|
||||
dispatched = waitForDispatch(dbg, "ENABLE_BREAKPOINT", 3);
|
||||
dispatched = waitForDispatch(dbg, "ENABLE_BREAKPOINT", 2);
|
||||
selectContextMenuItem(dbg, selectors.breakpointContextMenu.enableOthers);
|
||||
await waitForState(dbg, state =>
|
||||
dbg.selectors.getBreakpointsList(state)
|
||||
.every(bp => (bp.location.line === 1) === bp.disabled)
|
||||
.every(bp => (bp.location.line === 4) === bp.disabled)
|
||||
);
|
||||
await dispatched;
|
||||
ok("all breakpoints except line 1 are enabled");
|
||||
|
||||
openFirstBreakpointContextMenu(dbg);
|
||||
// select "Remove Others"
|
||||
dispatched = waitForDispatch(dbg, "REMOVE_BREAKPOINT", 3);
|
||||
dispatched = waitForDispatch(dbg, "REMOVE_BREAKPOINT", 2);
|
||||
selectContextMenuItem(dbg, selectors.breakpointContextMenu.removeOthers);
|
||||
await waitForState(dbg, state =>
|
||||
dbg.selectors.getBreakpointsList(state).length === 1 &&
|
||||
dbg.selectors.getBreakpointsList(state)[0].location.line === 1
|
||||
dbg.selectors.getBreakpointsList(state)[0].location.line === 4
|
||||
);
|
||||
await dispatched;
|
||||
ok("remaining breakpoint should be on line 1");
|
||||
ok("remaining breakpoint should be on line 4");
|
||||
});
|
||||
|
|
|
@ -36,6 +36,9 @@ add_task(async function() {
|
|||
await pressResume(dbg);
|
||||
assertPausedLocation(dbg);
|
||||
|
||||
await pressStepOver(dbg);
|
||||
assertPausedLocation(dbg);
|
||||
|
||||
await pressStepIn(dbg);
|
||||
assertPausedLocation(dbg);
|
||||
|
||||
|
|
|
@ -33,28 +33,17 @@ add_task(async function test() {
|
|||
await selectSource(dbg, "pause-points.js")
|
||||
await testCase(dbg, {
|
||||
name: "statements",
|
||||
steps: [
|
||||
[9, 2],
|
||||
[10, 4],
|
||||
[10, 13],
|
||||
[11, 2],
|
||||
[11, 10],
|
||||
[11, 21],
|
||||
[11, 29],
|
||||
[12, 2],
|
||||
[12, 12],
|
||||
[13, 0]
|
||||
]
|
||||
steps: [[9,2], [10,4], [10,13], [11,2], [11,21], [12,2], [12,12], [13,0]]
|
||||
});
|
||||
|
||||
await testCase(dbg, {
|
||||
name: "expressions",
|
||||
steps: [[40,2], [41,2], [41,8], [42,12], [43,0]]
|
||||
steps: [[40,2], [41,2], [42,12], [43,0]]
|
||||
});
|
||||
|
||||
await testCase(dbg, {
|
||||
name: "sequences",
|
||||
steps: [[23,2], [25,12], [31,4], [34,2], [37,0]]
|
||||
steps: [[23,2], [25,12], [29,12], [34,2], [37,0]]
|
||||
});
|
||||
|
||||
await testCase(dbg, {
|
||||
|
@ -62,15 +51,11 @@ add_task(async function test() {
|
|||
steps: [
|
||||
[16, 2],
|
||||
[17, 12],
|
||||
[17, 20],
|
||||
[18, 10],
|
||||
[19, 2],
|
||||
[19, 8],
|
||||
[19, 17],
|
||||
[19, 25],
|
||||
[19, 8],
|
||||
[19, 17],
|
||||
[19, 25],
|
||||
[19, 8]
|
||||
]
|
||||
});
|
||||
|
|
|
@ -57,6 +57,7 @@ function testStepOverForOf(dbg) {
|
|||
{ line: 4, column: 2 },
|
||||
[
|
||||
["stepOver", { line: 6, column: 20 }],
|
||||
["stepOver", { line: 6, column: 2 }],
|
||||
["stepOver", { line: 7, column: 4 }],
|
||||
["stepOver", { line: 6, column: 2 }],
|
||||
["stepOver", { line: 7, column: 4 }],
|
||||
|
@ -76,10 +77,10 @@ function testStepOverForOfArray(dbg) {
|
|||
{ line: 3, column: 2 },
|
||||
[
|
||||
["stepOver", { line: 5, column: 2 }],
|
||||
["stepOver", { line: 5, column: 7 }],
|
||||
["stepOver", { line: 5, column: 13 }],
|
||||
["stepOver", { line: 6, column: 4 }],
|
||||
["stepOver", { line: 5, column: 2 }],
|
||||
["stepOver", { line: 5, column: 7 }],
|
||||
["stepOver", { line: 5, column: 13 }],
|
||||
["stepOver", { line: 6, column: 4 }],
|
||||
["stepOver", { line: 5, column: 2 }],
|
||||
["stepOver", { line: 9, column: 2 }]
|
||||
|
@ -114,9 +115,9 @@ function testStepOverForOfArrayClosure(dbg) {
|
|||
{ line: 3, column: 2 },
|
||||
[
|
||||
["stepOver", { line: 5, column: 2 }],
|
||||
["stepOver", { line: 5, column: 7 }],
|
||||
["stepOver", { line: 5, column: 13 }],
|
||||
["stepOver", { line: 5, column: 2 }],
|
||||
["stepOver", { line: 5, column: 7 }],
|
||||
["stepOver", { line: 5, column: 13 }],
|
||||
["stepOver", { line: 5, column: 2 }],
|
||||
["stepOver", { line: 9, column: 2 }]
|
||||
]
|
||||
|
|
|
@ -81,7 +81,6 @@ add_task(async function() {
|
|||
await waitForPaused(dbg);
|
||||
assertPausedLocation(dbg);
|
||||
|
||||
await stepIn(dbg);
|
||||
await stepIn(dbg);
|
||||
assertPausedLocation(dbg);
|
||||
|
||||
|
|
|
@ -24,6 +24,6 @@ add_task(async function test() {
|
|||
await stepIn(dbg);
|
||||
await stepIn(dbg);
|
||||
|
||||
assertDebugLine(dbg, 42267);
|
||||
assertDebugLine(dbg, 42271);
|
||||
assertPausedLocation(dbg);
|
||||
});
|
||||
|
|
|
@ -28,12 +28,10 @@ add_task(async function() {
|
|||
await reverseStepOverToLine(client, 21);
|
||||
await checkEvaluateInTopFrame(client, "number", 9);
|
||||
|
||||
await stepOverToLine(client, 21);
|
||||
await stepOverToLine(client, 22);
|
||||
await stepOverToLine(client, 23);
|
||||
await stepOverToLine(client, 13);
|
||||
await stepOverToLine(client, 17);
|
||||
await stepOverToLine(client, 17);
|
||||
await stepOverToLine(client, 18);
|
||||
|
||||
// After forward-stepping out of the topmost frame we should run forward to
|
||||
|
|
|
@ -737,6 +737,13 @@ ReplayDebuggerScript.prototype = {
|
|||
getSuccessorOffsets(pc) { return this._forward("getSuccessorOffsets", pc); },
|
||||
getPredecessorOffsets(pc) { return this._forward("getPredecessorOffsets", pc); },
|
||||
getAllColumnOffsets() { return this._forward("getAllColumnOffsets"); },
|
||||
getOffsetMetadata(pc) { return this._forward("getOffsetMetadata", pc); },
|
||||
getPossibleBreakpoints(query) {
|
||||
return this._forward("getPossibleBreakpoints", query);
|
||||
},
|
||||
getPossibleBreakpointOffsets(query) {
|
||||
return this._forward("getPossibleBreakpointOffsets", query);
|
||||
},
|
||||
|
||||
setBreakpoint(offset, handler) {
|
||||
this._dbg._setBreakpoint(() => { handler.hit(this._dbg.getNewestFrame()); },
|
||||
|
|
|
@ -783,6 +783,9 @@ const gRequestHandlers = {
|
|||
getSuccessorOffsets: forwardToScript("getSuccessorOffsets"),
|
||||
getPredecessorOffsets: forwardToScript("getPredecessorOffsets"),
|
||||
getAllColumnOffsets: forwardToScript("getAllColumnOffsets"),
|
||||
getOffsetMetadata: forwardToScript("getOffsetMetadata"),
|
||||
getPossibleBreakpoints: forwardToScript("getPossibleBreakpoints"),
|
||||
getPossibleBreakpointOffsets: forwardToScript("getPossibleBreakpointOffsets"),
|
||||
|
||||
frameEvaluate(request) {
|
||||
if (!RecordReplayControl.maybeDivergeFromRecording()) {
|
||||
|
|
|
@ -268,7 +268,7 @@ const SourceActor = ActorClassWithSpec(sourceSpec, {
|
|||
getExecutableLines: async function() {
|
||||
const offsetsLines = new Set();
|
||||
for (const s of this._findDebuggeeScripts()) {
|
||||
for (const offset of s.getAllColumnOffsets()) {
|
||||
for (const offset of s.getPossibleBreakpoints()) {
|
||||
offsetsLines.add(offset.lineNumber);
|
||||
}
|
||||
}
|
||||
|
@ -307,7 +307,7 @@ const SourceActor = ActorClassWithSpec(sourceSpec, {
|
|||
|
||||
const positions = [];
|
||||
for (const script of scripts) {
|
||||
const offsets = script.getAllColumnOffsets();
|
||||
const offsets = script.getPossibleBreakpoints();
|
||||
for (const { lineNumber, columnNumber } of offsets) {
|
||||
if (
|
||||
lineNumber < startLine ||
|
||||
|
@ -330,13 +330,7 @@ const SourceActor = ActorClassWithSpec(sourceSpec, {
|
|||
.sort((a, b) => {
|
||||
const lineDiff = a.line - b.line;
|
||||
return lineDiff === 0 ? a.column - b.column : lineDiff;
|
||||
})
|
||||
// Filter out duplicate locations since they are useless in this context.
|
||||
.filter((item, i, arr) => (
|
||||
i === 0 ||
|
||||
item.line !== arr[i - 1].line ||
|
||||
item.column !== arr[i - 1].column
|
||||
));
|
||||
});
|
||||
},
|
||||
|
||||
getBreakpointPositionsCompressed(query) {
|
||||
|
@ -449,12 +443,13 @@ const SourceActor = ActorClassWithSpec(sourceSpec, {
|
|||
// Find all entry points that correspond to the given location.
|
||||
const entryPoints = [];
|
||||
if (column === undefined) {
|
||||
// This is a line breakpoint, so we are interested in all offsets
|
||||
// that correspond to the given line number.
|
||||
// This is a line breakpoint, so we add a breakpoint on the first
|
||||
// breakpoint on the line.
|
||||
for (const script of scripts) {
|
||||
const offsets = script.getLineOffsets(line);
|
||||
const offsets = script.getPossibleBreakpointOffsets({ line });
|
||||
if (offsets.length > 0) {
|
||||
entryPoints.push({ script, offsets });
|
||||
entryPoints.push({ script, offsets: [offsets[0]] });
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -463,8 +458,7 @@ const SourceActor = ActorClassWithSpec(sourceSpec, {
|
|||
const columnToOffsetMaps = scripts.map(script =>
|
||||
[
|
||||
script,
|
||||
script.getAllColumnOffsets()
|
||||
.filter(({ lineNumber }) => lineNumber === line),
|
||||
script.getPossibleBreakpoints({ line }),
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
@ -607,51 +607,37 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
// "step" from another location.
|
||||
_intraFrameLocationIsStepTarget: function(startLocation, script, offset) {
|
||||
// Only allow stepping stops at entry points for the line.
|
||||
if (!script.getOffsetLocation(offset).isEntryPoint) {
|
||||
if (!script.getOffsetMetadata(offset).isBreakpoint) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cases when we have executed enough within a frame to consider a "step"
|
||||
// to have occured:
|
||||
//
|
||||
// 1. We change URLs (can happen without changing frames thanks to
|
||||
// source mapping).
|
||||
// 2. The source has pause points and we change locations.
|
||||
// 3. The source does not have pause points and we change lines.
|
||||
|
||||
const generatedLocation = this.sources.getScriptOffsetLocation(script, offset);
|
||||
|
||||
// Case 1.
|
||||
if (startLocation.generatedUrl !== generatedLocation.generatedUrl) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const pausePoints = generatedLocation.generatedSourceActor.pausePoints;
|
||||
// TODO(logan): When we remove points points, this can be removed too as
|
||||
// we assert that we're at a different frame offset from the last time
|
||||
// we paused.
|
||||
const lineChanged = startLocation.generatedLine !== generatedLocation.generatedLine;
|
||||
const columnChanged =
|
||||
startLocation.generatedColumn !== generatedLocation.generatedColumn;
|
||||
|
||||
if (!pausePoints) {
|
||||
// Case 3.
|
||||
return lineChanged;
|
||||
}
|
||||
|
||||
// Case 2.
|
||||
if (!lineChanged && !columnChanged) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// When pause points are specified for the source,
|
||||
// we should pause when we are at a stepOver pause point
|
||||
const pausePoint = findPausePointForLocation(pausePoints, generatedLocation);
|
||||
const pausePoints = generatedLocation.generatedSourceActor.pausePoints;
|
||||
const pausePoint = pausePoints &&
|
||||
findPausePointForLocation(pausePoints, generatedLocation);
|
||||
|
||||
if (pausePoint) {
|
||||
return pausePoint.step;
|
||||
}
|
||||
|
||||
// NOTE: if we do not find a pause point we want to
|
||||
// fall back on the old behavior (Case 3)
|
||||
return lineChanged;
|
||||
return script.getOffsetMetadata(offset).isStepStart;
|
||||
},
|
||||
|
||||
_makeOnStep: function({ thread, pauseAndRespond, startFrame,
|
||||
|
|
|
@ -273,7 +273,7 @@ TabSources.prototype = {
|
|||
* Returns an object of the form { source, line, column }
|
||||
*/
|
||||
getScriptOffsetLocation: function(script, offset) {
|
||||
const {lineNumber, columnNumber} = script.getOffsetLocation(offset);
|
||||
const {lineNumber, columnNumber} = script.getOffsetMetadata(offset);
|
||||
return new GeneratedLocation(
|
||||
this.createSourceActor(script.source),
|
||||
lineNumber,
|
||||
|
|
|
@ -16,7 +16,11 @@ add_task(threadClientTest(({ threadClient, debuggee }) => {
|
|||
threadClient,
|
||||
packet.frame.where.actor
|
||||
);
|
||||
const location = { sourceUrl: source.url, line: debuggee.line0 + 3 };
|
||||
const location = {
|
||||
sourceUrl: source.url,
|
||||
line: debuggee.line0 + 3,
|
||||
column: 5,
|
||||
};
|
||||
|
||||
threadClient.setBreakpoint(location, {});
|
||||
|
||||
|
@ -27,6 +31,16 @@ add_task(threadClientTest(({ threadClient, debuggee }) => {
|
|||
// Check that the breakpoint worked.
|
||||
Assert.equal(debuggee.i, 0);
|
||||
|
||||
// Remove the breakpoint.
|
||||
threadClient.removeBreakpoint(location);
|
||||
|
||||
const location2 = {
|
||||
sourceUrl: source.url,
|
||||
line: debuggee.line0 + 3,
|
||||
column: 12,
|
||||
};
|
||||
threadClient.setBreakpoint(location2, {});
|
||||
|
||||
threadClient.addOneTimeListener("paused", function(event, packet) {
|
||||
// Check the return value.
|
||||
Assert.equal(packet.type, "paused");
|
||||
|
@ -35,7 +49,7 @@ add_task(threadClientTest(({ threadClient, debuggee }) => {
|
|||
Assert.equal(debuggee.i, 1);
|
||||
|
||||
// Remove the breakpoint.
|
||||
threadClient.removeBreakpoint(location);
|
||||
threadClient.removeBreakpoint(location2);
|
||||
|
||||
threadClient.resume(resolve);
|
||||
});
|
||||
|
|
|
@ -16,7 +16,11 @@ add_task(threadClientTest(({ threadClient, debuggee }) => {
|
|||
threadClient,
|
||||
packet.frame.where.actor
|
||||
);
|
||||
const location = { sourceUrl: source.url, line: debuggee.line0 + 2 };
|
||||
const location = {
|
||||
sourceUrl: source.url,
|
||||
line: debuggee.line0 + 2,
|
||||
column: 8,
|
||||
};
|
||||
|
||||
threadClient.setBreakpoint(location, {});
|
||||
|
||||
|
@ -27,6 +31,17 @@ add_task(threadClientTest(({ threadClient, debuggee }) => {
|
|||
// Check that the breakpoint worked.
|
||||
Assert.equal(debuggee.a, undefined);
|
||||
|
||||
// Remove the breakpoint.
|
||||
threadClient.removeBreakpoint(location);
|
||||
|
||||
const location2 = {
|
||||
sourceUrl: source.url,
|
||||
line: debuggee.line0 + 2,
|
||||
column: 32,
|
||||
};
|
||||
|
||||
threadClient.setBreakpoint(location2, {});
|
||||
|
||||
threadClient.addOneTimeListener("paused", function(event, packet) {
|
||||
// Check the return value.
|
||||
Assert.equal(packet.type, "paused");
|
||||
|
@ -36,7 +51,7 @@ add_task(threadClientTest(({ threadClient, debuggee }) => {
|
|||
Assert.equal(debuggee.res, undefined);
|
||||
|
||||
// Remove the breakpoint.
|
||||
threadClient.removeBreakpoint(location);
|
||||
threadClient.removeBreakpoint(location2);
|
||||
|
||||
threadClient.resume(resolve);
|
||||
});
|
||||
|
|
|
@ -32,12 +32,6 @@ add_task(threadClientTest(({ threadClient, debuggee }) => {
|
|||
Assert.notEqual(packet.why.type, "breakpoint");
|
||||
Assert.equal(packet.why.type, "resumeLimit");
|
||||
},
|
||||
function(packet) {
|
||||
// At the end of the foo function call frame.
|
||||
Assert.equal(packet.frame.where.line, debuggee.line0 + 3);
|
||||
Assert.notEqual(packet.why.type, "breakpoint");
|
||||
Assert.equal(packet.why.type, "resumeLimit");
|
||||
},
|
||||
function(packet) {
|
||||
// Check that the breakpoint wasn't the reason for this pause, but
|
||||
// that the frame is about to be popped while stepping.
|
||||
|
|
|
@ -31,11 +31,6 @@ add_task(threadClientTest(({ threadClient, debuggee }) => {
|
|||
Assert.equal(packet.why.type, "breakpoint");
|
||||
Assert.notEqual(packet.why.type, "resumeLimit");
|
||||
},
|
||||
function(packet) {
|
||||
// Stepped to the closing brace of the function.
|
||||
Assert.equal(packet.frame.where.line, debuggee.line0 + 3);
|
||||
Assert.equal(packet.why.type, "resumeLimit");
|
||||
},
|
||||
function(packet) {
|
||||
// The frame is about to be popped while stepping.
|
||||
Assert.equal(packet.frame.where.line, debuggee.line0 + 3);
|
||||
|
|
|
@ -25,6 +25,9 @@ add_task(threadClientTest(async ({ threadClient, debuggee, client }) => {
|
|||
let variables = frame.environment.bindings.variables;
|
||||
Assert.equal(variables.i.value.type, "undefined");
|
||||
|
||||
const location2 = { sourceUrl: sourceClient.url, line: 7 };
|
||||
setBreakpoint(threadClient, location2);
|
||||
|
||||
packet = await executeOnNextTickAndWaitForPause(
|
||||
() => resume(threadClient),
|
||||
client
|
||||
|
@ -36,9 +39,9 @@ add_task(threadClientTest(async ({ threadClient, debuggee, client }) => {
|
|||
frame = packet.frame;
|
||||
where = frame.where;
|
||||
Assert.equal(where.actor, source.actor);
|
||||
Assert.equal(where.line, location.line);
|
||||
Assert.equal(where.line, location2.line);
|
||||
variables = frame.environment.bindings.variables;
|
||||
Assert.equal(variables.i.value, 0);
|
||||
Assert.equal(variables.i.value, 1);
|
||||
|
||||
await resume(threadClient);
|
||||
}, { doNotRunWorker: true }));
|
||||
|
|
|
@ -37,7 +37,12 @@ function run_test() {
|
|||
}
|
||||
|
||||
const SOURCE_URL = "http://example.com/foobar.js";
|
||||
const SOURCE_CONTENT = "stopMe()";
|
||||
const SOURCE_CONTENT = `
|
||||
stopMe();
|
||||
for(var i = 0; i < 2; i++) {
|
||||
debugger;
|
||||
}
|
||||
`;
|
||||
|
||||
function test_source() {
|
||||
DebuggerServer.LONG_STRING_LENGTH = 200;
|
||||
|
@ -60,11 +65,23 @@ function test_source() {
|
|||
Assert.deepEqual(
|
||||
response.positions,
|
||||
[{
|
||||
line: 1,
|
||||
column: 0,
|
||||
line: 2,
|
||||
column: 2,
|
||||
}, {
|
||||
line: 1,
|
||||
column: 8,
|
||||
line: 3,
|
||||
column: 14,
|
||||
}, {
|
||||
line: 3,
|
||||
column: 17,
|
||||
}, {
|
||||
line: 3,
|
||||
column: 24,
|
||||
}, {
|
||||
line: 4,
|
||||
column: 4,
|
||||
}, {
|
||||
line: 6,
|
||||
column: 0,
|
||||
}]
|
||||
);
|
||||
|
||||
|
@ -74,7 +91,10 @@ function test_source() {
|
|||
Assert.deepEqual(
|
||||
response.positions,
|
||||
{
|
||||
1: [0, 8],
|
||||
2: [2],
|
||||
3: [14, 17, 24],
|
||||
4: [4],
|
||||
6: [0],
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ async function stepOutOfA(dbg, func, expectedLocation) {
|
|||
|
||||
async function stepOverInA(dbg, func, expectedLocation) {
|
||||
await invokeAndPause(dbg, `${func}()`);
|
||||
await steps(dbg, [stepOver, stepIn, stepOver]);
|
||||
await steps(dbg, [stepOver, stepIn]);
|
||||
|
||||
let packet = await step(dbg, stepOver);
|
||||
dump(`>> stepOverInA hi\n`);
|
||||
|
@ -82,9 +82,9 @@ function run_test() {
|
|||
return (async function() {
|
||||
const dbg = await setupTestFromUrl("stepping.js");
|
||||
|
||||
await testStep(dbg, "arithmetic", {line: 16, column: 8});
|
||||
await testStep(dbg, "composition", {line: 21, column: 2});
|
||||
await testStep(dbg, "chaining", {line: 26, column: 6});
|
||||
await testStep(dbg, "arithmetic", {line: 17, column: 0});
|
||||
await testStep(dbg, "composition", {line: 22, column: 0});
|
||||
await testStep(dbg, "chaining", {line: 27, column: 0});
|
||||
|
||||
await testFinish(dbg);
|
||||
})();
|
||||
|
|
|
@ -49,7 +49,7 @@ async function testRet(dbg) {
|
|||
|
||||
info(`1. Test returning from doRet via stepping over`);
|
||||
await invokeAndPause(dbg, `doRet()`);
|
||||
await steps(dbg, [stepOver, stepIn, stepOver]);
|
||||
await steps(dbg, [stepOver, stepIn]);
|
||||
packet = await step(dbg, stepOver);
|
||||
|
||||
deepEqual(
|
||||
|
@ -89,7 +89,7 @@ async function testThrow(dbg) {
|
|||
|
||||
info(`3. Test leaving from doThrow via stepping over`);
|
||||
await invokeAndPause(dbg, `doThrow()`);
|
||||
await steps(dbg, [stepOver, stepOver, stepIn]);
|
||||
await steps(dbg, [stepOver, stepIn]);
|
||||
packet = await step(dbg, stepOver);
|
||||
|
||||
deepEqual(
|
||||
|
@ -113,24 +113,19 @@ async function testThrow(dbg) {
|
|||
|
||||
info(`4. Test leaving from doThrow via stepping out`);
|
||||
await invokeAndPause(dbg, `doThrow()`);
|
||||
await steps(dbg, [stepOver, stepOver, stepIn]);
|
||||
await steps(dbg, [stepOver, stepIn]);
|
||||
|
||||
packet = await step(dbg, stepOut);
|
||||
deepEqual(
|
||||
getPauseLocation(packet),
|
||||
{line: 22, column: 14},
|
||||
`completion location in doThrow`
|
||||
{line: 24, column: 0},
|
||||
`stepOut location in doThrow`
|
||||
);
|
||||
|
||||
deepEqual(
|
||||
getFrameFinished(packet).throw.class,
|
||||
"Error",
|
||||
`completion completion value class`
|
||||
);
|
||||
deepEqual(
|
||||
getFrameFinished(packet).throw.preview.message,
|
||||
"yo",
|
||||
`completion completion value preview`
|
||||
getFrameFinished(packet),
|
||||
{return: {type: "undefined"}},
|
||||
`completion type`
|
||||
);
|
||||
await resume(dbg.threadClient);
|
||||
}
|
||||
|
|
|
@ -29,17 +29,14 @@ add_task(threadClientTest(async ({ threadClient, debuggee, client }) => {
|
|||
dumpn("Continuing and waiting for second debugger statement");
|
||||
const dbgStmt2 = await resumeAndWaitForPause(client, threadClient);
|
||||
equal(dbgStmt2.frame.where.line, 12,
|
||||
"Should be at debugger statement on line 3");
|
||||
"Should be at debugger statement on line 12");
|
||||
|
||||
dumpn("Testing stepping with explicit return");
|
||||
const step3 = await stepOver(client, threadClient);
|
||||
equal(step3.frame.where.line, 13, "Should step to line 13");
|
||||
const step4 = await stepOver(client, threadClient);
|
||||
equal(step4.frame.where.line, 15, "Should step out of the function from line 15");
|
||||
// This step is a bit funny, see bug 1013219 for details.
|
||||
const step5 = await stepOver(client, threadClient);
|
||||
equal(step5.frame.where.line, 15, "Should step out of the function from line 15");
|
||||
ok(step5.why.frameFinished, "This should be the explicit function return");
|
||||
ok(step4.why.frameFinished, "This should be the explicit function return");
|
||||
}));
|
||||
|
||||
function evaluateTestCode(debuggee) {
|
||||
|
|
|
@ -21,13 +21,17 @@ add_task(threadClientTest(async ({ threadClient, debuggee, client }) => {
|
|||
await threadClient.setBreakpoint({ sourceUrl: source.url, line: 7 }, {});
|
||||
|
||||
dumpn("Step in to innerFunction");
|
||||
const step1 = await stepIn(client, threadClient);
|
||||
equal(step1.frame.where.line, 7);
|
||||
const step1 = await stepOver(client, threadClient);
|
||||
equal(step1.frame.where.line, 3);
|
||||
|
||||
dumpn("Step in to innerFunction");
|
||||
const step2 = await stepIn(client, threadClient);
|
||||
equal(step2.frame.where.line, 7);
|
||||
|
||||
dumpn("Step out of innerFunction");
|
||||
const step2 = await stepOut(client, threadClient);
|
||||
const step3 = await stepOut(client, threadClient);
|
||||
// The bug was that we'd stop again at the breakpoint on line 7.
|
||||
equal(step2.frame.where.line, 4);
|
||||
equal(step3.frame.where.line, 4);
|
||||
}));
|
||||
|
||||
function evaluateTestCode(debuggee) {
|
||||
|
|
|
@ -18,7 +18,7 @@ add_task(threadClientTest(async ({ threadClient, debuggee, client }) => {
|
|||
const step2 = await stepOut(client, threadClient);
|
||||
// The bug was that we'd step right past the end of the function and never pause.
|
||||
equal(step2.frame.where.line, 2);
|
||||
equal(step2.why.frameFinished.return, 42);
|
||||
deepEqual(step2.why.frameFinished.return, { type: "undefined"});
|
||||
}));
|
||||
|
||||
function evaluateTestCode(debuggee) {
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* eslint-disable no-shadow, max-nested-callbacks */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Check basic step-over functionality with pause points
|
||||
* for the first statement and end of the last statement.
|
||||
*/
|
||||
|
||||
add_task(threadClientTest(async ({ threadClient, debuggee, client }) => {
|
||||
dumpn("Evaluating test code and waiting for first debugger statement");
|
||||
const dbgStmt = await executeOnNextTickAndWaitForPause(
|
||||
() => evaluateTestCode(debuggee), client);
|
||||
equal(dbgStmt.frame.where.line, 2, "Should be at debugger statement on line 2");
|
||||
equal(debuggee.a, undefined);
|
||||
equal(debuggee.b, undefined);
|
||||
|
||||
const source = await getSource(threadClient, "test_stepping-01-test-code.js");
|
||||
|
||||
// Add pause points for the first and end of the last statement.
|
||||
// Note: we intentionally ignore the second statement.
|
||||
source.setPausePoints([{
|
||||
location: {line: 3, column: 8},
|
||||
types: {breakpoint: true, stepOver: true},
|
||||
},
|
||||
{
|
||||
location: {line: 4, column: 14},
|
||||
types: {breakpoint: true, stepOver: true},
|
||||
}]);
|
||||
|
||||
dumpn("Step Over to line 3");
|
||||
const step1 = await stepOver(client, threadClient);
|
||||
equal(step1.type, "paused");
|
||||
equal(step1.why.type, "resumeLimit");
|
||||
equal(step1.frame.where.line, 3);
|
||||
equal(step1.frame.where.column, 0);
|
||||
|
||||
equal(debuggee.a, undefined);
|
||||
equal(debuggee.b, undefined);
|
||||
|
||||
dumpn("Step Over to line 4");
|
||||
const step2 = await stepOver(client, threadClient);
|
||||
equal(step2.type, "paused");
|
||||
equal(step2.why.type, "resumeLimit");
|
||||
equal(step2.frame.where.line, 4);
|
||||
equal(step2.frame.where.column, 0);
|
||||
|
||||
equal(debuggee.a, 1);
|
||||
equal(debuggee.b, undefined);
|
||||
|
||||
dumpn("Step Over to the end of line 4");
|
||||
const step3 = await stepOver(client, threadClient);
|
||||
equal(step3.type, "paused");
|
||||
equal(step3.why.type, "resumeLimit");
|
||||
equal(step3.frame.where.line, 4);
|
||||
equal(step3.frame.where.column, 14);
|
||||
equal(debuggee.a, 1);
|
||||
equal(debuggee.b, 2);
|
||||
}));
|
||||
|
||||
function evaluateTestCode(debuggee) {
|
||||
/* eslint-disable */
|
||||
Cu.evalInSandbox(
|
||||
` // 1
|
||||
debugger; // 2
|
||||
var a = 1; // 3
|
||||
var b = 2;`, // 4
|
||||
debuggee,
|
||||
"1.8",
|
||||
"test_stepping-01-test-code.js",
|
||||
1
|
||||
);
|
||||
/* eslint-disable */
|
||||
}
|
|
@ -35,7 +35,7 @@ add_task(threadClientTest(async ({ threadClient, debuggee, client }) => {
|
|||
equal(step1.type, "paused");
|
||||
equal(step1.why.type, "resumeLimit");
|
||||
equal(step1.frame.where.line, 3);
|
||||
equal(step1.frame.where.column, 0);
|
||||
equal(step1.frame.where.column, 12);
|
||||
|
||||
equal(debuggee.a, undefined);
|
||||
equal(debuggee.b, undefined);
|
||||
|
@ -45,7 +45,7 @@ add_task(threadClientTest(async ({ threadClient, debuggee, client }) => {
|
|||
equal(step2.type, "paused");
|
||||
equal(step2.why.type, "resumeLimit");
|
||||
equal(step2.frame.where.line, 4);
|
||||
equal(step2.frame.where.column, 0);
|
||||
equal(step2.frame.where.column, 12);
|
||||
|
||||
equal(debuggee.a, 1);
|
||||
equal(debuggee.b, undefined);
|
||||
|
|
|
@ -192,7 +192,6 @@ skip-if = true # breakpoint sliding is not supported bug 1525685
|
|||
[test_stepping-07.js]
|
||||
[test_stepping-08.js]
|
||||
[test_stepping-09.js]
|
||||
[test_stepping-with-pause-points.js]
|
||||
[test_stepping-with-skip-breakpoints.js]
|
||||
[test_framebindings-01.js]
|
||||
[test_framebindings-02.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче