Commit ec5ab775 authored by Joel Einbinder's avatar Joel Einbinder Committed by Commit Bot

DevTools: Fix breakpoints after externally editing a file

Change-Id: I84e9dfd26c69b0673086112e5d6078b33f2eb323
Reviewed-on: https://chromium-review.googlesource.com/935465
Commit-Queue: Joel Einbinder <einbinder@chromium.org>
Reviewed-by: default avatarPavel Feldman <pfeldman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#541385}
parent 6ba75010
Verify that breakpoints survive external editing.
Running: addFileSystem
Running: setBreakpointInFileSystemUISourceCode
breakpoint at 2
inline breakpoint at (2, 0)
inline breakpoint at (2, 17) disabled
inline breakpoint at (2, 22) disabled
inline breakpoint at (2, 23) disabled
Running: addCommitToFilesystemUISourceCode
breakpoint at 2
inline breakpoint at (2, 0)
inline breakpoint at (2, 8) disabled
inline breakpoint at (2, 36) disabled
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(async function() {
TestRunner.addResult(`Verify that breakpoints survive external editing.\n`);
await TestRunner.loadModule('sources_test_runner');
await TestRunner.loadModule('bindings_test_runner');
await TestRunner.addScriptTag('resources/foo.js');
await TestRunner.showPanel('sources');
var testMapping = BindingsTestRunner.initializeTestMapping();
var fs = new BindingsTestRunner.TestFileSystem('file:///var/www');
var fsEntry = BindingsTestRunner.addFooJSFile(fs);
TestRunner.runTestSuite([
function addFileSystem(next) {
fs.reportCreated(next);
},
async function setBreakpointInFileSystemUISourceCode(next) {
testMapping.addBinding('foo.js');
await BindingsTestRunner.waitForBinding('foo.js');
var uiSourceCode = await TestRunner.waitForUISourceCode('foo.js', Workspace.projectTypes.FileSystem);
var sourceFrame = await SourcesTestRunner.showUISourceCodePromise(uiSourceCode);
SourcesTestRunner.setBreakpoint(sourceFrame, 2, '', true);
await TestRunner.addSnifferPromise(sourceFrame, '_breakpointDecorationsUpdatedForTest');
await SourcesTestRunner.dumpJavaScriptSourceFrameBreakpoints(sourceFrame);
next();
},
async function addCommitToFilesystemUISourceCode(next) {
await new Promise(x => setTimeout(x, 1000));
var uiSourceCode = await TestRunner.waitForUISourceCode('foo.js', Workspace.projectTypes.FileSystem);
var sourceFrame = await SourcesTestRunner.showUISourceCodePromise(uiSourceCode);
var promise = TestRunner.addSnifferPromise(SDK.DebuggerModel.prototype, '_didEditScriptSource');
uiSourceCode.addRevision(`
var w = 'some content';
var x = 'new content'; var inline = 'something else';
var y = 'more new content';`);
await promise;
await TestRunner.addSnifferPromise(sourceFrame, '_breakpointDecorationsUpdatedForTest');
await SourcesTestRunner.dumpJavaScriptSourceFrameBreakpoints(sourceFrame);
next();
}
]);
})();
\ No newline at end of file
......@@ -467,6 +467,13 @@ Bindings.BreakpointManager.Breakpoint = class {
this._breakpointManager._targetManager.observeModels(SDK.DebuggerModel, this);
}
refreshInDebugger() {
if (this._isRemoved)
return;
for (const breakpoint of this._modelBreakpoints.values())
breakpoint._refreshBreakpoint();
}
/**
* @override
* @param {!SDK.DebuggerModel} debuggerModel
......@@ -784,10 +791,8 @@ Bindings.BreakpointManager.ModelBreakpoint = class {
this._breakpoint._currentState = newState;
if (this._debuggerId) {
this._resetLocations();
this._debuggerModel.removeBreakpoint(this._debuggerId).then(this._didRemoveFromDebugger.bind(this, callback));
this._scheduleUpdateInDebugger();
this._currentState = null;
await this._refreshBreakpoint();
callback();
return;
}
......@@ -811,6 +816,16 @@ Bindings.BreakpointManager.ModelBreakpoint = class {
this._didSetBreakpointInDebugger(callback, null, []);
}
async _refreshBreakpoint() {
if (!this._debuggerId)
return;
this._resetLocations();
await this._debuggerModel.removeBreakpoint(this._debuggerId);
this._didRemoveFromDebugger();
this._currentState = null;
this._scheduleUpdateInDebugger();
}
/**
* @param {function()} callback
* @param {?Protocol.Debugger.BreakpointId} breakpointId
......@@ -838,20 +853,15 @@ Bindings.BreakpointManager.ModelBreakpoint = class {
callback();
}
/**
* @param {function()} callback
*/
_didRemoveFromDebugger(callback) {
_didRemoveFromDebugger() {
if (this._cancelCallback) {
this._cancelCallback = false;
callback();
return;
}
this._resetLocations();
this._debuggerModel.removeBreakpointListener(this._debuggerId, this._breakpointResolved, this);
delete this._debuggerId;
callback();
}
/**
......@@ -901,7 +911,7 @@ Bindings.BreakpointManager.ModelBreakpoint = class {
this._resetLocations();
this._currentState = null;
if (this._debuggerId)
this._didRemoveFromDebugger(function() {});
this._didRemoveFromDebugger();
}
_removeEventListeners() {
......
......@@ -308,6 +308,7 @@ Bindings.ResourceScriptFile = class extends Common.Object {
if (!this._script)
return;
const debuggerModel = this._resourceScriptMapping._debuggerModel;
const breakpoints = Bindings.breakpointManager.breakpointsForUISourceCode(this._uiSourceCode);
const source = this._uiSourceCode.workingCopy();
debuggerModel.setScriptSource(this._script.scriptId, source, scriptSourceWasSet.bind(this));
......@@ -316,13 +317,17 @@ Bindings.ResourceScriptFile = class extends Common.Object {
* @param {!Protocol.Runtime.ExceptionDetails=} exceptionDetails
* @this {Bindings.ResourceScriptFile}
*/
function scriptSourceWasSet(error, exceptionDetails) {
async function scriptSourceWasSet(error, exceptionDetails) {
if (!error && !exceptionDetails)
this._scriptSource = source;
this._update();
if (!error && !exceptionDetails)
if (!error && !exceptionDetails) {
// Live edit can cause breakpoints to be in the wrong position, or to be lost altogether.
// If any breakpoints were in the pre-live edit script, they need to be re-added.
breakpoints.map(breakpoint => breakpoint.refreshInDebugger());
return;
}
if (!exceptionDetails) {
Common.console.addMessage(Common.UIString('LiveEdit failed: %s', error), Common.Console.MessageLevel.Warning);
return;
......
......@@ -180,17 +180,6 @@ Sources.JavaScriptSourceFrame = class extends Sources.UISourceCodeFrame {
this._popoverHelper.hidePopover();
}
/**
* @override
*/
onUISourceCodeContentChanged() {
for (const decoration of this._breakpointDecorations) {
if (decoration.breakpoint)
decoration.breakpoint.remove();
}
super.onUISourceCodeContentChanged();
}
/**
* @override
*/
......
......@@ -232,17 +232,14 @@ Sources.UISourceCodeFrame = class extends SourceFrame.SourceFrame {
if (this._muteSourceCodeEvents)
return;
this._innerSetContent(this._uiSourceCode.workingCopy());
this.onUISourceCodeContentChanged();
}
/**
* @param {!Common.Event} event
*/
_onWorkingCopyCommitted(event) {
if (!this._muteSourceCodeEvents) {
if (!this._muteSourceCodeEvents)
this._innerSetContent(this._uiSourceCode.workingCopy());
this.onUISourceCodeContentChanged();
}
this.textEditor.markClean();
this._updateStyle();
}
......@@ -311,9 +308,6 @@ Sources.UISourceCodeFrame = class extends SourceFrame.SourceFrame {
this.setEditable(this._canEditSource());
}
onUISourceCodeContentChanged() {
}
/**
* @param {string} content
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment