Index: Source/devtools/front_end/sdk/BreakpointManager.js |
diff --git a/Source/devtools/front_end/sdk/BreakpointManager.js b/Source/devtools/front_end/sdk/BreakpointManager.js |
index 2c0ef4f66e1f4d463447f640ee423b4272a1e89f..0045df84f90de2d83d63f239050d7cb3a1970c1c 100644 |
--- a/Source/devtools/front_end/sdk/BreakpointManager.js |
+++ b/Source/devtools/front_end/sdk/BreakpointManager.js |
@@ -31,7 +31,6 @@ |
/** |
* @constructor |
* @extends {WebInspector.Object} |
- * @implements {WebInspector.TargetManager.Observer} |
* @param {!WebInspector.Setting} breakpointStorage |
* @param {!WebInspector.Workspace} workspace |
* @param {!WebInspector.TargetManager} targetManager |
@@ -42,7 +41,6 @@ WebInspector.BreakpointManager = function(breakpointStorage, workspace, targetMa |
this._workspace = workspace; |
this._targetManager = targetManager; |
- this._breakpointForDebuggerId = {}; |
this._breakpointsForUISourceCode = new Map(); |
this._breakpointsForPrimaryUISourceCode = new Map(); |
/** @type {!StringMultimap.<!WebInspector.BreakpointManager.Breakpoint>} */ |
@@ -51,7 +49,6 @@ WebInspector.BreakpointManager = function(breakpointStorage, workspace, targetMa |
this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this); |
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this); |
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this); |
- this._targetManager.observeTargets(this); |
} |
WebInspector.BreakpointManager.Events = { |
@@ -80,21 +77,6 @@ WebInspector.BreakpointManager._breakpointStorageId = function(sourceFileId, lin |
} |
WebInspector.BreakpointManager.prototype = { |
- /** |
- * @param {!WebInspector.Target} target |
- */ |
- targetAdded: function(target) |
- { |
- target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointResolved, this._breakpointResolved, this); |
- }, |
- |
- /** |
- * @param {!WebInspector.Target} target |
- */ |
- targetRemoved: function(target) |
- { |
- target.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.BreakpointResolved, this._breakpointResolved, this); |
- }, |
/** |
* @param {string} sourceFileId |
@@ -109,17 +91,11 @@ WebInspector.BreakpointManager.prototype = { |
return result; |
}, |
- /** |
- * @param {!WebInspector.Target} target |
- */ |
- removeProvisionalBreakpointsForTest: function(target) |
+ removeProvisionalBreakpointsForTest: function() |
{ |
var breakpoints = this._provisionalBreakpoints.values(); |
- for (var i = 0; i < breakpoints.length; ++i) { |
- var debuggerId = breakpoints[i]._debuggerId; |
- if (debuggerId) |
- target.debuggerModel.removeBreakpoint(debuggerId); |
- } |
+ for (var i = 0; i < breakpoints.length; ++i) |
+ breakpoints[i].remove(); |
this._provisionalBreakpoints.clear(); |
}, |
@@ -143,7 +119,7 @@ WebInspector.BreakpointManager.prototype = { |
if (!this._breakpointsForPrimaryUISourceCode.get(uiSourceCode)) |
this._breakpointsForPrimaryUISourceCode.put(uiSourceCode, []); |
this._breakpointsForPrimaryUISourceCode.get(uiSourceCode).push(provisionalBreakpoint); |
- provisionalBreakpoint._updateInDebugger(); |
+ provisionalBreakpoint._updateBreakpoint(); |
} else { |
this._innerSetBreakpoint(uiSourceCode, breakpointItem.lineNumber, breakpointItem.columnNumber, breakpointItem.condition, breakpointItem.enabled); |
} |
@@ -230,7 +206,7 @@ WebInspector.BreakpointManager.prototype = { |
{ |
var breakpoint = this.findBreakpoint(uiSourceCode, lineNumber, columnNumber); |
if (breakpoint) { |
- breakpoint._updateBreakpoint(condition, enabled); |
+ breakpoint._updateState(condition, enabled); |
return breakpoint; |
} |
var projectId = uiSourceCode.project().id(); |
@@ -361,16 +337,6 @@ WebInspector.BreakpointManager.prototype = { |
this._removeUISourceCode(uiSourceCodes[i]); |
}, |
- _breakpointResolved: function(event) |
- { |
- var breakpointId = /** @type {!DebuggerAgent.BreakpointId} */ (event.data.breakpointId); |
- var location = /** @type {!WebInspector.DebuggerModel.Location} */ (event.data.location); |
- var breakpoint = this._breakpointForDebuggerId[breakpointId]; |
- if (!breakpoint) |
- return; |
- breakpoint._addResolvedLocation(location); |
- }, |
- |
/** |
* @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint |
* @param {boolean} removeFromStorage |
@@ -379,9 +345,7 @@ WebInspector.BreakpointManager.prototype = { |
{ |
var uiSourceCode = breakpoint.uiSourceCode(); |
var breakpoints = uiSourceCode ? this._breakpointsForPrimaryUISourceCode.get(uiSourceCode) || [] : []; |
- var index = breakpoints.indexOf(breakpoint); |
- if (index > -1) |
- breakpoints.splice(index, 1); |
+ breakpoints.remove(breakpoint); |
if (removeFromStorage) |
this._storage._removeBreakpoint(breakpoint); |
this._provisionalBreakpoints.remove(breakpoint._sourceFileId, breakpoint); |
@@ -443,6 +407,7 @@ WebInspector.BreakpointManager.prototype = { |
/** |
* @constructor |
+ * @implements {WebInspector.TargetManager.Observer} |
* @param {!WebInspector.BreakpointManager} breakpointManager |
* @param {string} projectId |
* @param {string} path |
@@ -460,22 +425,41 @@ WebInspector.BreakpointManager.Breakpoint = function(breakpointManager, projectI |
this._lineNumber = lineNumber; |
this._columnNumber = columnNumber; |
this._sourceFileId = sourceFileId; |
- /** @type {!Array.<!WebInspector.Script.Location>} */ |
- this._liveLocations = []; |
- /** @type {!Object.<string, !WebInspector.UILocation>} */ |
- this._uiLocations = {}; |
/** @type {!Object.<string, number>} */ |
- this._numberOfDebuggerLocationForUILocation = new Map(); |
+ this._numberOfDebuggerLocationForUILocation = {}; |
// Force breakpoint update. |
/** @type {string} */ this._condition; |
/** @type {boolean} */ this._enabled; |
- this._updateBreakpoint(condition, enabled); |
+ /** @type {boolean} */ this._isRemoved; |
+ /** @type {!WebInspector.UILocation|undefined} */ this._fakeBreakpointPrimaryLocation; |
vsevik
2014/06/05 13:19:10
nit: this._fakePrimaryLocation
sergeyv
2014/06/05 13:25:54
Done.
|
+ |
+ /** @type {!Map.<!WebInspector.Target, !WebInspector.BreakpointManager.TargetBreakpoint>}*/ |
+ this._targetBreakpoints = new Map(); |
+ this._breakpointManager._targetManager.observeTargets(this); |
+ this._updateState(condition, enabled); |
} |
WebInspector.BreakpointManager.Breakpoint.prototype = { |
/** |
+ * @param {!WebInspector.Target} target |
+ */ |
+ targetAdded: function(target) |
+ { |
+ this._targetBreakpoints.put(target, new WebInspector.BreakpointManager.TargetBreakpoint(target, this)); |
+ }, |
+ |
+ /** |
+ * @param {!WebInspector.Target} target |
+ */ |
+ targetRemoved: function(target) |
+ { |
+ var targetBreakpoint = this._targetBreakpoints.remove(target); |
+ targetBreakpoint._resetLocations(); |
+ }, |
+ |
+ /** |
* @return {string} |
*/ |
projectId: function() |
@@ -516,46 +500,37 @@ WebInspector.BreakpointManager.Breakpoint.prototype = { |
}, |
/** |
- * @param {!WebInspector.DebuggerModel.Location} location |
- * @return {boolean} |
+ * @param {?WebInspector.UILocation} oldUILocation |
+ * @param {!WebInspector.UILocation} newUILocation |
*/ |
- _addResolvedLocation: function(location) |
+ _replaceUILocation: function(oldUILocation, newUILocation) |
{ |
- var script = location.script(); |
- var uiLocation = script.rawLocationToUILocation(location.lineNumber, location.columnNumber); |
- var breakpoint = this._breakpointManager.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber); |
- if (breakpoint && breakpoint != this) { |
- // location clash |
- this.remove(); |
- return false; |
- } |
- this._liveLocations.push(location.createLiveLocation(this._locationUpdated.bind(this, location))); |
- return true; |
+ if (this._isRemoved) |
+ return; |
+ |
+ this._removeUILocation(oldUILocation, true); |
+ this._removeFakeBreakpointAtPrimaryLocation(); |
+ |
+ if (!this._numberOfDebuggerLocationForUILocation[newUILocation.id()]) |
+ this._numberOfDebuggerLocationForUILocation[newUILocation.id()] = 0; |
+ |
+ if (++this._numberOfDebuggerLocationForUILocation[newUILocation.id()] === 1) |
+ this._breakpointManager._uiLocationAdded(this, newUILocation); |
}, |
/** |
- * @param {!WebInspector.DebuggerModel.Location} location |
- * @param {!WebInspector.UILocation} uiLocation |
+ * @param {?WebInspector.UILocation} uiLocation |
+ * @param {boolean=} muteCreationFakeBreakpoint |
*/ |
- _locationUpdated: function(location, uiLocation) |
+ _removeUILocation: function(uiLocation, muteCreationFakeBreakpoint) |
{ |
- var oldUILocation = /** @type {!WebInspector.UILocation} */ (this._uiLocations[location.id()]); |
- if (oldUILocation && --this._numberOfDebuggerLocationForUILocation[oldUILocation.id()] === 0) { |
- delete this._numberOfDebuggerLocationForUILocation[oldUILocation.id()]; |
- this._breakpointManager._uiLocationRemoved(this, oldUILocation); |
- } |
- if (this._uiLocations[""]) { |
- var defaultLocation = this._uiLocations[""]; |
- delete this._uiLocations[""]; |
- this._breakpointManager._uiLocationRemoved(this, defaultLocation); |
- } |
- this._uiLocations[location.id()] = uiLocation; |
- |
- if (!this._numberOfDebuggerLocationForUILocation[uiLocation.id()]) |
- this._numberOfDebuggerLocationForUILocation[uiLocation.id()] = 0; |
+ if (!uiLocation || --this._numberOfDebuggerLocationForUILocation[uiLocation.id()] !== 0) |
+ return; |
- if (++this._numberOfDebuggerLocationForUILocation[uiLocation.id()] === 1) |
- this._breakpointManager._uiLocationAdded(this, uiLocation); |
+ delete this._numberOfDebuggerLocationForUILocation[uiLocation.id()]; |
+ this._breakpointManager._uiLocationRemoved(this, uiLocation); |
+ if (!muteCreationFakeBreakpoint) |
+ this._fakeBreakpointAtPrimaryLocation(); |
}, |
/** |
@@ -571,7 +546,7 @@ WebInspector.BreakpointManager.Breakpoint.prototype = { |
*/ |
setEnabled: function(enabled) |
{ |
- this._updateBreakpoint(this._condition, enabled); |
+ this._updateState(this._condition, enabled); |
}, |
/** |
@@ -587,20 +562,27 @@ WebInspector.BreakpointManager.Breakpoint.prototype = { |
*/ |
setCondition: function(condition) |
{ |
- this._updateBreakpoint(condition, this._enabled); |
+ this._updateState(condition, this._enabled); |
}, |
/** |
* @param {string} condition |
* @param {boolean} enabled |
*/ |
- _updateBreakpoint: function(condition, enabled) |
+ _updateState: function(condition, enabled) |
{ |
if (this._enabled === enabled && this._condition === condition) |
return; |
this._enabled = enabled; |
this._condition = condition; |
this._breakpointManager._storage._updateBreakpoint(this); |
+ this._updateBreakpoint(); |
+ }, |
+ |
+ _updateBreakpoint: function() |
+ { |
+ this._removeFakeBreakpointAtPrimaryLocation(); |
+ this._fakeBreakpointAtPrimaryLocation(); |
this._updateInDebugger(); |
}, |
@@ -609,106 +591,199 @@ WebInspector.BreakpointManager.Breakpoint.prototype = { |
*/ |
remove: function(keepInStorage) |
{ |
+ this._isRemoved = true; |
var removeFromStorage = !keepInStorage; |
- this._removeFromDebugger(); |
+ this._removeFakeBreakpointAtPrimaryLocation(); |
+ var targets = this._targetBreakpoints.keys(); |
+ for (var i = 0; i < targets.length; ++i) |
+ this._targetBreakpoints.get(targets[i])._dispose(); |
+ |
this._breakpointManager._removeBreakpoint(this, removeFromStorage); |
+ this._breakpointManager._targetManager.unobserveTargets(this); |
}, |
_updateInDebugger: function() |
{ |
- this._removeFromDebugger(); |
- this._fakeBreakpointAtPrimaryLocation(); |
- var uiSourceCode = this.uiSourceCode(); |
- if (!uiSourceCode || !this._enabled) |
+ var targetBreakpoints = this._targetBreakpoints.values(); |
+ for (var i = 0; i < targetBreakpoints.length; ++i) |
+ targetBreakpoints[i]._updateInDebugger(); |
+ }, |
+ |
+ /** |
+ * @return {string} |
+ */ |
+ _breakpointStorageId: function() |
+ { |
+ return WebInspector.BreakpointManager._breakpointStorageId(this._sourceFileId, this._lineNumber, this._columnNumber); |
+ }, |
+ |
+ _fakeBreakpointAtPrimaryLocation: function() |
+ { |
+ if (this._isRemoved || !Object.isEmpty(this._numberOfDebuggerLocationForUILocation) || this._fakeBreakpointPrimaryLocation) |
return; |
- var targets = this._breakpointManager._targetManager.targets(); |
- for (var i = 0; i < targets.length; ++i) { |
- var scriptFile = uiSourceCode.scriptFileForTarget(targets[i]); |
- if (scriptFile && scriptFile.hasDivergedFromVM()) |
- return; |
- } |
+ var uiSourceCode = this._breakpointManager._workspace.uiSourceCode(this._projectId, this._path); |
+ if (!uiSourceCode) |
+ return; |
- for (var i = 0; i < targets.length; ++i) { |
- var rawLocation = uiSourceCode.uiLocationToRawLocation(targets[i], this._lineNumber, this._columnNumber); |
- var debuggerModelLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (rawLocation); |
- if (debuggerModelLocation) |
- targets[i].debuggerModel.setBreakpointByScriptLocation(debuggerModelLocation, this._condition, this._didSetBreakpointInDebugger.bind(this)); |
- else if (uiSourceCode.url) |
- targets[i].debuggerModel.setBreakpointByURL(uiSourceCode.url, this._lineNumber, this._columnNumber, this._condition, this._didSetBreakpointInDebugger.bind(this)); |
+ this._fakeBreakpointPrimaryLocation = uiSourceCode.uiLocation(this._lineNumber, this._columnNumber); |
+ this._breakpointManager._uiLocationAdded(this, this._fakeBreakpointPrimaryLocation); |
+ }, |
+ |
+ _removeFakeBreakpointAtPrimaryLocation: function() |
+ { |
+ if (this._fakeBreakpointPrimaryLocation) { |
+ this._breakpointManager._uiLocationRemoved(this, this._fakeBreakpointPrimaryLocation); |
+ delete this._fakeBreakpointPrimaryLocation; |
} |
}, |
+ _resetLocations: function() |
+ { |
+ this._removeFakeBreakpointAtPrimaryLocation(); |
+ var targetBreakpoints = this._targetBreakpoints.values(); |
+ for (var i = 0; i < targetBreakpoints.length; ++i) |
+ targetBreakpoints[i]._resetLocations(); |
+ } |
+} |
+ |
+/** |
+ * @constructor |
+ * @extends {WebInspector.TargetAware} |
+ * @param {!WebInspector.Target} target |
+ * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint |
+ */ |
+WebInspector.BreakpointManager.TargetBreakpoint = function(target, breakpoint) |
+{ |
+ WebInspector.TargetAware.call(this, target); |
+ this._breakpoint = breakpoint; |
+ /** @type {!Array.<!WebInspector.Script.Location>} */ |
+ this._liveLocations = []; |
+ |
+ /** @type {!Object.<string, !WebInspector.UILocation>} */ |
+ this._uiLocations = {}; |
+ target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointResolved, this._breakpointResolved, this); |
+} |
+ |
+WebInspector.BreakpointManager.TargetBreakpoint.prototype = { |
+ |
+ _resetLocations: function() |
+ { |
+ var uiLocations = Object.values(this._uiLocations); |
+ for (var i = 0; i < uiLocations.length; ++i) |
+ this._breakpoint._removeUILocation(uiLocations[i]); |
+ |
+ this._uiLocations = {}; |
+ |
+ for (var i = 0; i < this._liveLocations.length; ++i) |
+ this._liveLocations[i].dispose(); |
+ this._liveLocations = []; |
+ }, |
+ |
+ /** |
+ * @param {boolean=} muteCallback |
+ */ |
+ _removeFromDebugger: function(muteCallback) |
+ { |
+ this._resetLocations(); |
+ if (!this._debuggerId) |
+ return; |
+ this.target().debuggerModel.removeBreakpoint(this._debuggerId, muteCallback ? undefined : this._didRemoveFromDebugger.bind(this)); |
+ }, |
+ |
+ _updateInDebugger: function() |
+ { |
+ this._removeFromDebugger(); |
+ var uiSourceCode = this._breakpoint.uiSourceCode(); |
+ if (!uiSourceCode || !this._breakpoint._enabled) |
+ return; |
+ var scriptFile = uiSourceCode.scriptFileForTarget(this._target); |
+ if (scriptFile && scriptFile.hasDivergedFromVM()) |
+ return; |
+ |
+ var lineNumber = this._breakpoint._lineNumber; |
+ var columnNumber = this._breakpoint._columnNumber; |
+ var rawLocation = uiSourceCode.uiLocationToRawLocation(this._target, lineNumber, columnNumber); |
+ var debuggerModelLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (rawLocation); |
+ var condition = this._breakpoint.condition(); |
+ if (debuggerModelLocation) |
+ this.target().debuggerModel.setBreakpointByScriptLocation(debuggerModelLocation, condition, this._didSetBreakpointInDebugger.bind(this)); |
+ else if (uiSourceCode.url) |
+ this.target().debuggerModel.setBreakpointByURL(uiSourceCode.url, lineNumber, columnNumber, condition, this._didSetBreakpointInDebugger.bind(this)); |
+ }, |
+ |
/** |
- * @param {?DebuggerAgent.BreakpointId} breakpointId |
- * @param {!Array.<!WebInspector.DebuggerModel.Location>} locations |
- */ |
+ * @param {?DebuggerAgent.BreakpointId} breakpointId |
+ * @param {!Array.<!WebInspector.DebuggerModel.Location>} locations |
+ */ |
_didSetBreakpointInDebugger: function(breakpointId, locations) |
{ |
if (!breakpointId) { |
- this.remove(true); |
+ this._breakpoint.remove(true); |
return; |
} |
- this._debuggerId = breakpointId; |
- this._breakpointManager._breakpointForDebuggerId[breakpointId] = this; |
+ if (this._debuggerId) |
+ this._removeFromDebugger(true); |
+ this._debuggerId = breakpointId; |
for (var i = 0; i < locations.length; ++i) |
if (!this._addResolvedLocation(locations[i])) |
return; |
}, |
- _removeFromDebugger: function() |
+ _didRemoveFromDebugger: function() |
{ |
- this._resetLocations(); |
- if (!this._debuggerId) |
- return; |
- var barrier = new CallbackBarrier(); |
- this._breakpointManager._targetManager.targets().forEach(function(target){target.debuggerModel.removeBreakpoint(this._debuggerId, barrier.createCallback())}, this); |
- barrier.callWhenDone(this._didRemoveFromDebugger.bind(this)); |
+ delete this._debuggerId; |
}, |
- _didRemoveFromDebugger: function() |
+ /** |
+ * @param {!WebInspector.Event} event |
+ */ |
+ _breakpointResolved: function(event) |
{ |
- delete this._breakpointManager._breakpointForDebuggerId[this._debuggerId]; |
- delete this._debuggerId; |
+ var breakpointId = /** @type {!DebuggerAgent.BreakpointId} */ (event.data.breakpointId); |
+ var location = /** @type {!WebInspector.DebuggerModel.Location} */ (event.data.location); |
+ if (this._debuggerId === breakpointId) |
+ this._addResolvedLocation(location); |
}, |
- _resetLocations: function() |
+ /** |
+ * @param {!WebInspector.DebuggerModel.Location} location |
+ * @param {!WebInspector.UILocation} uiLocation |
+ */ |
+ _locationUpdated: function(location, uiLocation) |
{ |
- for (var stringifiedLocation in this._uiLocations) { |
- var uiLocation = this._uiLocations[stringifiedLocation]; |
- if (this._numberOfDebuggerLocationForUILocation[uiLocation.id()]) { |
- this._breakpointManager._uiLocationRemoved(this, uiLocation); |
- delete this._numberOfDebuggerLocationForUILocation[uiLocation.id()]; |
- } |
- } |
- if (this._uiLocations[""]) |
- this._breakpointManager._uiLocationRemoved(this, this._uiLocations[""]); |
- for (var i = 0; i < this._liveLocations.length; ++i) |
- this._liveLocations[i].dispose(); |
- this._liveLocations = []; |
- this._uiLocations = {}; |
- this._numberOfDebuggerLocationForUILocation = {}; |
+ var oldUILocation = this._uiLocations[location.id()] || null; |
+ this._uiLocations[location.id()] = uiLocation; |
+ this._breakpoint._replaceUILocation(oldUILocation, uiLocation); |
}, |
/** |
- * @return {string} |
+ * @param {!WebInspector.DebuggerModel.Location} location |
+ * @return {boolean} |
*/ |
- _breakpointStorageId: function() |
+ _addResolvedLocation: function(location) |
{ |
- return WebInspector.BreakpointManager._breakpointStorageId(this._sourceFileId, this._lineNumber, this._columnNumber); |
+ var script = location.script(); |
+ var uiLocation = script.rawLocationToUILocation(location.lineNumber, location.columnNumber); |
+ var breakpoint = this._breakpoint._breakpointManager.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber); |
+ if (breakpoint && breakpoint != this._breakpoint) { |
+ // location clash |
+ this._breakpoint.remove(); |
+ return false; |
+ } |
+ this._liveLocations.push(location.createLiveLocation(this._locationUpdated.bind(this, location))); |
+ return true; |
}, |
- _fakeBreakpointAtPrimaryLocation: function() |
+ _dispose: function() |
{ |
- var uiSourceCode = this._breakpointManager._workspace.uiSourceCode(this._projectId, this._path); |
- if (!uiSourceCode) |
- return; |
- var uiLocation = uiSourceCode.uiLocation(this._lineNumber, this._columnNumber); |
- this._uiLocations[""] = uiLocation; |
- this._breakpointManager._uiLocationAdded(this, uiLocation); |
- } |
+ this.target().debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.BreakpointResolved, this._breakpointResolved, this); |
+ this._removeFromDebugger(); |
+ }, |
+ |
+ __proto__: WebInspector.TargetAware.prototype |
} |
/** |