Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(626)

Side by Side Diff: Source/devtools/front_end/sdk/BreakpointManager.js

Issue 310463003: DevTools: introduce TargetBreakpoints as a presentation of breakpoint and its state within target (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Address vsevik's comments Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 13 matching lines...) Expand all
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 /** 31 /**
32 * @constructor 32 * @constructor
33 * @extends {WebInspector.Object} 33 * @extends {WebInspector.Object}
34 * @implements {WebInspector.TargetManager.Observer}
35 * @param {!WebInspector.Setting} breakpointStorage 34 * @param {!WebInspector.Setting} breakpointStorage
36 * @param {!WebInspector.Workspace} workspace 35 * @param {!WebInspector.Workspace} workspace
37 * @param {!WebInspector.TargetManager} targetManager 36 * @param {!WebInspector.TargetManager} targetManager
38 */ 37 */
39 WebInspector.BreakpointManager = function(breakpointStorage, workspace, targetMa nager) 38 WebInspector.BreakpointManager = function(breakpointStorage, workspace, targetMa nager)
40 { 39 {
41 this._storage = new WebInspector.BreakpointManager.Storage(this, breakpointS torage); 40 this._storage = new WebInspector.BreakpointManager.Storage(this, breakpointS torage);
42 this._workspace = workspace; 41 this._workspace = workspace;
43 this._targetManager = targetManager; 42 this._targetManager = targetManager;
44 43
45 this._breakpointForDebuggerId = {};
46 this._breakpointsForUISourceCode = new Map(); 44 this._breakpointsForUISourceCode = new Map();
47 this._breakpointsForPrimaryUISourceCode = new Map(); 45 this._breakpointsForPrimaryUISourceCode = new Map();
48 /** @type {!StringMultimap.<!WebInspector.BreakpointManager.Breakpoint>} */ 46 /** @type {!StringMultimap.<!WebInspector.BreakpointManager.Breakpoint>} */
49 this._provisionalBreakpoints = new StringMultimap(); 47 this._provisionalBreakpoints = new StringMultimap();
50 48
51 this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemove d, this._projectRemoved, this); 49 this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemove d, this._projectRemoved, this);
52 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeA dded, this._uiSourceCodeAdded, this); 50 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeA dded, this._uiSourceCodeAdded, this);
53 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeR emoved, this._uiSourceCodeRemoved, this); 51 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeR emoved, this._uiSourceCodeRemoved, this);
54 this._targetManager.observeTargets(this);
55 } 52 }
56 53
57 WebInspector.BreakpointManager.Events = { 54 WebInspector.BreakpointManager.Events = {
58 BreakpointAdded: "breakpoint-added", 55 BreakpointAdded: "breakpoint-added",
59 BreakpointRemoved: "breakpoint-removed" 56 BreakpointRemoved: "breakpoint-removed"
60 } 57 }
61 58
62 WebInspector.BreakpointManager._sourceFileId = function(uiSourceCode) 59 WebInspector.BreakpointManager._sourceFileId = function(uiSourceCode)
63 { 60 {
64 if (!uiSourceCode.url) 61 if (!uiSourceCode.url)
65 return ""; 62 return "";
66 return uiSourceCode.uri(); 63 return uiSourceCode.uri();
67 } 64 }
68 65
69 /** 66 /**
70 * @param {string} sourceFileId 67 * @param {string} sourceFileId
71 * @param {number} lineNumber 68 * @param {number} lineNumber
72 * @param {number} columnNumber 69 * @param {number} columnNumber
73 * @return {string} 70 * @return {string}
74 */ 71 */
75 WebInspector.BreakpointManager._breakpointStorageId = function(sourceFileId, lin eNumber, columnNumber) 72 WebInspector.BreakpointManager._breakpointStorageId = function(sourceFileId, lin eNumber, columnNumber)
76 { 73 {
77 if (!sourceFileId) 74 if (!sourceFileId)
78 return ""; 75 return "";
79 return sourceFileId + ":" + lineNumber + ":" + columnNumber; 76 return sourceFileId + ":" + lineNumber + ":" + columnNumber;
80 } 77 }
81 78
82 WebInspector.BreakpointManager.prototype = { 79 WebInspector.BreakpointManager.prototype = {
83 /**
84 * @param {!WebInspector.Target} target
85 */
86 targetAdded: function(target)
87 {
88 target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events. BreakpointResolved, this._breakpointResolved, this);
89 },
90
91 /**
92 * @param {!WebInspector.Target} target
93 */
94 targetRemoved: function(target)
95 {
96 target.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Even ts.BreakpointResolved, this._breakpointResolved, this);
97 },
98 80
99 /** 81 /**
100 * @param {string} sourceFileId 82 * @param {string} sourceFileId
101 * @return {!StringMap.<!WebInspector.BreakpointManager.Breakpoint>} 83 * @return {!StringMap.<!WebInspector.BreakpointManager.Breakpoint>}
102 */ 84 */
103 _provisionalBreakpointsForSourceFileId: function(sourceFileId) 85 _provisionalBreakpointsForSourceFileId: function(sourceFileId)
104 { 86 {
105 var result = new StringMap(); 87 var result = new StringMap();
106 var breakpoints = this._provisionalBreakpoints.get(sourceFileId).values( ); 88 var breakpoints = this._provisionalBreakpoints.get(sourceFileId).values( );
107 for (var i = 0; i < breakpoints.length; ++i) 89 for (var i = 0; i < breakpoints.length; ++i)
108 result.put(breakpoints[i]._breakpointStorageId(), breakpoints[i]); 90 result.put(breakpoints[i]._breakpointStorageId(), breakpoints[i]);
109 return result; 91 return result;
110 }, 92 },
111 93
112 /** 94 removeProvisionalBreakpointsForTest: function()
113 * @param {!WebInspector.Target} target
114 */
115 removeProvisionalBreakpointsForTest: function(target)
116 { 95 {
117 var breakpoints = this._provisionalBreakpoints.values(); 96 var breakpoints = this._provisionalBreakpoints.values();
118 for (var i = 0; i < breakpoints.length; ++i) { 97 for (var i = 0; i < breakpoints.length; ++i)
119 var debuggerId = breakpoints[i]._debuggerId; 98 breakpoints[i].remove();
120 if (debuggerId)
121 target.debuggerModel.removeBreakpoint(debuggerId);
122 }
123 this._provisionalBreakpoints.clear(); 99 this._provisionalBreakpoints.clear();
124 }, 100 },
125 101
126 /** 102 /**
127 * @param {!WebInspector.UISourceCode} uiSourceCode 103 * @param {!WebInspector.UISourceCode} uiSourceCode
128 */ 104 */
129 _restoreBreakpoints: function(uiSourceCode) 105 _restoreBreakpoints: function(uiSourceCode)
130 { 106 {
131 var sourceFileId = WebInspector.BreakpointManager._sourceFileId(uiSource Code); 107 var sourceFileId = WebInspector.BreakpointManager._sourceFileId(uiSource Code);
132 if (!sourceFileId) 108 if (!sourceFileId)
133 return; 109 return;
134 110
135 this._storage.mute(); 111 this._storage.mute();
136 var breakpointItems = this._storage.breakpointItems(uiSourceCode); 112 var breakpointItems = this._storage.breakpointItems(uiSourceCode);
137 var provisionalBreakpoints = this._provisionalBreakpointsForSourceFileId (sourceFileId); 113 var provisionalBreakpoints = this._provisionalBreakpointsForSourceFileId (sourceFileId);
138 for (var i = 0; i < breakpointItems.length; ++i) { 114 for (var i = 0; i < breakpointItems.length; ++i) {
139 var breakpointItem = breakpointItems[i]; 115 var breakpointItem = breakpointItems[i];
140 var itemStorageId = WebInspector.BreakpointManager._breakpointStorag eId(breakpointItem.sourceFileId, breakpointItem.lineNumber, breakpointItem.colum nNumber); 116 var itemStorageId = WebInspector.BreakpointManager._breakpointStorag eId(breakpointItem.sourceFileId, breakpointItem.lineNumber, breakpointItem.colum nNumber);
141 var provisionalBreakpoint = provisionalBreakpoints.get(itemStorageId ); 117 var provisionalBreakpoint = provisionalBreakpoints.get(itemStorageId );
142 if (provisionalBreakpoint) { 118 if (provisionalBreakpoint) {
143 if (!this._breakpointsForPrimaryUISourceCode.get(uiSourceCode)) 119 if (!this._breakpointsForPrimaryUISourceCode.get(uiSourceCode))
144 this._breakpointsForPrimaryUISourceCode.put(uiSourceCode, [] ); 120 this._breakpointsForPrimaryUISourceCode.put(uiSourceCode, [] );
145 this._breakpointsForPrimaryUISourceCode.get(uiSourceCode).push(p rovisionalBreakpoint); 121 this._breakpointsForPrimaryUISourceCode.get(uiSourceCode).push(p rovisionalBreakpoint);
146 provisionalBreakpoint._updateInDebugger(); 122 provisionalBreakpoint._updateBreakpoint();
147 } else { 123 } else {
148 this._innerSetBreakpoint(uiSourceCode, breakpointItem.lineNumber , breakpointItem.columnNumber, breakpointItem.condition, breakpointItem.enabled) ; 124 this._innerSetBreakpoint(uiSourceCode, breakpointItem.lineNumber , breakpointItem.columnNumber, breakpointItem.condition, breakpointItem.enabled) ;
149 } 125 }
150 } 126 }
151 this._provisionalBreakpoints.removeAll(sourceFileId); 127 this._provisionalBreakpoints.removeAll(sourceFileId);
152 this._storage.unmute(); 128 this._storage.unmute();
153 }, 129 },
154 130
155 /** 131 /**
156 * @param {!WebInspector.Event} event 132 * @param {!WebInspector.Event} event
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 * @param {number} lineNumber 199 * @param {number} lineNumber
224 * @param {number} columnNumber 200 * @param {number} columnNumber
225 * @param {string} condition 201 * @param {string} condition
226 * @param {boolean} enabled 202 * @param {boolean} enabled
227 * @return {!WebInspector.BreakpointManager.Breakpoint} 203 * @return {!WebInspector.BreakpointManager.Breakpoint}
228 */ 204 */
229 _innerSetBreakpoint: function(uiSourceCode, lineNumber, columnNumber, condit ion, enabled) 205 _innerSetBreakpoint: function(uiSourceCode, lineNumber, columnNumber, condit ion, enabled)
230 { 206 {
231 var breakpoint = this.findBreakpoint(uiSourceCode, lineNumber, columnNum ber); 207 var breakpoint = this.findBreakpoint(uiSourceCode, lineNumber, columnNum ber);
232 if (breakpoint) { 208 if (breakpoint) {
233 breakpoint._updateBreakpoint(condition, enabled); 209 breakpoint._updateState(condition, enabled);
234 return breakpoint; 210 return breakpoint;
235 } 211 }
236 var projectId = uiSourceCode.project().id(); 212 var projectId = uiSourceCode.project().id();
237 var path = uiSourceCode.path(); 213 var path = uiSourceCode.path();
238 var sourceFileId = WebInspector.BreakpointManager._sourceFileId(uiSource Code); 214 var sourceFileId = WebInspector.BreakpointManager._sourceFileId(uiSource Code);
239 breakpoint = new WebInspector.BreakpointManager.Breakpoint(this, project Id, path, sourceFileId, lineNumber, columnNumber, condition, enabled); 215 breakpoint = new WebInspector.BreakpointManager.Breakpoint(this, project Id, path, sourceFileId, lineNumber, columnNumber, condition, enabled);
240 if (!this._breakpointsForPrimaryUISourceCode.get(uiSourceCode)) 216 if (!this._breakpointsForPrimaryUISourceCode.get(uiSourceCode))
241 this._breakpointsForPrimaryUISourceCode.put(uiSourceCode, []); 217 this._breakpointsForPrimaryUISourceCode.put(uiSourceCode, []);
242 this._breakpointsForPrimaryUISourceCode.get(uiSourceCode).push(breakpoin t); 218 this._breakpointsForPrimaryUISourceCode.get(uiSourceCode).push(breakpoin t);
243 return breakpoint; 219 return breakpoint;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 }, 330 },
355 331
356 _projectRemoved: function(event) 332 _projectRemoved: function(event)
357 { 333 {
358 var project = /** @type {!WebInspector.Project} */ (event.data); 334 var project = /** @type {!WebInspector.Project} */ (event.data);
359 var uiSourceCodes = project.uiSourceCodes(); 335 var uiSourceCodes = project.uiSourceCodes();
360 for (var i = 0; i < uiSourceCodes.length; ++i) 336 for (var i = 0; i < uiSourceCodes.length; ++i)
361 this._removeUISourceCode(uiSourceCodes[i]); 337 this._removeUISourceCode(uiSourceCodes[i]);
362 }, 338 },
363 339
364 _breakpointResolved: function(event)
365 {
366 var breakpointId = /** @type {!DebuggerAgent.BreakpointId} */ (event.dat a.breakpointId);
367 var location = /** @type {!WebInspector.DebuggerModel.Location} */ (even t.data.location);
368 var breakpoint = this._breakpointForDebuggerId[breakpointId];
369 if (!breakpoint)
370 return;
371 breakpoint._addResolvedLocation(location);
372 },
373
374 /** 340 /**
375 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint 341 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
376 * @param {boolean} removeFromStorage 342 * @param {boolean} removeFromStorage
377 */ 343 */
378 _removeBreakpoint: function(breakpoint, removeFromStorage) 344 _removeBreakpoint: function(breakpoint, removeFromStorage)
379 { 345 {
380 var uiSourceCode = breakpoint.uiSourceCode(); 346 var uiSourceCode = breakpoint.uiSourceCode();
381 var breakpoints = uiSourceCode ? this._breakpointsForPrimaryUISourceCode .get(uiSourceCode) || [] : []; 347 var breakpoints = uiSourceCode ? this._breakpointsForPrimaryUISourceCode .get(uiSourceCode) || [] : [];
382 var index = breakpoints.indexOf(breakpoint); 348 breakpoints.remove(breakpoint);
383 if (index > -1)
384 breakpoints.splice(index, 1);
385 if (removeFromStorage) 349 if (removeFromStorage)
386 this._storage._removeBreakpoint(breakpoint); 350 this._storage._removeBreakpoint(breakpoint);
387 this._provisionalBreakpoints.remove(breakpoint._sourceFileId, breakpoint ); 351 this._provisionalBreakpoints.remove(breakpoint._sourceFileId, breakpoint );
388 }, 352 },
389 353
390 /** 354 /**
391 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint 355 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
392 * @param {!WebInspector.UILocation} uiLocation 356 * @param {!WebInspector.UILocation} uiLocation
393 */ 357 */
394 _uiLocationAdded: function(breakpoint, uiLocation) 358 _uiLocationAdded: function(breakpoint, uiLocation)
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 if (!breakpoints.size()) 400 if (!breakpoints.size())
437 this._breakpointsForUISourceCode.remove(uiLocation.uiSourceCode); 401 this._breakpointsForUISourceCode.remove(uiLocation.uiSourceCode);
438 this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.Brea kpointRemoved, {breakpoint: breakpoint, uiLocation: uiLocation}); 402 this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.Brea kpointRemoved, {breakpoint: breakpoint, uiLocation: uiLocation});
439 }, 403 },
440 404
441 __proto__: WebInspector.Object.prototype 405 __proto__: WebInspector.Object.prototype
442 } 406 }
443 407
444 /** 408 /**
445 * @constructor 409 * @constructor
410 * @implements {WebInspector.TargetManager.Observer}
446 * @param {!WebInspector.BreakpointManager} breakpointManager 411 * @param {!WebInspector.BreakpointManager} breakpointManager
447 * @param {string} projectId 412 * @param {string} projectId
448 * @param {string} path 413 * @param {string} path
449 * @param {string} sourceFileId 414 * @param {string} sourceFileId
450 * @param {number} lineNumber 415 * @param {number} lineNumber
451 * @param {number} columnNumber 416 * @param {number} columnNumber
452 * @param {string} condition 417 * @param {string} condition
453 * @param {boolean} enabled 418 * @param {boolean} enabled
454 */ 419 */
455 WebInspector.BreakpointManager.Breakpoint = function(breakpointManager, projectI d, path, sourceFileId, lineNumber, columnNumber, condition, enabled) 420 WebInspector.BreakpointManager.Breakpoint = function(breakpointManager, projectI d, path, sourceFileId, lineNumber, columnNumber, condition, enabled)
456 { 421 {
457 this._breakpointManager = breakpointManager; 422 this._breakpointManager = breakpointManager;
458 this._projectId = projectId; 423 this._projectId = projectId;
459 this._path = path; 424 this._path = path;
460 this._lineNumber = lineNumber; 425 this._lineNumber = lineNumber;
461 this._columnNumber = columnNumber; 426 this._columnNumber = columnNumber;
462 this._sourceFileId = sourceFileId; 427 this._sourceFileId = sourceFileId;
463 /** @type {!Array.<!WebInspector.Script.Location>} */
464 this._liveLocations = [];
465 /** @type {!Object.<string, !WebInspector.UILocation>} */
466 this._uiLocations = {};
467 428
468 /** @type {!Object.<string, number>} */ 429 /** @type {!Object.<string, number>} */
469 this._numberOfDebuggerLocationForUILocation = new Map(); 430 this._numberOfDebuggerLocationForUILocation = {};
470 431
471 // Force breakpoint update. 432 // Force breakpoint update.
472 /** @type {string} */ this._condition; 433 /** @type {string} */ this._condition;
473 /** @type {boolean} */ this._enabled; 434 /** @type {boolean} */ this._enabled;
474 this._updateBreakpoint(condition, enabled); 435 /** @type {boolean} */ this._isRemoved;
436 /** @type {!WebInspector.UILocation|undefined} */ this._fakeBreakpointPrimar yLocation;
vsevik 2014/06/05 13:19:10 nit: this._fakePrimaryLocation
sergeyv 2014/06/05 13:25:54 Done.
437
438 /** @type {!Map.<!WebInspector.Target, !WebInspector.BreakpointManager.Targe tBreakpoint>}*/
439 this._targetBreakpoints = new Map();
440 this._breakpointManager._targetManager.observeTargets(this);
441 this._updateState(condition, enabled);
475 } 442 }
476 443
477 WebInspector.BreakpointManager.Breakpoint.prototype = { 444 WebInspector.BreakpointManager.Breakpoint.prototype = {
478 /** 445 /**
446 * @param {!WebInspector.Target} target
447 */
448 targetAdded: function(target)
449 {
450 this._targetBreakpoints.put(target, new WebInspector.BreakpointManager.T argetBreakpoint(target, this));
451 },
452
453 /**
454 * @param {!WebInspector.Target} target
455 */
456 targetRemoved: function(target)
457 {
458 var targetBreakpoint = this._targetBreakpoints.remove(target);
459 targetBreakpoint._resetLocations();
460 },
461
462 /**
479 * @return {string} 463 * @return {string}
480 */ 464 */
481 projectId: function() 465 projectId: function()
482 { 466 {
483 return this._projectId; 467 return this._projectId;
484 }, 468 },
485 469
486 /** 470 /**
487 * @return {string} 471 * @return {string}
488 */ 472 */
(...skipping 20 matching lines...) Expand all
509 493
510 /** 494 /**
511 * @return {?WebInspector.UISourceCode} 495 * @return {?WebInspector.UISourceCode}
512 */ 496 */
513 uiSourceCode: function() 497 uiSourceCode: function()
514 { 498 {
515 return this._breakpointManager._workspace.uiSourceCode(this._projectId, this._path); 499 return this._breakpointManager._workspace.uiSourceCode(this._projectId, this._path);
516 }, 500 },
517 501
518 /** 502 /**
519 * @param {!WebInspector.DebuggerModel.Location} location 503 * @param {?WebInspector.UILocation} oldUILocation
520 * @return {boolean} 504 * @param {!WebInspector.UILocation} newUILocation
521 */ 505 */
522 _addResolvedLocation: function(location) 506 _replaceUILocation: function(oldUILocation, newUILocation)
523 { 507 {
524 var script = location.script(); 508 if (this._isRemoved)
525 var uiLocation = script.rawLocationToUILocation(location.lineNumber, loc ation.columnNumber); 509 return;
526 var breakpoint = this._breakpointManager.findBreakpoint(uiLocation.uiSou rceCode, uiLocation.lineNumber, uiLocation.columnNumber); 510
527 if (breakpoint && breakpoint != this) { 511 this._removeUILocation(oldUILocation, true);
528 // location clash 512 this._removeFakeBreakpointAtPrimaryLocation();
529 this.remove(); 513
530 return false; 514 if (!this._numberOfDebuggerLocationForUILocation[newUILocation.id()])
531 } 515 this._numberOfDebuggerLocationForUILocation[newUILocation.id()] = 0;
532 this._liveLocations.push(location.createLiveLocation(this._locationUpdat ed.bind(this, location))); 516
533 return true; 517 if (++this._numberOfDebuggerLocationForUILocation[newUILocation.id()] == = 1)
518 this._breakpointManager._uiLocationAdded(this, newUILocation);
534 }, 519 },
535 520
536 /** 521 /**
537 * @param {!WebInspector.DebuggerModel.Location} location 522 * @param {?WebInspector.UILocation} uiLocation
538 * @param {!WebInspector.UILocation} uiLocation 523 * @param {boolean=} muteCreationFakeBreakpoint
539 */ 524 */
540 _locationUpdated: function(location, uiLocation) 525 _removeUILocation: function(uiLocation, muteCreationFakeBreakpoint)
541 { 526 {
542 var oldUILocation = /** @type {!WebInspector.UILocation} */ (this._uiLoc ations[location.id()]); 527 if (!uiLocation || --this._numberOfDebuggerLocationForUILocation[uiLocat ion.id()] !== 0)
543 if (oldUILocation && --this._numberOfDebuggerLocationForUILocation[oldUI Location.id()] === 0) { 528 return;
544 delete this._numberOfDebuggerLocationForUILocation[oldUILocation.id( )];
545 this._breakpointManager._uiLocationRemoved(this, oldUILocation);
546 }
547 if (this._uiLocations[""]) {
548 var defaultLocation = this._uiLocations[""];
549 delete this._uiLocations[""];
550 this._breakpointManager._uiLocationRemoved(this, defaultLocation);
551 }
552 this._uiLocations[location.id()] = uiLocation;
553 529
554 if (!this._numberOfDebuggerLocationForUILocation[uiLocation.id()]) 530 delete this._numberOfDebuggerLocationForUILocation[uiLocation.id()];
555 this._numberOfDebuggerLocationForUILocation[uiLocation.id()] = 0; 531 this._breakpointManager._uiLocationRemoved(this, uiLocation);
556 532 if (!muteCreationFakeBreakpoint)
557 if (++this._numberOfDebuggerLocationForUILocation[uiLocation.id()] === 1 ) 533 this._fakeBreakpointAtPrimaryLocation();
558 this._breakpointManager._uiLocationAdded(this, uiLocation);
559 }, 534 },
560 535
561 /** 536 /**
562 * @return {boolean} 537 * @return {boolean}
563 */ 538 */
564 enabled: function() 539 enabled: function()
565 { 540 {
566 return this._enabled; 541 return this._enabled;
567 }, 542 },
568 543
569 /** 544 /**
570 * @param {boolean} enabled 545 * @param {boolean} enabled
571 */ 546 */
572 setEnabled: function(enabled) 547 setEnabled: function(enabled)
573 { 548 {
574 this._updateBreakpoint(this._condition, enabled); 549 this._updateState(this._condition, enabled);
575 }, 550 },
576 551
577 /** 552 /**
578 * @return {string} 553 * @return {string}
579 */ 554 */
580 condition: function() 555 condition: function()
581 { 556 {
582 return this._condition; 557 return this._condition;
583 }, 558 },
584 559
585 /** 560 /**
586 * @param {string} condition 561 * @param {string} condition
587 */ 562 */
588 setCondition: function(condition) 563 setCondition: function(condition)
589 { 564 {
590 this._updateBreakpoint(condition, this._enabled); 565 this._updateState(condition, this._enabled);
591 }, 566 },
592 567
593 /** 568 /**
594 * @param {string} condition 569 * @param {string} condition
595 * @param {boolean} enabled 570 * @param {boolean} enabled
596 */ 571 */
597 _updateBreakpoint: function(condition, enabled) 572 _updateState: function(condition, enabled)
598 { 573 {
599 if (this._enabled === enabled && this._condition === condition) 574 if (this._enabled === enabled && this._condition === condition)
600 return; 575 return;
601 this._enabled = enabled; 576 this._enabled = enabled;
602 this._condition = condition; 577 this._condition = condition;
603 this._breakpointManager._storage._updateBreakpoint(this); 578 this._breakpointManager._storage._updateBreakpoint(this);
579 this._updateBreakpoint();
580 },
581
582 _updateBreakpoint: function()
583 {
584 this._removeFakeBreakpointAtPrimaryLocation();
585 this._fakeBreakpointAtPrimaryLocation();
604 this._updateInDebugger(); 586 this._updateInDebugger();
605 }, 587 },
606 588
607 /** 589 /**
608 * @param {boolean=} keepInStorage 590 * @param {boolean=} keepInStorage
609 */ 591 */
610 remove: function(keepInStorage) 592 remove: function(keepInStorage)
611 { 593 {
594 this._isRemoved = true;
612 var removeFromStorage = !keepInStorage; 595 var removeFromStorage = !keepInStorage;
613 this._removeFromDebugger(); 596 this._removeFakeBreakpointAtPrimaryLocation();
597 var targets = this._targetBreakpoints.keys();
598 for (var i = 0; i < targets.length; ++i)
599 this._targetBreakpoints.get(targets[i])._dispose();
600
614 this._breakpointManager._removeBreakpoint(this, removeFromStorage); 601 this._breakpointManager._removeBreakpoint(this, removeFromStorage);
602 this._breakpointManager._targetManager.unobserveTargets(this);
615 }, 603 },
616 604
617 _updateInDebugger: function() 605 _updateInDebugger: function()
618 { 606 {
619 this._removeFromDebugger(); 607 var targetBreakpoints = this._targetBreakpoints.values();
620 this._fakeBreakpointAtPrimaryLocation(); 608 for (var i = 0; i < targetBreakpoints.length; ++i)
621 var uiSourceCode = this.uiSourceCode(); 609 targetBreakpoints[i]._updateInDebugger();
622 if (!uiSourceCode || !this._enabled)
623 return;
624
625 var targets = this._breakpointManager._targetManager.targets();
626 for (var i = 0; i < targets.length; ++i) {
627 var scriptFile = uiSourceCode.scriptFileForTarget(targets[i]);
628 if (scriptFile && scriptFile.hasDivergedFromVM())
629 return;
630 }
631
632 for (var i = 0; i < targets.length; ++i) {
633 var rawLocation = uiSourceCode.uiLocationToRawLocation(targets[i], t his._lineNumber, this._columnNumber);
634 var debuggerModelLocation = /** @type {!WebInspector.DebuggerModel.L ocation} */ (rawLocation);
635 if (debuggerModelLocation)
636 targets[i].debuggerModel.setBreakpointByScriptLocation(debuggerM odelLocation, this._condition, this._didSetBreakpointInDebugger.bind(this));
637 else if (uiSourceCode.url)
638 targets[i].debuggerModel.setBreakpointByURL(uiSourceCode.url, th is._lineNumber, this._columnNumber, this._condition, this._didSetBreakpointInDeb ugger.bind(this));
639 }
640 },
641
642 /**
643 * @param {?DebuggerAgent.BreakpointId} breakpointId
644 * @param {!Array.<!WebInspector.DebuggerModel.Location>} locations
645 */
646 _didSetBreakpointInDebugger: function(breakpointId, locations)
647 {
648 if (!breakpointId) {
649 this.remove(true);
650 return;
651 }
652
653 this._debuggerId = breakpointId;
654 this._breakpointManager._breakpointForDebuggerId[breakpointId] = this;
655
656 for (var i = 0; i < locations.length; ++i)
657 if (!this._addResolvedLocation(locations[i]))
658 return;
659 },
660
661 _removeFromDebugger: function()
662 {
663 this._resetLocations();
664 if (!this._debuggerId)
665 return;
666 var barrier = new CallbackBarrier();
667 this._breakpointManager._targetManager.targets().forEach(function(target ){target.debuggerModel.removeBreakpoint(this._debuggerId, barrier.createCallback ())}, this);
668 barrier.callWhenDone(this._didRemoveFromDebugger.bind(this));
669 },
670
671 _didRemoveFromDebugger: function()
672 {
673 delete this._breakpointManager._breakpointForDebuggerId[this._debuggerId ];
674 delete this._debuggerId;
675 },
676
677 _resetLocations: function()
678 {
679 for (var stringifiedLocation in this._uiLocations) {
680 var uiLocation = this._uiLocations[stringifiedLocation];
681 if (this._numberOfDebuggerLocationForUILocation[uiLocation.id()]) {
682 this._breakpointManager._uiLocationRemoved(this, uiLocation);
683 delete this._numberOfDebuggerLocationForUILocation[uiLocation.id ()];
684 }
685 }
686 if (this._uiLocations[""])
687 this._breakpointManager._uiLocationRemoved(this, this._uiLocations[" "]);
688 for (var i = 0; i < this._liveLocations.length; ++i)
689 this._liveLocations[i].dispose();
690 this._liveLocations = [];
691 this._uiLocations = {};
692 this._numberOfDebuggerLocationForUILocation = {};
693 }, 610 },
694 611
695 /** 612 /**
696 * @return {string} 613 * @return {string}
697 */ 614 */
698 _breakpointStorageId: function() 615 _breakpointStorageId: function()
699 { 616 {
700 return WebInspector.BreakpointManager._breakpointStorageId(this._sourceF ileId, this._lineNumber, this._columnNumber); 617 return WebInspector.BreakpointManager._breakpointStorageId(this._sourceF ileId, this._lineNumber, this._columnNumber);
701 }, 618 },
702 619
703 _fakeBreakpointAtPrimaryLocation: function() 620 _fakeBreakpointAtPrimaryLocation: function()
704 { 621 {
622 if (this._isRemoved || !Object.isEmpty(this._numberOfDebuggerLocationFor UILocation) || this._fakeBreakpointPrimaryLocation)
623 return;
624
705 var uiSourceCode = this._breakpointManager._workspace.uiSourceCode(this. _projectId, this._path); 625 var uiSourceCode = this._breakpointManager._workspace.uiSourceCode(this. _projectId, this._path);
706 if (!uiSourceCode) 626 if (!uiSourceCode)
707 return; 627 return;
708 var uiLocation = uiSourceCode.uiLocation(this._lineNumber, this._columnN umber); 628
709 this._uiLocations[""] = uiLocation; 629 this._fakeBreakpointPrimaryLocation = uiSourceCode.uiLocation(this._line Number, this._columnNumber);
710 this._breakpointManager._uiLocationAdded(this, uiLocation); 630 this._breakpointManager._uiLocationAdded(this, this._fakeBreakpointPrima ryLocation);
631 },
632
633 _removeFakeBreakpointAtPrimaryLocation: function()
634 {
635 if (this._fakeBreakpointPrimaryLocation) {
636 this._breakpointManager._uiLocationRemoved(this, this._fakeBreakpoin tPrimaryLocation);
637 delete this._fakeBreakpointPrimaryLocation;
638 }
639 },
640
641 _resetLocations: function()
642 {
643 this._removeFakeBreakpointAtPrimaryLocation();
644 var targetBreakpoints = this._targetBreakpoints.values();
645 for (var i = 0; i < targetBreakpoints.length; ++i)
646 targetBreakpoints[i]._resetLocations();
711 } 647 }
712 } 648 }
713 649
714 /** 650 /**
651 * @constructor
652 * @extends {WebInspector.TargetAware}
653 * @param {!WebInspector.Target} target
654 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
655 */
656 WebInspector.BreakpointManager.TargetBreakpoint = function(target, breakpoint)
657 {
658 WebInspector.TargetAware.call(this, target);
659 this._breakpoint = breakpoint;
660 /** @type {!Array.<!WebInspector.Script.Location>} */
661 this._liveLocations = [];
662
663 /** @type {!Object.<string, !WebInspector.UILocation>} */
664 this._uiLocations = {};
665 target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.Brea kpointResolved, this._breakpointResolved, this);
666 }
667
668 WebInspector.BreakpointManager.TargetBreakpoint.prototype = {
669
670 _resetLocations: function()
671 {
672 var uiLocations = Object.values(this._uiLocations);
673 for (var i = 0; i < uiLocations.length; ++i)
674 this._breakpoint._removeUILocation(uiLocations[i]);
675
676 this._uiLocations = {};
677
678 for (var i = 0; i < this._liveLocations.length; ++i)
679 this._liveLocations[i].dispose();
680 this._liveLocations = [];
681 },
682
683 /**
684 * @param {boolean=} muteCallback
685 */
686 _removeFromDebugger: function(muteCallback)
687 {
688 this._resetLocations();
689 if (!this._debuggerId)
690 return;
691 this.target().debuggerModel.removeBreakpoint(this._debuggerId, muteCallb ack ? undefined : this._didRemoveFromDebugger.bind(this));
692 },
693
694 _updateInDebugger: function()
695 {
696 this._removeFromDebugger();
697 var uiSourceCode = this._breakpoint.uiSourceCode();
698 if (!uiSourceCode || !this._breakpoint._enabled)
699 return;
700 var scriptFile = uiSourceCode.scriptFileForTarget(this._target);
701 if (scriptFile && scriptFile.hasDivergedFromVM())
702 return;
703
704 var lineNumber = this._breakpoint._lineNumber;
705 var columnNumber = this._breakpoint._columnNumber;
706 var rawLocation = uiSourceCode.uiLocationToRawLocation(this._target, lin eNumber, columnNumber);
707 var debuggerModelLocation = /** @type {!WebInspector.DebuggerModel.Locat ion} */ (rawLocation);
708 var condition = this._breakpoint.condition();
709 if (debuggerModelLocation)
710 this.target().debuggerModel.setBreakpointByScriptLocation(debuggerMo delLocation, condition, this._didSetBreakpointInDebugger.bind(this));
711 else if (uiSourceCode.url)
712 this.target().debuggerModel.setBreakpointByURL(uiSourceCode.url, lin eNumber, columnNumber, condition, this._didSetBreakpointInDebugger.bind(this));
713 },
714
715 /**
716 * @param {?DebuggerAgent.BreakpointId} breakpointId
717 * @param {!Array.<!WebInspector.DebuggerModel.Location>} locations
718 */
719 _didSetBreakpointInDebugger: function(breakpointId, locations)
720 {
721 if (!breakpointId) {
722 this._breakpoint.remove(true);
723 return;
724 }
725
726 if (this._debuggerId)
727 this._removeFromDebugger(true);
728
729 this._debuggerId = breakpointId;
730 for (var i = 0; i < locations.length; ++i)
731 if (!this._addResolvedLocation(locations[i]))
732 return;
733 },
734
735 _didRemoveFromDebugger: function()
736 {
737 delete this._debuggerId;
738 },
739
740 /**
741 * @param {!WebInspector.Event} event
742 */
743 _breakpointResolved: function(event)
744 {
745 var breakpointId = /** @type {!DebuggerAgent.BreakpointId} */ (event.dat a.breakpointId);
746 var location = /** @type {!WebInspector.DebuggerModel.Location} */ (even t.data.location);
747 if (this._debuggerId === breakpointId)
748 this._addResolvedLocation(location);
749 },
750
751 /**
752 * @param {!WebInspector.DebuggerModel.Location} location
753 * @param {!WebInspector.UILocation} uiLocation
754 */
755 _locationUpdated: function(location, uiLocation)
756 {
757 var oldUILocation = this._uiLocations[location.id()] || null;
758 this._uiLocations[location.id()] = uiLocation;
759 this._breakpoint._replaceUILocation(oldUILocation, uiLocation);
760 },
761
762 /**
763 * @param {!WebInspector.DebuggerModel.Location} location
764 * @return {boolean}
765 */
766 _addResolvedLocation: function(location)
767 {
768 var script = location.script();
769 var uiLocation = script.rawLocationToUILocation(location.lineNumber, loc ation.columnNumber);
770 var breakpoint = this._breakpoint._breakpointManager.findBreakpoint(uiLo cation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber);
771 if (breakpoint && breakpoint != this._breakpoint) {
772 // location clash
773 this._breakpoint.remove();
774 return false;
775 }
776 this._liveLocations.push(location.createLiveLocation(this._locationUpdat ed.bind(this, location)));
777 return true;
778 },
779
780 _dispose: function()
781 {
782 this.target().debuggerModel.removeEventListener(WebInspector.DebuggerMod el.Events.BreakpointResolved, this._breakpointResolved, this);
783 this._removeFromDebugger();
784 },
785
786 __proto__: WebInspector.TargetAware.prototype
787 }
788
789 /**
715 * @constructor 790 * @constructor
716 * @param {!WebInspector.BreakpointManager} breakpointManager 791 * @param {!WebInspector.BreakpointManager} breakpointManager
717 * @param {!WebInspector.Setting} setting 792 * @param {!WebInspector.Setting} setting
718 */ 793 */
719 WebInspector.BreakpointManager.Storage = function(breakpointManager, setting) 794 WebInspector.BreakpointManager.Storage = function(breakpointManager, setting)
720 { 795 {
721 this._breakpointManager = breakpointManager; 796 this._breakpointManager = breakpointManager;
722 this._setting = setting; 797 this._setting = setting;
723 var breakpoints = this._setting.get(); 798 var breakpoints = this._setting.get();
724 /** @type {!Object.<string, !WebInspector.BreakpointManager.Storage.Item>} * / 799 /** @type {!Object.<string, !WebInspector.BreakpointManager.Storage.Item>} * /
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 { 871 {
797 this.sourceFileId = breakpoint._sourceFileId; 872 this.sourceFileId = breakpoint._sourceFileId;
798 this.lineNumber = breakpoint.lineNumber(); 873 this.lineNumber = breakpoint.lineNumber();
799 this.columnNumber = breakpoint.columnNumber(); 874 this.columnNumber = breakpoint.columnNumber();
800 this.condition = breakpoint.condition(); 875 this.condition = breakpoint.condition();
801 this.enabled = breakpoint.enabled(); 876 this.enabled = breakpoint.enabled();
802 } 877 }
803 878
804 /** @type {!WebInspector.BreakpointManager} */ 879 /** @type {!WebInspector.BreakpointManager} */
805 WebInspector.breakpointManager; 880 WebInspector.breakpointManager;
OLDNEW
« no previous file with comments | « LayoutTests/inspector/sources/debugger/set-breakpoint.html ('k') | Source/devtools/front_end/sdk/Target.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698