зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1447316 - The debugger should use pausePoints to decide where to stop. r=jimb
MozReview-Commit-ID: 4Sxz0VIKB3j
This commit is contained in:
Родитель
e561bf58c4
Коммит
2fef0dedc3
|
@ -661,6 +661,21 @@ let SourceActor = ActorClassWithSpec(sourceSpec, {
|
|||
this.threadActor.sources.unblackBox(this.url);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for the "setPausePoints" packet.
|
||||
*
|
||||
* @param Array pausePoints
|
||||
* A list of pausePoint objects
|
||||
*
|
||||
* type PausePoint = {
|
||||
* location: { line: number, column: number }
|
||||
* types: { breakpoint: boolean, stepOver: boolean }
|
||||
* }
|
||||
*/
|
||||
setPausePoints: function(pausePoints) {
|
||||
this.pausePoints = pausePoints;
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle a request to set a breakpoint.
|
||||
*
|
||||
|
|
|
@ -497,7 +497,8 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
// 1.1. We change frames.
|
||||
// 1.2. We change URLs (can happen without changing frames thanks to
|
||||
// source mapping).
|
||||
// 1.3. We change lines.
|
||||
// 1.3. The source has pause points and we change locations.
|
||||
// 1.4 The source does not have pause points and We change lines.
|
||||
//
|
||||
// Cases when we should always continue execution, even if one of the
|
||||
// above cases is true:
|
||||
|
@ -512,10 +513,33 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
// Cases 1.1, 1.2 and 1.3
|
||||
if (this !== startFrame
|
||||
|| startLocation.originalUrl !== newLocation.originalUrl
|
||||
|| startLocation.originalLine !== newLocation.originalLine) {
|
||||
// Cases 1.1, 1.2
|
||||
if (this !== startFrame || startLocation.originalUrl !== newLocation.originalUrl) {
|
||||
return pauseAndRespond(this);
|
||||
}
|
||||
|
||||
const pausePoints = newLocation.originalSourceActor.pausePoints;
|
||||
|
||||
if (!pausePoints) {
|
||||
// Case 1.4
|
||||
if (startLocation.originalLine !== newLocation.originalLine) {
|
||||
return pauseAndRespond(this);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Case 1.3
|
||||
if (
|
||||
startLocation.originalLine === newLocation.originalLine
|
||||
&& startLocation.originalColumn === newLocation.originalColumn
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// When pause points are specified for the source,
|
||||
// we should pause when we are at a stepOver pause point
|
||||
const pausePoint = findPausePointForLocation(pausePoints, newLocation);
|
||||
if (pausePoint && pausePoint.types.stepOver) {
|
||||
return pauseAndRespond(this);
|
||||
}
|
||||
|
||||
|
@ -1888,6 +1912,13 @@ function findEntryPointsForLine(scripts, line) {
|
|||
return entryPoints;
|
||||
}
|
||||
|
||||
function findPausePointForLocation(pausePoints, location) {
|
||||
return pausePoints.find(pausePoint =>
|
||||
pausePoint.location.line === location.originalLine
|
||||
&& pausePoint.location.column === location.originalColumn
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwrap a global that is wrapped in a |Debugger.Object|, or if the global has
|
||||
* become a dead object, return |undefined|.
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
var gDebuggee;
|
||||
var gClient;
|
||||
var gCallback;
|
||||
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
run_test_with_server(DebuggerServer, function() {
|
||||
run_test_with_server(WorkerDebuggerServer, do_test_finished);
|
||||
});
|
||||
}
|
||||
|
||||
function run_test_with_server(server, callback) {
|
||||
gCallback = callback;
|
||||
initTestDebuggerServer(server);
|
||||
gDebuggee = addTestGlobal("test-stepping", server);
|
||||
gClient = new DebuggerClient(server.connectPipe());
|
||||
gClient.connect(test_simple_stepping);
|
||||
}
|
||||
|
||||
async function test_simple_stepping() {
|
||||
const [attachResponse,, threadClient] = await attachTestTabAndResume(gClient,
|
||||
"test-stepping");
|
||||
ok(!attachResponse.error, "Should not get an error attaching");
|
||||
|
||||
dumpn("Evaluating test code and waiting for first debugger statement");
|
||||
const dbgStmt = await executeOnNextTickAndWaitForPause(evaluateTestCode, gClient);
|
||||
equal(dbgStmt.frame.where.line, 2, "Should be at debugger statement on line 2");
|
||||
equal(gDebuggee.a, undefined);
|
||||
equal(gDebuggee.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(gClient, threadClient);
|
||||
equal(step1.type, "paused");
|
||||
equal(step1.why.type, "resumeLimit");
|
||||
equal(step1.frame.where.line, 3);
|
||||
equal(step1.frame.where.column, 8);
|
||||
|
||||
equal(gDebuggee.a, undefined);
|
||||
equal(gDebuggee.b, undefined);
|
||||
|
||||
dumpn("Step Over to the end of line 4");
|
||||
const step4 = await stepOver(gClient, threadClient);
|
||||
equal(step4.type, "paused");
|
||||
equal(step4.why.type, "resumeLimit");
|
||||
equal(step4.frame.where.line, 4);
|
||||
equal(step4.frame.where.column, 14);
|
||||
equal(gDebuggee.a, 1);
|
||||
equal(gDebuggee.b, 2);
|
||||
|
||||
finishClient(gClient, gCallback);
|
||||
}
|
||||
|
||||
function evaluateTestCode() {
|
||||
/* eslint-disable */
|
||||
Cu.evalInSandbox(
|
||||
` // 1
|
||||
debugger; // 2
|
||||
var a = 1; // 3
|
||||
var b = 2;`, // 4
|
||||
gDebuggee,
|
||||
"1.8",
|
||||
"test_stepping-01-test-code.js",
|
||||
1
|
||||
);
|
||||
/* eslint-disable */
|
||||
}
|
|
@ -190,6 +190,7 @@ reason = only ran on B2G
|
|||
[test_stepping-06.js]
|
||||
[test_stepping-07.js]
|
||||
[test_stepping-08.js]
|
||||
[test_stepping-with-pause-points.js]
|
||||
[test_framebindings-01.js]
|
||||
[test_framebindings-02.js]
|
||||
[test_framebindings-03.js]
|
||||
|
|
|
@ -276,7 +276,16 @@ SourceClient.prototype = {
|
|||
|
||||
return doSetBreakpoint(cleanUp);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
setPausePoints: function(pausePoints) {
|
||||
const packet = {
|
||||
to: this._form.actor,
|
||||
type: "setPausePoints",
|
||||
pausePoints
|
||||
};
|
||||
return this._client.request(packet);
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = SourceClient;
|
||||
|
|
|
@ -21,6 +21,11 @@ const sourceSpec = generateActorSpec({
|
|||
disablePrettyPrint: {
|
||||
response: RetVal("json")
|
||||
},
|
||||
setPausePoints: {
|
||||
request: {
|
||||
pausePoints: Arg(0, "json"),
|
||||
}
|
||||
},
|
||||
blackbox: { response: { pausedInSource: RetVal("boolean") } },
|
||||
unblackbox: {},
|
||||
setBreakpoint: {
|
||||
|
|
Загрузка…
Ссылка в новой задаче