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

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: Fix quadratic complexity 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._fakePrimaryLocation;
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 this._targetBreakpoints.remove(target)._dispose();
459 },
460
461 /**
479 * @return {string} 462 * @return {string}
480 */ 463 */
481 projectId: function() 464 projectId: function()
482 { 465 {
483 return this._projectId; 466 return this._projectId;
484 }, 467 },
485 468
486 /** 469 /**
487 * @return {string} 470 * @return {string}
488 */ 471 */
(...skipping 20 matching lines...) Expand all
509 492
510 /** 493 /**
511 * @return {?WebInspector.UISourceCode} 494 * @return {?WebInspector.UISourceCode}
512 */ 495 */
513 uiSourceCode: function() 496 uiSourceCode: function()
514 { 497 {
515 return this._breakpointManager._workspace.uiSourceCode(this._projectId, this._path); 498 return this._breakpointManager._workspace.uiSourceCode(this._projectId, this._path);
516 }, 499 },
517 500
518 /** 501 /**
519 * @param {!WebInspector.DebuggerModel.Location} location 502 * @param {?WebInspector.UILocation} oldUILocation
520 * @return {boolean} 503 * @param {!WebInspector.UILocation} newUILocation
521 */ 504 */
522 _addResolvedLocation: function(location) 505 _replaceUILocation: function(oldUILocation, newUILocation)
523 { 506 {
524 var script = location.script(); 507 if (this._isRemoved)
525 var uiLocation = script.rawLocationToUILocation(location.lineNumber, loc ation.columnNumber); 508 return;
526 var breakpoint = this._breakpointManager.findBreakpoint(uiLocation.uiSou rceCode, uiLocation.lineNumber, uiLocation.columnNumber); 509
527 if (breakpoint && breakpoint != this) { 510 this._removeUILocation(oldUILocation, true);
528 // location clash 511 this._removeFakeBreakpointAtPrimaryLocation();
529 this.remove(); 512
530 return false; 513 if (!this._numberOfDebuggerLocationForUILocation[newUILocation.id()])
531 } 514 this._numberOfDebuggerLocationForUILocation[newUILocation.id()] = 0;
532 this._liveLocations.push(location.createLiveLocation(this._locationUpdat ed.bind(this, location))); 515
533 return true; 516 if (++this._numberOfDebuggerLocationForUILocation[newUILocation.id()] == = 1)
517 this._breakpointManager._uiLocationAdded(this, newUILocation);
534 }, 518 },
535 519
536 /** 520 /**
537 * @param {!WebInspector.DebuggerModel.Location} location 521 * @param {?WebInspector.UILocation} uiLocation
538 * @param {!WebInspector.UILocation} uiLocation 522 * @param {boolean=} muteCreationFakeBreakpoint
539 */ 523 */
540 _locationUpdated: function(location, uiLocation) 524 _removeUILocation: function(uiLocation, muteCreationFakeBreakpoint)
541 { 525 {
542 var oldUILocation = /** @type {!WebInspector.UILocation} */ (this._uiLoc ations[location.id()]); 526 if (!uiLocation || --this._numberOfDebuggerLocationForUILocation[uiLocat ion.id()] !== 0)
543 if (oldUILocation && --this._numberOfDebuggerLocationForUILocation[oldUI Location.id()] === 0) { 527 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 528
554 if (!this._numberOfDebuggerLocationForUILocation[uiLocation.id()]) 529 delete this._numberOfDebuggerLocationForUILocation[uiLocation.id()];
555 this._numberOfDebuggerLocationForUILocation[uiLocation.id()] = 0; 530 this._breakpointManager._uiLocationRemoved(this, uiLocation);
556 531 if (!muteCreationFakeBreakpoint)
557 if (++this._numberOfDebuggerLocationForUILocation[uiLocation.id()] === 1 ) 532 this._fakeBreakpointAtPrimaryLocation();
558 this._breakpointManager._uiLocationAdded(this, uiLocation);
559 }, 533 },
560 534
561 /** 535 /**
562 * @return {boolean} 536 * @return {boolean}
563 */ 537 */
564 enabled: function() 538 enabled: function()
565 { 539 {
566 return this._enabled; 540 return this._enabled;
567 }, 541 },
568 542
569 /** 543 /**
570 * @param {boolean} enabled 544 * @param {boolean} enabled
571 */ 545 */
572 setEnabled: function(enabled) 546 setEnabled: function(enabled)
573 { 547 {
574 this._updateBreakpoint(this._condition, enabled); 548 this._updateState(this._condition, enabled);
575 }, 549 },
576 550
577 /** 551 /**
578 * @return {string} 552 * @return {string}
579 */ 553 */
580 condition: function() 554 condition: function()
581 { 555 {
582 return this._condition; 556 return this._condition;
583 }, 557 },
584 558
585 /** 559 /**
586 * @param {string} condition 560 * @param {string} condition
587 */ 561 */
588 setCondition: function(condition) 562 setCondition: function(condition)
589 { 563 {
590 this._updateBreakpoint(condition, this._enabled); 564 this._updateState(condition, this._enabled);
591 }, 565 },
592 566
593 /** 567 /**
594 * @param {string} condition 568 * @param {string} condition
595 * @param {boolean} enabled 569 * @param {boolean} enabled
596 */ 570 */
597 _updateBreakpoint: function(condition, enabled) 571 _updateState: function(condition, enabled)
598 { 572 {
599 if (this._enabled === enabled && this._condition === condition) 573 if (this._enabled === enabled && this._condition === condition)
600 return; 574 return;
601 this._enabled = enabled; 575 this._enabled = enabled;
602 this._condition = condition; 576 this._condition = condition;
603 this._breakpointManager._storage._updateBreakpoint(this); 577 this._breakpointManager._storage._updateBreakpoint(this);
578 this._updateBreakpoint();
579 },
580
581 _updateBreakpoint: function()
582 {
583 this._removeFakeBreakpointAtPrimaryLocation();
584 this._fakeBreakpointAtPrimaryLocation();
604 this._updateInDebugger(); 585 this._updateInDebugger();
605 }, 586 },
606 587
607 /** 588 /**
608 * @param {boolean=} keepInStorage 589 * @param {boolean=} keepInStorage
609 */ 590 */
610 remove: function(keepInStorage) 591 remove: function(keepInStorage)
611 { 592 {
593 this._isRemoved = true;
612 var removeFromStorage = !keepInStorage; 594 var removeFromStorage = !keepInStorage;
595 this._removeFakeBreakpointAtPrimaryLocation();
596 var targets = this._targetBreakpoints.keys();
597 for (var i = 0; i < targets.length; ++i)
598 this._targetBreakpoints.get(targets[i])._dispose();
599
600 this._breakpointManager._removeBreakpoint(this, removeFromStorage);
601 this._breakpointManager._targetManager.unobserveTargets(this);
602 },
603
604 _updateInDebugger: function()
605 {
606 var targetBreakpoints = this._targetBreakpoints.values();
607 for (var i = 0; i < targetBreakpoints.length; ++i)
608 targetBreakpoints[i]._updateInDebugger();
609 },
610
611 /**
612 * @return {string}
613 */
614 _breakpointStorageId: function()
615 {
616 return WebInspector.BreakpointManager._breakpointStorageId(this._sourceF ileId, this._lineNumber, this._columnNumber);
617 },
618
619 _fakeBreakpointAtPrimaryLocation: function()
620 {
621 if (this._isRemoved || !Object.isEmpty(this._numberOfDebuggerLocationFor UILocation) || this._fakePrimaryLocation)
622 return;
623
624 var uiSourceCode = this._breakpointManager._workspace.uiSourceCode(this. _projectId, this._path);
625 if (!uiSourceCode)
626 return;
627
628 this._fakePrimaryLocation = uiSourceCode.uiLocation(this._lineNumber, th is._columnNumber);
629 this._breakpointManager._uiLocationAdded(this, this._fakePrimaryLocation );
630 },
631
632 _removeFakeBreakpointAtPrimaryLocation: function()
633 {
634 if (this._fakePrimaryLocation) {
635 this._breakpointManager._uiLocationRemoved(this, this._fakePrimaryLo cation);
636 delete this._fakePrimaryLocation;
637 }
638 },
639
640 _resetLocations: function()
641 {
642 this._removeFakeBreakpointAtPrimaryLocation();
643 var targetBreakpoints = this._targetBreakpoints.values();
644 for (var i = 0; i < targetBreakpoints.length; ++i)
645 targetBreakpoints[i]._resetLocations();
646 }
647 }
648
649 /**
650 * @constructor
651 * @extends {WebInspector.TargetAware}
652 * @implements {WebInspector.DebuggerModel.BreakpointListener}
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 }
666
667 WebInspector.BreakpointManager.TargetBreakpoint.prototype = {
668
669 _resetLocations: function()
670 {
671 var uiLocations = Object.values(this._uiLocations);
672 for (var i = 0; i < uiLocations.length; ++i)
673 this._breakpoint._removeUILocation(uiLocations[i]);
674
675 this._uiLocations = {};
676
677 for (var i = 0; i < this._liveLocations.length; ++i)
678 this._liveLocations[i].dispose();
679 this._liveLocations = [];
680 },
681
682 /**
683 * @param {boolean=} callCallbackImmediately
684 */
685 _removeFromDebugger: function(callCallbackImmediately)
vsevik 2014/06/05 15:48:29 callbackImmediately
sergeyv 2014/06/06 11:44:53 Done.
686 {
687 this._resetLocations();
688 if (!this._debuggerId)
689 return;
690 this.target().debuggerModel.removeBreakpoint(this._debuggerId, callCallb ackImmediately ? undefined : this._didRemoveFromDebugger.bind(this));
691
692 if (callCallbackImmediately)
693 this._didRemoveFromDebugger();
694 },
695
696 _updateInDebugger: function()
697 {
613 this._removeFromDebugger(); 698 this._removeFromDebugger();
614 this._breakpointManager._removeBreakpoint(this, removeFromStorage); 699 var uiSourceCode = this._breakpoint.uiSourceCode();
615 }, 700 if (!uiSourceCode || !this._breakpoint._enabled)
616 701 return;
617 _updateInDebugger: function() 702 var scriptFile = uiSourceCode.scriptFileForTarget(this._target);
618 { 703 if (scriptFile && scriptFile.hasDivergedFromVM())
619 this._removeFromDebugger(); 704 return;
620 this._fakeBreakpointAtPrimaryLocation(); 705
621 var uiSourceCode = this.uiSourceCode(); 706 var lineNumber = this._breakpoint._lineNumber;
622 if (!uiSourceCode || !this._enabled) 707 var columnNumber = this._breakpoint._columnNumber;
623 return; 708 var rawLocation = uiSourceCode.uiLocationToRawLocation(this._target, lin eNumber, columnNumber);
624 709 var debuggerModelLocation = /** @type {!WebInspector.DebuggerModel.Locat ion} */ (rawLocation);
625 var targets = this._breakpointManager._targetManager.targets(); 710 var condition = this._breakpoint.condition();
626 for (var i = 0; i < targets.length; ++i) { 711 if (debuggerModelLocation)
627 var scriptFile = uiSourceCode.scriptFileForTarget(targets[i]); 712 this.target().debuggerModel.setBreakpointByScriptLocation(debuggerMo delLocation, condition, this._didSetBreakpointInDebugger.bind(this));
628 if (scriptFile && scriptFile.hasDivergedFromVM()) 713 else if (uiSourceCode.url)
629 return; 714 this.target().debuggerModel.setBreakpointByURL(uiSourceCode.url, lin eNumber, columnNumber, condition, this._didSetBreakpointInDebugger.bind(this));
715 },
716
717 /**
718 * @param {?DebuggerAgent.BreakpointId} breakpointId
719 * @param {!Array.<!WebInspector.DebuggerModel.Location>} locations
720 */
721 _didSetBreakpointInDebugger: function(breakpointId, locations)
722 {
723 if (!breakpointId) {
724 this._breakpoint.remove(true);
725 return;
630 } 726 }
631 727
632 for (var i = 0; i < targets.length; ++i) { 728 if (this._debuggerId)
633 var rawLocation = uiSourceCode.uiLocationToRawLocation(targets[i], t his._lineNumber, this._columnNumber); 729 this._removeFromDebugger(true);
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 730
653 this._debuggerId = breakpointId; 731 this._debuggerId = breakpointId;
654 this._breakpointManager._breakpointForDebuggerId[breakpointId] = this; 732 this.target().debuggerModel.registerBreakpointListenerForId(this._debugg erId, this);
vsevik 2014/06/05 15:48:29 addBreakpointListener(id, this._breakpointResolved
sergeyv 2014/06/06 11:44:53 Done.
655
656 for (var i = 0; i < locations.length; ++i) 733 for (var i = 0; i < locations.length; ++i)
657 if (!this._addResolvedLocation(locations[i])) 734 if (!this._addResolvedLocation(locations[i]))
658 return; 735 return;
659 }, 736 },
660 737
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() 738 _didRemoveFromDebugger: function()
672 { 739 {
673 delete this._breakpointManager._breakpointForDebuggerId[this._debuggerId ]; 740 this.target().debuggerModel.unregisterBreakpointListenerForId(this._debu ggerId);
674 delete this._debuggerId; 741 delete this._debuggerId;
675 }, 742 },
676 743
677 _resetLocations: function() 744 /**
678 { 745 * @param {!WebInspector.DebuggerModel.Location} location
679 for (var stringifiedLocation in this._uiLocations) { 746 */
680 var uiLocation = this._uiLocations[stringifiedLocation]; 747 breakpointResolved: function(location)
681 if (this._numberOfDebuggerLocationForUILocation[uiLocation.id()]) { 748 {
682 this._breakpointManager._uiLocationRemoved(this, uiLocation); 749 this._addResolvedLocation(location);
683 delete this._numberOfDebuggerLocationForUILocation[uiLocation.id ()]; 750 },
684 } 751
752 /**
753 * @param {!WebInspector.DebuggerModel.Location} location
754 * @param {!WebInspector.UILocation} uiLocation
755 */
756 _locationUpdated: function(location, uiLocation)
757 {
758 var oldUILocation = this._uiLocations[location.id()] || null;
759 this._uiLocations[location.id()] = uiLocation;
760 this._breakpoint._replaceUILocation(oldUILocation, uiLocation);
761 },
762
763 /**
764 * @param {!WebInspector.DebuggerModel.Location} location
765 * @return {boolean}
766 */
767 _addResolvedLocation: function(location)
768 {
769 var script = location.script();
770 var uiLocation = script.rawLocationToUILocation(location.lineNumber, loc ation.columnNumber);
771 var breakpoint = this._breakpoint._breakpointManager.findBreakpoint(uiLo cation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber);
772 if (breakpoint && breakpoint != this._breakpoint) {
773 // location clash
774 this._breakpoint.remove();
775 return false;
685 } 776 }
686 if (this._uiLocations[""]) 777 this._liveLocations.push(location.createLiveLocation(this._locationUpdat ed.bind(this, location)));
687 this._breakpointManager._uiLocationRemoved(this, this._uiLocations[" "]); 778 return true;
688 for (var i = 0; i < this._liveLocations.length; ++i) 779 },
689 this._liveLocations[i].dispose(); 780
690 this._liveLocations = []; 781 _dispose: function()
vsevik 2014/06/05 15:48:29 Looks like this method is now redundant.
sergeyv 2014/06/06 11:44:53 Done.
691 this._uiLocations = {}; 782 {
692 this._numberOfDebuggerLocationForUILocation = {}; 783 this._removeFromDebugger();
vsevik 2014/06/05 15:48:29 This should not be done on TargetRemoved
sergeyv 2014/06/06 11:44:53 Done.
693 }, 784 },
694 785
695 /** 786 __proto__: WebInspector.TargetAware.prototype
696 * @return {string}
697 */
698 _breakpointStorageId: function()
699 {
700 return WebInspector.BreakpointManager._breakpointStorageId(this._sourceF ileId, this._lineNumber, this._columnNumber);
701 },
702
703 _fakeBreakpointAtPrimaryLocation: function()
704 {
705 var uiSourceCode = this._breakpointManager._workspace.uiSourceCode(this. _projectId, this._path);
706 if (!uiSourceCode)
707 return;
708 var uiLocation = uiSourceCode.uiLocation(this._lineNumber, this._columnN umber);
709 this._uiLocations[""] = uiLocation;
710 this._breakpointManager._uiLocationAdded(this, uiLocation);
711 }
712 } 787 }
713 788
714 /** 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;
(...skipping 74 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

Powered by Google App Engine
This is Rietveld 408576698