Bug 978019 - Fix breakpoints after reload on immediately invoked function expressions; r=past

This commit is contained in:
Nick Fitzgerald 2014-03-07 11:06:28 -08:00
Родитель d982916c7e
Коммит 92419315ec
6 изменённых файлов: 106 добавлений и 4 удалений

Просмотреть файл

@ -9,6 +9,7 @@ support-files =
code_blackboxing_one.js
code_blackboxing_three.js
code_blackboxing_two.js
code_breakpoints-break-on-last-line-of-script-on-reload.js
code_function-search-01.js
code_function-search-02.js
code_function-search-03.js
@ -34,6 +35,7 @@ support-files =
doc_auto-pretty-print-02.html
doc_binary_search.html
doc_blackboxing.html
doc_breakpoints-break-on-last-line-of-script-on-reload.html
doc_closures.html
doc_cmd-break.html
doc_cmd-dbg.html
@ -97,6 +99,7 @@ support-files =
[browser_dbg_break-on-dom-07.js]
[browser_dbg_break-on-dom-08.js]
[browser_dbg_breakpoints-actual-location.js]
[browser_dbg_breakpoints-break-on-last-line-of-script-on-reload.js]
[browser_dbg_breakpoints-button-01.js]
[browser_dbg_breakpoints-button-02.js]
[browser_dbg_breakpoints-contextmenu.js]

Просмотреть файл

@ -0,0 +1,79 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Bug 978019: Setting a breakpoint on the last line of a Debugger.Script and
* reloading should still hit the breakpoint.
*/
const TAB_URL = EXAMPLE_URL + "doc_breakpoints-break-on-last-line-of-script-on-reload.html";
const CODE_URL = EXAMPLE_URL + "code_breakpoints-break-on-last-line-of-script-on-reload.js";
const { promiseInvoke } = require("devtools/async-utils");
function test() {
let gPanel, gDebugger, gThreadClient, gEvents;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gThreadClient = gDebugger.gThreadClient;
gEvents = gDebugger.EVENTS;
Task.spawn(function* () {
yield waitForSourceShown(gPanel, CODE_URL);
// Pause and set our breakpoints.
yield doInterrupt();
yield promise.all([
gPanel.addBreakpoint({
url: CODE_URL,
line: 2
}),
gPanel.addBreakpoint({
url: CODE_URL,
line: 3
}),
gPanel.addBreakpoint({
url: CODE_URL,
line: 4
})
]);
// Should hit the first breakpoint on reload.
yield promise.all([
reloadActiveTab(gPanel, gEvents.SOURCE_SHOWN),
waitForCaretUpdated(gPanel, 2)
]);
// And should hit the other breakpoints as we resume.
yield promise.all([
doResume(),
waitForCaretUpdated(gPanel, 3)
]);
yield promise.all([
doResume(),
waitForCaretUpdated(gPanel, 4)
]);
yield resumeDebuggerThenCloseAndFinish(gPanel);
});
});
function rdpInvoke(obj, method) {
return promiseInvoke(obj, method)
.then(({error, message }) => {
if (error) {
throw new Error(error + ": " + message);
}
});
}
function doResume() {
return rdpInvoke(gThreadClient, gThreadClient.resume);
}
function doInterrupt() {
return rdpInvoke(gThreadClient, gThreadClient.interrupt);
}
}

Просмотреть файл

@ -0,0 +1,5 @@
var a = (function(){
var b = 9;
console.log("x", b);
return b;
})();

Просмотреть файл

@ -0,0 +1,8 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!DOCTYPE html>
<head>
<meta charset="utf-8"/>
<title>Debugger Break on Last Line of Script on Reload Test Page</title>
</head>
<script src="code_breakpoints-break-on-last-line-of-script-on-reload.js"></script>

Просмотреть файл

@ -16,6 +16,7 @@ let { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
let { Promise: promise } = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {});
let { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
let { require } = devtools;
let { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
let { BrowserToolboxProcess } = Cu.import("resource:///modules/devtools/ToolboxProcess.jsm", {});
let { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});

Просмотреть файл

@ -1892,8 +1892,7 @@ ThreadActor.prototype = {
* @return The EnvironmentActor for aEnvironment or undefined for host
* functions or functions scoped to a non-debuggee global.
*/
createEnvironmentActor:
function (aEnvironment, aPool) {
createEnvironmentActor: function (aEnvironment, aPool) {
if (!aEnvironment) {
return undefined;
}
@ -1954,8 +1953,7 @@ ThreadActor.prototype = {
* Return a protocol completion value representing the given
* Debugger-provided completion value.
*/
createProtocolCompletionValue:
function (aCompletion) {
createProtocolCompletionValue: function (aCompletion) {
let protoValue = {};
if ("return" in aCompletion) {
protoValue.return = this.createValueGrip(aCompletion.return);
@ -2194,6 +2192,14 @@ ThreadActor.prototype = {
*/
onNewScript: function (aScript, aGlobal) {
this._addScript(aScript);
// |onNewScript| is only fired for top level scripts (AKA staticLevel == 0),
// so we have to make sure to call |_addScript| on every child script as
// well to restore breakpoints in those scripts.
for (let s of aScript.getChildScripts()) {
this._addScript(s);
}
this.sources.sourcesForScript(aScript);
},