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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved. 2 * Copyright (C) 2010 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
11 * copyright notice, this list of conditions and the following disclaimer 11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the 12 * in the documentation and/or other materials provided with the
13 * distribution. 13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its 14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from 15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission. 16 * this software without specific prior written permission.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
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
31 /** 30 /**
32 * @constructor 31 * @unrestricted
33 * @extends {WebInspector.SDKModel}
34 * @param {!WebInspector.Target} target
35 */ 32 */
36 WebInspector.DebuggerModel = function(target) 33 WebInspector.DebuggerModel = class extends WebInspector.SDKModel {
37 { 34 /**
38 WebInspector.SDKModel.call(this, WebInspector.DebuggerModel, target); 35 * @param {!WebInspector.Target} target
36 */
37 constructor(target) {
38 super(WebInspector.DebuggerModel, target);
39 39
40 target.registerDebuggerDispatcher(new WebInspector.DebuggerDispatcher(this)) ; 40 target.registerDebuggerDispatcher(new WebInspector.DebuggerDispatcher(this)) ;
41 this._agent = target.debuggerAgent(); 41 this._agent = target.debuggerAgent();
42 42
43 /** @type {?WebInspector.DebuggerPausedDetails} */ 43 /** @type {?WebInspector.DebuggerPausedDetails} */
44 this._debuggerPausedDetails = null; 44 this._debuggerPausedDetails = null;
45 /** @type {!Object.<string, !WebInspector.Script>} */ 45 /** @type {!Object.<string, !WebInspector.Script>} */
46 this._scripts = {}; 46 this._scripts = {};
47 /** @type {!Map.<string, !Array.<!WebInspector.Script>>} */ 47 /** @type {!Map.<string, !Array.<!WebInspector.Script>>} */
48 this._scriptsBySourceURL = new Map(); 48 this._scriptsBySourceURL = new Map();
49 49
50 /** @type {!WebInspector.Object} */ 50 /** @type {!WebInspector.Object} */
51 this._breakpointResolvedEventTarget = new WebInspector.Object(); 51 this._breakpointResolvedEventTarget = new WebInspector.Object();
52 52
53 this._isPausing = false; 53 this._isPausing = false;
54 WebInspector.moduleSetting("pauseOnExceptionEnabled").addChangeListener(this ._pauseOnExceptionStateChanged, this); 54 WebInspector.moduleSetting('pauseOnExceptionEnabled').addChangeListener(this ._pauseOnExceptionStateChanged, this);
55 WebInspector.moduleSetting("pauseOnCaughtException").addChangeListener(this. _pauseOnExceptionStateChanged, this); 55 WebInspector.moduleSetting('pauseOnCaughtException').addChangeListener(this. _pauseOnExceptionStateChanged, this);
56 WebInspector.moduleSetting("enableAsyncStackTraces").addChangeListener(this. asyncStackTracesStateChanged, this); 56 WebInspector.moduleSetting('enableAsyncStackTraces').addChangeListener(this. asyncStackTracesStateChanged, this);
57 57
58 this.enableDebugger(); 58 this.enableDebugger();
59 }
60
61 /**
62 * @return {!Array<!WebInspector.DebuggerModel>}
63 */
64 static instances() {
65 var result = [];
66 for (var target of WebInspector.targetManager.targets()) {
67 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
68 if (debuggerModel)
69 result.push(debuggerModel);
70 }
71 return result;
72 }
73
74 /**
75 * @param {?WebInspector.Target} target
76 * @return {?WebInspector.DebuggerModel}
77 */
78 static fromTarget(target) {
79 if (!target || !target.hasJSCapability())
80 return null;
81 return /** @type {?WebInspector.DebuggerModel} */ (target.model(WebInspector .DebuggerModel));
82 }
83
84 /**
85 * @return {boolean}
86 */
87 debuggerEnabled() {
88 return !!this._debuggerEnabled;
89 }
90
91 /**
92 * @param {function()=} callback
93 */
94 enableDebugger(callback) {
95 if (this._debuggerEnabled) {
96 if (callback)
97 callback();
98 return;
99 }
100 this._agent.enable(callback);
101 this._debuggerEnabled = true;
102 this._pauseOnExceptionStateChanged();
103 this.asyncStackTracesStateChanged();
104 this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerWasE nabled);
105 }
106
107 /**
108 * @param {function()=} callback
109 */
110 disableDebugger(callback) {
111 if (!this._debuggerEnabled) {
112 if (callback)
113 callback();
114 return;
115 }
116
117 this._agent.disable(callback);
118 this._debuggerEnabled = false;
119 this._isPausing = false;
120 this.asyncStackTracesStateChanged();
121 this.globalObjectCleared();
122 this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerWasD isabled);
123 }
124
125 /**
126 * @param {boolean} skip
127 */
128 _skipAllPauses(skip) {
129 if (this._skipAllPausesTimeout) {
130 clearTimeout(this._skipAllPausesTimeout);
131 delete this._skipAllPausesTimeout;
132 }
133 this._agent.setSkipAllPauses(skip);
134 }
135
136 /**
137 * @param {number} timeout
138 */
139 skipAllPausesUntilReloadOrTimeout(timeout) {
140 if (this._skipAllPausesTimeout)
141 clearTimeout(this._skipAllPausesTimeout);
142 this._agent.setSkipAllPauses(true);
143 // If reload happens before the timeout, the flag will be already unset and the timeout callback won't change anything.
144 this._skipAllPausesTimeout = setTimeout(this._skipAllPauses.bind(this, false ), timeout);
145 }
146
147 _pauseOnExceptionStateChanged() {
148 var state;
149 if (!WebInspector.moduleSetting('pauseOnExceptionEnabled').get()) {
150 state = WebInspector.DebuggerModel.PauseOnExceptionsState.DontPauseOnExcep tions;
151 } else if (WebInspector.moduleSetting('pauseOnCaughtException').get()) {
152 state = WebInspector.DebuggerModel.PauseOnExceptionsState.PauseOnAllExcept ions;
153 } else {
154 state = WebInspector.DebuggerModel.PauseOnExceptionsState.PauseOnUncaughtE xceptions;
155 }
156 this._agent.setPauseOnExceptions(state);
157 }
158
159 asyncStackTracesStateChanged() {
160 const maxAsyncStackChainDepth = 4;
161 var enabled = WebInspector.moduleSetting('enableAsyncStackTraces').get() && this._debuggerEnabled;
162 this._agent.setAsyncCallStackDepth(enabled ? maxAsyncStackChainDepth : 0);
163 }
164
165 stepInto() {
166 this._agent.stepInto();
167 }
168
169 stepOver() {
170 this._agent.stepOver();
171 }
172
173 stepOut() {
174 this._agent.stepOut();
175 }
176
177 resume() {
178 this._agent.resume();
179 this._isPausing = false;
180 }
181
182 pause() {
183 this._isPausing = true;
184 this._skipAllPauses(false);
185 this._agent.pause();
186 }
187
188 /**
189 * @param {boolean} active
190 */
191 setBreakpointsActive(active) {
192 this._agent.setBreakpointsActive(active);
193 }
194
195 /**
196 * @param {string} url
197 * @param {number} lineNumber
198 * @param {number=} columnNumber
199 * @param {string=} condition
200 * @param {function(?DebuggerAgent.BreakpointId, !Array.<!WebInspector.Debugge rModel.Location>)=} callback
201 */
202 setBreakpointByURL(url, lineNumber, columnNumber, condition, callback) {
203 // Adjust column if needed.
204 var minColumnNumber = 0;
205 var scripts = this._scriptsBySourceURL.get(url) || [];
206 for (var i = 0, l = scripts.length; i < l; ++i) {
207 var script = scripts[i];
208 if (lineNumber === script.lineOffset)
209 minColumnNumber = minColumnNumber ? Math.min(minColumnNumber, script.col umnOffset) : script.columnOffset;
210 }
211 columnNumber = Math.max(columnNumber, minColumnNumber);
212
213 var target = this.target();
214 /**
215 * @param {?Protocol.Error} error
216 * @param {!DebuggerAgent.BreakpointId} breakpointId
217 * @param {!Array.<!DebuggerAgent.Location>} locations
218 * @this {WebInspector.DebuggerModel}
219 */
220 function didSetBreakpoint(error, breakpointId, locations) {
221 if (callback) {
222 var rawLocations = locations ?
223 locations.map(
224 WebInspector.DebuggerModel.Location.fromPayload.bind(WebInspecto r.DebuggerModel.Location, this)) :
225 [];
226 callback(error ? null : breakpointId, rawLocations);
227 }
228 }
229 this._agent.setBreakpointByUrl(lineNumber, url, undefined, columnNumber, con dition, didSetBreakpoint.bind(this));
230 }
231
232 /**
233 * @param {!WebInspector.DebuggerModel.Location} rawLocation
234 * @param {string} condition
235 * @param {function(?DebuggerAgent.BreakpointId, !Array.<!WebInspector.Debugge rModel.Location>)=} callback
236 */
237 setBreakpointBySourceId(rawLocation, condition, callback) {
238 var target = this.target();
239
240 /**
241 * @this {WebInspector.DebuggerModel}
242 * @param {?Protocol.Error} error
243 * @param {!DebuggerAgent.BreakpointId} breakpointId
244 * @param {!DebuggerAgent.Location} actualLocation
245 */
246 function didSetBreakpoint(error, breakpointId, actualLocation) {
247 if (callback) {
248 if (error || !actualLocation) {
249 callback(null, []);
250 return;
251 }
252 callback(breakpointId, [WebInspector.DebuggerModel.Location.fromPayload( this, actualLocation)]);
253 }
254 }
255 this._agent.setBreakpoint(rawLocation.payload(), condition, didSetBreakpoint .bind(this));
256 }
257
258 /**
259 * @param {!DebuggerAgent.BreakpointId} breakpointId
260 * @param {function()=} callback
261 */
262 removeBreakpoint(breakpointId, callback) {
263 this._agent.removeBreakpoint(breakpointId, innerCallback);
264
265 /**
266 * @param {?Protocol.Error} error
267 */
268 function innerCallback(error) {
269 if (error)
270 console.error('Failed to remove breakpoint: ' + error);
271 if (callback)
272 callback();
273 }
274 }
275
276 /**
277 * @param {!DebuggerAgent.BreakpointId} breakpointId
278 * @param {!DebuggerAgent.Location} location
279 */
280 _breakpointResolved(breakpointId, location) {
281 this._breakpointResolvedEventTarget.dispatchEventToListeners(
282 breakpointId, WebInspector.DebuggerModel.Location.fromPayload(this, loca tion));
283 }
284
285 globalObjectCleared() {
286 this._setDebuggerPausedDetails(null);
287 this._reset();
288 // TODO(dgozman): move clients to ExecutionContextDestroyed/ScriptCollected events.
289 this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.GlobalObject Cleared);
290 }
291
292 _reset() {
293 this._scripts = {};
294 this._scriptsBySourceURL.clear();
295 }
296
297 /**
298 * @return {!Object.<string, !WebInspector.Script>}
299 */
300 get scripts() {
301 return this._scripts;
302 }
303
304 /**
305 * @param {!RuntimeAgent.ScriptId} scriptId
306 * @return {?WebInspector.Script}
307 */
308 scriptForId(scriptId) {
309 return this._scripts[scriptId] || null;
310 }
311
312 /**
313 * @return {!Array.<!WebInspector.Script>}
314 */
315 scriptsForSourceURL(sourceURL) {
316 if (!sourceURL)
317 return [];
318 return this._scriptsBySourceURL.get(sourceURL) || [];
319 }
320
321 /**
322 * @param {!RuntimeAgent.ScriptId} scriptId
323 * @param {string} newSource
324 * @param {function(?Protocol.Error, !RuntimeAgent.ExceptionDetails=)} callbac k
325 */
326 setScriptSource(scriptId, newSource, callback) {
327 this._scripts[scriptId].editSource(newSource, this._didEditScriptSource.bind (this, scriptId, newSource, callback));
328 }
329
330 /**
331 * @param {!RuntimeAgent.ScriptId} scriptId
332 * @param {string} newSource
333 * @param {function(?Protocol.Error, !RuntimeAgent.ExceptionDetails=)} callbac k
334 * @param {?Protocol.Error} error
335 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails
336 * @param {!Array.<!DebuggerAgent.CallFrame>=} callFrames
337 * @param {!RuntimeAgent.StackTrace=} asyncStackTrace
338 * @param {boolean=} needsStepIn
339 */
340 _didEditScriptSource(
341 scriptId,
342 newSource,
343 callback,
344 error,
345 exceptionDetails,
346 callFrames,
347 asyncStackTrace,
348 needsStepIn) {
349 if (needsStepIn) {
350 this.stepInto();
351 this._pendingLiveEditCallback = callback.bind(this, error, exceptionDetail s);
352 return;
353 }
354
355 if (!error && callFrames && callFrames.length)
356 this._pausedScript(
357 callFrames, this._debuggerPausedDetails.reason, this._debuggerPausedDe tails.auxData,
358 this._debuggerPausedDetails.breakpointIds, asyncStackTrace);
359 callback(error, exceptionDetails);
360 }
361
362 /**
363 * @return {?Array.<!WebInspector.DebuggerModel.CallFrame>}
364 */
365 get callFrames() {
366 return this._debuggerPausedDetails ? this._debuggerPausedDetails.callFrames : null;
367 }
368
369 /**
370 * @return {?WebInspector.DebuggerPausedDetails}
371 */
372 debuggerPausedDetails() {
373 return this._debuggerPausedDetails;
374 }
375
376 /**
377 * @param {?WebInspector.DebuggerPausedDetails} debuggerPausedDetails
378 * @return {boolean}
379 */
380 _setDebuggerPausedDetails(debuggerPausedDetails) {
381 this._isPausing = false;
382 this._debuggerPausedDetails = debuggerPausedDetails;
383 if (this._debuggerPausedDetails) {
384 if (Runtime.experiments.isEnabled('emptySourceMapAutoStepping')) {
385 if (this.dispatchEventToListeners(
386 WebInspector.DebuggerModel.Events.BeforeDebuggerPaused, this._de buggerPausedDetails)) {
387 return false;
388 }
389 }
390 this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerPa used, this._debuggerPausedDetails);
391 }
392 if (debuggerPausedDetails)
393 this.setSelectedCallFrame(debuggerPausedDetails.callFrames[0]);
394 else
395 this.setSelectedCallFrame(null);
396 return true;
397 }
398
399 /**
400 * @param {!Array.<!DebuggerAgent.CallFrame>} callFrames
401 * @param {string} reason
402 * @param {!Object|undefined} auxData
403 * @param {!Array.<string>} breakpointIds
404 * @param {!RuntimeAgent.StackTrace=} asyncStackTrace
405 */
406 _pausedScript(callFrames, reason, auxData, breakpointIds, asyncStackTrace) {
407 var pausedDetails =
408 new WebInspector.DebuggerPausedDetails(this, callFrames, reason, auxData , breakpointIds, asyncStackTrace);
409 if (this._setDebuggerPausedDetails(pausedDetails)) {
410 if (this._pendingLiveEditCallback) {
411 var callback = this._pendingLiveEditCallback;
412 delete this._pendingLiveEditCallback;
413 callback();
414 }
415 } else {
416 this._agent.stepInto();
417 }
418 }
419
420 _resumedScript() {
421 this._setDebuggerPausedDetails(null);
422 this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerResu med);
423 }
424
425 /**
426 * @param {!RuntimeAgent.ScriptId} scriptId
427 * @param {string} sourceURL
428 * @param {number} startLine
429 * @param {number} startColumn
430 * @param {number} endLine
431 * @param {number} endColumn
432 * @param {!RuntimeAgent.ExecutionContextId} executionContextId
433 * @param {string} hash
434 * @param {*|undefined} executionContextAuxData
435 * @param {boolean} isLiveEdit
436 * @param {string=} sourceMapURL
437 * @param {boolean=} hasSourceURL
438 * @param {boolean=} hasSyntaxError
439 * @return {!WebInspector.Script}
440 */
441 _parsedScriptSource(
442 scriptId,
443 sourceURL,
444 startLine,
445 startColumn,
446 endLine,
447 endColumn,
448 executionContextId,
449 hash,
450 executionContextAuxData,
451 isLiveEdit,
452 sourceMapURL,
453 hasSourceURL,
454 hasSyntaxError) {
455 var isContentScript = false;
456 if (executionContextAuxData && ('isDefault' in executionContextAuxData))
457 isContentScript = !executionContextAuxData['isDefault'];
458 // Support file URL for node.js.
459 if (this.target().isNodeJS() && sourceURL && sourceURL.startsWith('/'))
460 sourceURL = WebInspector.ParsedURL.platformPathToURL(sourceURL);
461 var script = new WebInspector.Script(
462 this, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, e xecutionContextId, hash,
463 isContentScript, isLiveEdit, sourceMapURL, hasSourceURL);
464 this._registerScript(script);
465 if (!hasSyntaxError)
466 this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ParsedScri ptSource, script);
467 else
468 this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.FailedToPa rseScriptSource, script);
469 return script;
470 }
471
472 /**
473 * @param {!WebInspector.Script} script
474 */
475 _registerScript(script) {
476 this._scripts[script.scriptId] = script;
477 if (script.isAnonymousScript())
478 return;
479
480 var scripts = this._scriptsBySourceURL.get(script.sourceURL);
481 if (!scripts) {
482 scripts = [];
483 this._scriptsBySourceURL.set(script.sourceURL, scripts);
484 }
485 scripts.push(script);
486 }
487
488 /**
489 * @param {!WebInspector.Script} script
490 * @param {number} lineNumber
491 * @param {number} columnNumber
492 * @return {?WebInspector.DebuggerModel.Location}
493 */
494 createRawLocation(script, lineNumber, columnNumber) {
495 if (script.sourceURL)
496 return this.createRawLocationByURL(script.sourceURL, lineNumber, columnNum ber);
497 return new WebInspector.DebuggerModel.Location(this, script.scriptId, lineNu mber, columnNumber);
498 }
499
500 /**
501 * @param {string} sourceURL
502 * @param {number} lineNumber
503 * @param {number} columnNumber
504 * @return {?WebInspector.DebuggerModel.Location}
505 */
506 createRawLocationByURL(sourceURL, lineNumber, columnNumber) {
507 var closestScript = null;
508 var scripts = this._scriptsBySourceURL.get(sourceURL) || [];
509 for (var i = 0, l = scripts.length; i < l; ++i) {
510 var script = scripts[i];
511 if (!closestScript)
512 closestScript = script;
513 if (script.lineOffset > lineNumber || (script.lineOffset === lineNumber && script.columnOffset > columnNumber))
514 continue;
515 if (script.endLine < lineNumber || (script.endLine === lineNumber && scrip t.endColumn <= columnNumber))
516 continue;
517 closestScript = script;
518 break;
519 }
520 return closestScript ?
521 new WebInspector.DebuggerModel.Location(this, closestScript.scriptId, li neNumber, columnNumber) :
522 null;
523 }
524
525 /**
526 * @param {!RuntimeAgent.ScriptId} scriptId
527 * @param {number} lineNumber
528 * @param {number} columnNumber
529 * @return {?WebInspector.DebuggerModel.Location}
530 */
531 createRawLocationByScriptId(scriptId, lineNumber, columnNumber) {
532 var script = this.scriptForId(scriptId);
533 return script ? this.createRawLocation(script, lineNumber, columnNumber) : n ull;
534 }
535
536 /**
537 * @param {!RuntimeAgent.StackTrace} stackTrace
538 * @return {!Array<!WebInspector.DebuggerModel.Location>}
539 */
540 createRawLocationsByStackTrace(stackTrace) {
541 var frames = [];
542 while (stackTrace) {
543 for (var frame of stackTrace.callFrames)
544 frames.push(frame);
545 stackTrace = stackTrace.parent;
546 }
547
548 var rawLocations = [];
549 for (var frame of frames) {
550 var rawLocation = this.createRawLocationByScriptId(frame.scriptId, frame.l ineNumber, frame.columnNumber);
551 if (rawLocation)
552 rawLocations.push(rawLocation);
553 }
554 return rawLocations;
555 }
556
557 /**
558 * @return {boolean}
559 */
560 isPaused() {
561 return !!this.debuggerPausedDetails();
562 }
563
564 /**
565 * @return {boolean}
566 */
567 isPausing() {
568 return this._isPausing;
569 }
570
571 /**
572 * @param {?WebInspector.DebuggerModel.CallFrame} callFrame
573 */
574 setSelectedCallFrame(callFrame) {
575 this._selectedCallFrame = callFrame;
576 if (!this._selectedCallFrame)
577 return;
578
579 this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.CallFrameSel ected, callFrame);
580 }
581
582 /**
583 * @return {?WebInspector.DebuggerModel.CallFrame}
584 */
585 selectedCallFrame() {
586 return this._selectedCallFrame;
587 }
588
589 /**
590 * @param {string} code
591 * @param {string} objectGroup
592 * @param {boolean} includeCommandLineAPI
593 * @param {boolean} silent
594 * @param {boolean} returnByValue
595 * @param {boolean} generatePreview
596 * @param {function(?WebInspector.RemoteObject, !RuntimeAgent.ExceptionDetails =)} callback
597 */
598 evaluateOnSelectedCallFrame(
599 code,
600 objectGroup,
601 includeCommandLineAPI,
602 silent,
603 returnByValue,
604 generatePreview,
605 callback) {
606 /**
607 * @param {?RuntimeAgent.RemoteObject} result
608 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails
609 * @this {WebInspector.DebuggerModel}
610 */
611 function didEvaluate(result, exceptionDetails) {
612 if (!result)
613 callback(null);
614 else
615 callback(this.target().runtimeModel.createRemoteObject(result), exceptio nDetails);
616 }
617
618 this.selectedCallFrame().evaluate(
619 code, objectGroup, includeCommandLineAPI, silent, returnByValue, generat ePreview, didEvaluate.bind(this));
620 }
621
622 /**
623 * @param {!WebInspector.RemoteObject} remoteObject
624 * @return {!Promise<?WebInspector.DebuggerModel.FunctionDetails>}
625 */
626 functionDetailsPromise(remoteObject) {
627 return remoteObject.getAllPropertiesPromise(/* accessorPropertiesOnly */ fal se).then(buildDetails.bind(this));
628
629 /**
630 * @param {!{properties: ?Array.<!WebInspector.RemoteObjectProperty>, intern alProperties: ?Array.<!WebInspector.RemoteObjectProperty>}} response
631 * @return {?WebInspector.DebuggerModel.FunctionDetails}
632 * @this {!WebInspector.DebuggerModel}
633 */
634 function buildDetails(response) {
635 if (!response)
636 return null;
637 var location = null;
638 if (response.internalProperties) {
639 for (var prop of response.internalProperties) {
640 if (prop.name === '[[FunctionLocation]]')
641 location = prop.value;
642 }
643 }
644 var functionName = null;
645 if (response.properties) {
646 for (var prop of response.properties) {
647 if (prop.name === 'name' && prop.value && prop.value.type === 'string' )
648 functionName = prop.value;
649 if (prop.name === 'displayName' && prop.value && prop.value.type === ' string') {
650 functionName = prop.value;
651 break;
652 }
653 }
654 }
655 var debuggerLocation = null;
656 if (location)
657 debuggerLocation = this.createRawLocationByScriptId(
658 location.value.scriptId, location.value.lineNumber, location.value.c olumnNumber);
659 return {location: debuggerLocation, functionName: functionName ? functionN ame.value : ''};
660 }
661 }
662
663 /**
664 * @param {number} scopeNumber
665 * @param {string} variableName
666 * @param {!RuntimeAgent.CallArgument} newValue
667 * @param {string} callFrameId
668 * @param {function(string=)=} callback
669 */
670 setVariableValue(scopeNumber, variableName, newValue, callFrameId, callback) {
671 this._agent.setVariableValue(scopeNumber, variableName, newValue, callFrameI d, innerCallback);
672
673 /**
674 * @param {?Protocol.Error} error
675 */
676 function innerCallback(error) {
677 if (error) {
678 console.error(error);
679 if (callback)
680 callback(error);
681 return;
682 }
683 if (callback)
684 callback();
685 }
686 }
687
688 /**
689 * @param {!DebuggerAgent.BreakpointId} breakpointId
690 * @param {function(!WebInspector.Event)} listener
691 * @param {!Object=} thisObject
692 */
693 addBreakpointListener(breakpointId, listener, thisObject) {
694 this._breakpointResolvedEventTarget.addEventListener(breakpointId, listener, thisObject);
695 }
696
697 /**
698 * @param {!DebuggerAgent.BreakpointId} breakpointId
699 * @param {function(!WebInspector.Event)} listener
700 * @param {!Object=} thisObject
701 */
702 removeBreakpointListener(breakpointId, listener, thisObject) {
703 this._breakpointResolvedEventTarget.removeEventListener(breakpointId, listen er, thisObject);
704 }
705
706 /**
707 * @param {!Array<string>} patterns
708 * @return {!Promise<boolean>}
709 */
710 setBlackboxPatterns(patterns) {
711 var callback;
712 var promise = new Promise(fulfill => callback = fulfill);
713 this._agent.setBlackboxPatterns(patterns, patternsUpdated);
714 return promise;
715
716 /**
717 * @param {?Protocol.Error} error
718 */
719 function patternsUpdated(error) {
720 if (error)
721 console.error(error);
722 callback(!error);
723 }
724 }
725
726 /**
727 * @override
728 */
729 dispose() {
730 WebInspector.moduleSetting('pauseOnExceptionEnabled')
731 .removeChangeListener(this._pauseOnExceptionStateChanged, this);
732 WebInspector.moduleSetting('pauseOnCaughtException').removeChangeListener(th is._pauseOnExceptionStateChanged, this);
733 WebInspector.moduleSetting('enableAsyncStackTraces').removeChangeListener(th is.asyncStackTracesStateChanged, this);
734 }
735
736 /**
737 * @override
738 * @return {!Promise}
739 */
740 suspendModel() {
741 return new Promise(promiseBody.bind(this));
742
743 /**
744 * @param {function()} fulfill
745 * @this {WebInspector.DebuggerModel}
746 */
747 function promiseBody(fulfill) {
748 this.disableDebugger(fulfill);
749 }
750 }
751
752 /**
753 * @override
754 * @return {!Promise}
755 */
756 resumeModel() {
757 return new Promise(promiseBody.bind(this));
758
759 /**
760 * @param {function()} fulfill
761 * @this {WebInspector.DebuggerModel}
762 */
763 function promiseBody(fulfill) {
764 this.enableDebugger(fulfill);
765 }
766 }
59 }; 767 };
60 768
61 /** @typedef {{location: ?WebInspector.DebuggerModel.Location, functionName: str ing}} */ 769 /** @typedef {{location: ?WebInspector.DebuggerModel.Location, functionName: str ing}} */
62 WebInspector.DebuggerModel.FunctionDetails; 770 WebInspector.DebuggerModel.FunctionDetails;
63 771
64 /** 772 /**
65 * Keep these in sync with WebCore::V8Debugger 773 * Keep these in sync with WebCore::V8Debugger
66 * 774 *
67 * @enum {string} 775 * @enum {string}
68 */ 776 */
69 WebInspector.DebuggerModel.PauseOnExceptionsState = { 777 WebInspector.DebuggerModel.PauseOnExceptionsState = {
70 DontPauseOnExceptions : "none", 778 DontPauseOnExceptions: 'none',
71 PauseOnAllExceptions : "all", 779 PauseOnAllExceptions: 'all',
72 PauseOnUncaughtExceptions: "uncaught" 780 PauseOnUncaughtExceptions: 'uncaught'
73 }; 781 };
74 782
75 /** @enum {symbol} */ 783 /** @enum {symbol} */
76 WebInspector.DebuggerModel.Events = { 784 WebInspector.DebuggerModel.Events = {
77 DebuggerWasEnabled: Symbol("DebuggerWasEnabled"), 785 DebuggerWasEnabled: Symbol('DebuggerWasEnabled'),
78 DebuggerWasDisabled: Symbol("DebuggerWasDisabled"), 786 DebuggerWasDisabled: Symbol('DebuggerWasDisabled'),
79 BeforeDebuggerPaused: Symbol("BeforeDebuggerPaused"), 787 BeforeDebuggerPaused: Symbol('BeforeDebuggerPaused'),
80 DebuggerPaused: Symbol("DebuggerPaused"), 788 DebuggerPaused: Symbol('DebuggerPaused'),
81 DebuggerResumed: Symbol("DebuggerResumed"), 789 DebuggerResumed: Symbol('DebuggerResumed'),
82 ParsedScriptSource: Symbol("ParsedScriptSource"), 790 ParsedScriptSource: Symbol('ParsedScriptSource'),
83 FailedToParseScriptSource: Symbol("FailedToParseScriptSource"), 791 FailedToParseScriptSource: Symbol('FailedToParseScriptSource'),
84 GlobalObjectCleared: Symbol("GlobalObjectCleared"), 792 GlobalObjectCleared: Symbol('GlobalObjectCleared'),
85 CallFrameSelected: Symbol("CallFrameSelected"), 793 CallFrameSelected: Symbol('CallFrameSelected'),
86 ConsoleCommandEvaluatedInSelectedCallFrame: Symbol("ConsoleCommandEvaluatedI nSelectedCallFrame") 794 ConsoleCommandEvaluatedInSelectedCallFrame: Symbol('ConsoleCommandEvaluatedInS electedCallFrame')
87 }; 795 };
88 796
89 /** @enum {string} */ 797 /** @enum {string} */
90 WebInspector.DebuggerModel.BreakReason = { 798 WebInspector.DebuggerModel.BreakReason = {
91 DOM: "DOM", 799 DOM: 'DOM',
92 EventListener: "EventListener", 800 EventListener: 'EventListener',
93 XHR: "XHR", 801 XHR: 'XHR',
94 Exception: "exception", 802 Exception: 'exception',
95 PromiseRejection: "promiseRejection", 803 PromiseRejection: 'promiseRejection',
96 Assert: "assert", 804 Assert: 'assert',
97 DebugCommand: "debugCommand", 805 DebugCommand: 'debugCommand',
98 Other: "other" 806 Other: 'other'
99 }; 807 };
100 808
101 WebInspector.DebuggerModel.prototype = { 809 WebInspector.DebuggerEventTypes = {
102 /** 810 JavaScriptPause: 0,
103 * @return {boolean} 811 JavaScriptBreakpoint: 1,
104 */ 812 NativeBreakpoint: 2
105 debuggerEnabled: function()
106 {
107 return !!this._debuggerEnabled;
108 },
109
110 /**
111 * @param {function()=} callback
112 */
113 enableDebugger: function(callback)
114 {
115 if (this._debuggerEnabled) {
116 if (callback)
117 callback();
118 return;
119 }
120 this._agent.enable(callback);
121 this._debuggerEnabled = true;
122 this._pauseOnExceptionStateChanged();
123 this.asyncStackTracesStateChanged();
124 this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.Debugger WasEnabled);
125 },
126
127 /**
128 * @param {function()=} callback
129 */
130 disableDebugger: function(callback)
131 {
132 if (!this._debuggerEnabled) {
133 if (callback)
134 callback();
135 return;
136 }
137
138 this._agent.disable(callback);
139 this._debuggerEnabled = false;
140 this._isPausing = false;
141 this.asyncStackTracesStateChanged();
142 this.globalObjectCleared();
143 this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.Debugger WasDisabled);
144 },
145
146 /**
147 * @param {boolean} skip
148 */
149 _skipAllPauses: function(skip)
150 {
151 if (this._skipAllPausesTimeout) {
152 clearTimeout(this._skipAllPausesTimeout);
153 delete this._skipAllPausesTimeout;
154 }
155 this._agent.setSkipAllPauses(skip);
156 },
157
158 /**
159 * @param {number} timeout
160 */
161 skipAllPausesUntilReloadOrTimeout: function(timeout)
162 {
163 if (this._skipAllPausesTimeout)
164 clearTimeout(this._skipAllPausesTimeout);
165 this._agent.setSkipAllPauses(true);
166 // If reload happens before the timeout, the flag will be already unset and the timeout callback won't change anything.
167 this._skipAllPausesTimeout = setTimeout(this._skipAllPauses.bind(this, f alse), timeout);
168 },
169
170 _pauseOnExceptionStateChanged: function()
171 {
172 var state;
173 if (!WebInspector.moduleSetting("pauseOnExceptionEnabled").get()) {
174 state = WebInspector.DebuggerModel.PauseOnExceptionsState.DontPauseO nExceptions;
175 } else if (WebInspector.moduleSetting("pauseOnCaughtException").get()) {
176 state = WebInspector.DebuggerModel.PauseOnExceptionsState.PauseOnAll Exceptions;
177 } else {
178 state = WebInspector.DebuggerModel.PauseOnExceptionsState.PauseOnUnc aughtExceptions;
179 }
180 this._agent.setPauseOnExceptions(state);
181 },
182
183 asyncStackTracesStateChanged: function()
184 {
185 const maxAsyncStackChainDepth = 4;
186 var enabled = WebInspector.moduleSetting("enableAsyncStackTraces").get() && this._debuggerEnabled;
187 this._agent.setAsyncCallStackDepth(enabled ? maxAsyncStackChainDepth : 0 );
188 },
189
190 stepInto: function()
191 {
192 this._agent.stepInto();
193 },
194
195 stepOver: function()
196 {
197 this._agent.stepOver();
198 },
199
200 stepOut: function()
201 {
202 this._agent.stepOut();
203 },
204
205 resume: function()
206 {
207 this._agent.resume();
208 this._isPausing = false;
209 },
210
211 pause: function()
212 {
213 this._isPausing = true;
214 this._skipAllPauses(false);
215 this._agent.pause();
216 },
217
218 /**
219 * @param {boolean} active
220 */
221 setBreakpointsActive: function(active)
222 {
223 this._agent.setBreakpointsActive(active);
224 },
225
226 /**
227 * @param {string} url
228 * @param {number} lineNumber
229 * @param {number=} columnNumber
230 * @param {string=} condition
231 * @param {function(?DebuggerAgent.BreakpointId, !Array.<!WebInspector.Debug gerModel.Location>)=} callback
232 */
233 setBreakpointByURL: function(url, lineNumber, columnNumber, condition, callb ack)
234 {
235 // Adjust column if needed.
236 var minColumnNumber = 0;
237 var scripts = this._scriptsBySourceURL.get(url) || [];
238 for (var i = 0, l = scripts.length; i < l; ++i) {
239 var script = scripts[i];
240 if (lineNumber === script.lineOffset)
241 minColumnNumber = minColumnNumber ? Math.min(minColumnNumber, sc ript.columnOffset) : script.columnOffset;
242 }
243 columnNumber = Math.max(columnNumber, minColumnNumber);
244
245 var target = this.target();
246 /**
247 * @param {?Protocol.Error} error
248 * @param {!DebuggerAgent.BreakpointId} breakpointId
249 * @param {!Array.<!DebuggerAgent.Location>} locations
250 * @this {WebInspector.DebuggerModel}
251 */
252 function didSetBreakpoint(error, breakpointId, locations)
253 {
254 if (callback) {
255 var rawLocations = locations ? locations.map(WebInspector.Debugg erModel.Location.fromPayload.bind(WebInspector.DebuggerModel.Location, this)) : [];
256 callback(error ? null : breakpointId, rawLocations);
257 }
258 }
259 this._agent.setBreakpointByUrl(lineNumber, url, undefined, columnNumber, condition, didSetBreakpoint.bind(this));
260 },
261
262 /**
263 * @param {!WebInspector.DebuggerModel.Location} rawLocation
264 * @param {string} condition
265 * @param {function(?DebuggerAgent.BreakpointId, !Array.<!WebInspector.Debug gerModel.Location>)=} callback
266 */
267 setBreakpointBySourceId: function(rawLocation, condition, callback)
268 {
269 var target = this.target();
270
271 /**
272 * @this {WebInspector.DebuggerModel}
273 * @param {?Protocol.Error} error
274 * @param {!DebuggerAgent.BreakpointId} breakpointId
275 * @param {!DebuggerAgent.Location} actualLocation
276 */
277 function didSetBreakpoint(error, breakpointId, actualLocation)
278 {
279 if (callback) {
280 if (error || !actualLocation) {
281 callback(null, []);
282 return;
283 }
284 callback(breakpointId, [WebInspector.DebuggerModel.Location.from Payload(this, actualLocation)]);
285 }
286 }
287 this._agent.setBreakpoint(rawLocation.payload(), condition, didSetBreakp oint.bind(this));
288 },
289
290 /**
291 * @param {!DebuggerAgent.BreakpointId} breakpointId
292 * @param {function()=} callback
293 */
294 removeBreakpoint: function(breakpointId, callback)
295 {
296 this._agent.removeBreakpoint(breakpointId, innerCallback);
297
298 /**
299 * @param {?Protocol.Error} error
300 */
301 function innerCallback(error)
302 {
303 if (error)
304 console.error("Failed to remove breakpoint: " + error);
305 if (callback)
306 callback();
307 }
308 },
309
310 /**
311 * @param {!DebuggerAgent.BreakpointId} breakpointId
312 * @param {!DebuggerAgent.Location} location
313 */
314 _breakpointResolved: function(breakpointId, location)
315 {
316 this._breakpointResolvedEventTarget.dispatchEventToListeners(breakpointI d, WebInspector.DebuggerModel.Location.fromPayload(this, location));
317 },
318
319 globalObjectCleared: function()
320 {
321 this._setDebuggerPausedDetails(null);
322 this._reset();
323 // TODO(dgozman): move clients to ExecutionContextDestroyed/ScriptCollec ted events.
324 this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.GlobalOb jectCleared);
325 },
326
327 _reset: function()
328 {
329 this._scripts = {};
330 this._scriptsBySourceURL.clear();
331 },
332
333 /**
334 * @return {!Object.<string, !WebInspector.Script>}
335 */
336 get scripts()
337 {
338 return this._scripts;
339 },
340
341 /**
342 * @param {!RuntimeAgent.ScriptId} scriptId
343 * @return {?WebInspector.Script}
344 */
345 scriptForId: function(scriptId)
346 {
347 return this._scripts[scriptId] || null;
348 },
349
350 /**
351 * @return {!Array.<!WebInspector.Script>}
352 */
353 scriptsForSourceURL: function(sourceURL)
354 {
355 if (!sourceURL)
356 return [];
357 return this._scriptsBySourceURL.get(sourceURL) || [];
358 },
359
360 /**
361 * @param {!RuntimeAgent.ScriptId} scriptId
362 * @param {string} newSource
363 * @param {function(?Protocol.Error, !RuntimeAgent.ExceptionDetails=)} callb ack
364 */
365 setScriptSource: function(scriptId, newSource, callback)
366 {
367 this._scripts[scriptId].editSource(newSource, this._didEditScriptSource. bind(this, scriptId, newSource, callback));
368 },
369
370 /**
371 * @param {!RuntimeAgent.ScriptId} scriptId
372 * @param {string} newSource
373 * @param {function(?Protocol.Error, !RuntimeAgent.ExceptionDetails=)} callb ack
374 * @param {?Protocol.Error} error
375 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails
376 * @param {!Array.<!DebuggerAgent.CallFrame>=} callFrames
377 * @param {!RuntimeAgent.StackTrace=} asyncStackTrace
378 * @param {boolean=} needsStepIn
379 */
380 _didEditScriptSource: function(scriptId, newSource, callback, error, excepti onDetails, callFrames, asyncStackTrace, needsStepIn)
381 {
382 if (needsStepIn) {
383 this.stepInto();
384 this._pendingLiveEditCallback = callback.bind(this, error, exception Details);
385 return;
386 }
387
388 if (!error && callFrames && callFrames.length)
389 this._pausedScript(callFrames, this._debuggerPausedDetails.reason, t his._debuggerPausedDetails.auxData, this._debuggerPausedDetails.breakpointIds, a syncStackTrace);
390 callback(error, exceptionDetails);
391 },
392
393 /**
394 * @return {?Array.<!WebInspector.DebuggerModel.CallFrame>}
395 */
396 get callFrames()
397 {
398 return this._debuggerPausedDetails ? this._debuggerPausedDetails.callFra mes : null;
399 },
400
401 /**
402 * @return {?WebInspector.DebuggerPausedDetails}
403 */
404 debuggerPausedDetails: function()
405 {
406 return this._debuggerPausedDetails;
407 },
408
409 /**
410 * @param {?WebInspector.DebuggerPausedDetails} debuggerPausedDetails
411 * @return {boolean}
412 */
413 _setDebuggerPausedDetails: function(debuggerPausedDetails)
414 {
415 this._isPausing = false;
416 this._debuggerPausedDetails = debuggerPausedDetails;
417 if (this._debuggerPausedDetails) {
418 if (Runtime.experiments.isEnabled("emptySourceMapAutoStepping")) {
419 if (this.dispatchEventToListeners(WebInspector.DebuggerModel.Eve nts.BeforeDebuggerPaused, this._debuggerPausedDetails)) {
420 return false;
421 }
422 }
423 this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.Debu ggerPaused, this._debuggerPausedDetails);
424 }
425 if (debuggerPausedDetails)
426 this.setSelectedCallFrame(debuggerPausedDetails.callFrames[0]);
427 else
428 this.setSelectedCallFrame(null);
429 return true;
430 },
431
432 /**
433 * @param {!Array.<!DebuggerAgent.CallFrame>} callFrames
434 * @param {string} reason
435 * @param {!Object|undefined} auxData
436 * @param {!Array.<string>} breakpointIds
437 * @param {!RuntimeAgent.StackTrace=} asyncStackTrace
438 */
439 _pausedScript: function(callFrames, reason, auxData, breakpointIds, asyncSta ckTrace)
440 {
441 var pausedDetails = new WebInspector.DebuggerPausedDetails(this, callFra mes, reason, auxData, breakpointIds, asyncStackTrace);
442 if (this._setDebuggerPausedDetails(pausedDetails)) {
443 if (this._pendingLiveEditCallback) {
444 var callback = this._pendingLiveEditCallback;
445 delete this._pendingLiveEditCallback;
446 callback();
447 }
448 } else {
449 this._agent.stepInto();
450 }
451 },
452
453 _resumedScript: function()
454 {
455 this._setDebuggerPausedDetails(null);
456 this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.Debugger Resumed);
457 },
458
459 /**
460 * @param {!RuntimeAgent.ScriptId} scriptId
461 * @param {string} sourceURL
462 * @param {number} startLine
463 * @param {number} startColumn
464 * @param {number} endLine
465 * @param {number} endColumn
466 * @param {!RuntimeAgent.ExecutionContextId} executionContextId
467 * @param {string} hash
468 * @param {*|undefined} executionContextAuxData
469 * @param {boolean} isLiveEdit
470 * @param {string=} sourceMapURL
471 * @param {boolean=} hasSourceURL
472 * @param {boolean=} hasSyntaxError
473 * @return {!WebInspector.Script}
474 */
475 _parsedScriptSource: function(scriptId, sourceURL, startLine, startColumn, e ndLine, endColumn, executionContextId, hash, executionContextAuxData, isLiveEdit , sourceMapURL, hasSourceURL, hasSyntaxError)
476 {
477 var isContentScript = false;
478 if (executionContextAuxData && ("isDefault" in executionContextAuxData))
479 isContentScript = !executionContextAuxData["isDefault"];
480 // Support file URL for node.js.
481 if (this.target().isNodeJS() && sourceURL && sourceURL.startsWith("/"))
482 sourceURL = WebInspector.ParsedURL.platformPathToURL(sourceURL);
483 var script = new WebInspector.Script(this, scriptId, sourceURL, startLin e, startColumn, endLine, endColumn, executionContextId, hash, isContentScript, i sLiveEdit, sourceMapURL, hasSourceURL);
484 this._registerScript(script);
485 if (!hasSyntaxError)
486 this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.Pars edScriptSource, script);
487 else
488 this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.Fail edToParseScriptSource, script);
489 return script;
490 },
491
492 /**
493 * @param {!WebInspector.Script} script
494 */
495 _registerScript: function(script)
496 {
497 this._scripts[script.scriptId] = script;
498 if (script.isAnonymousScript())
499 return;
500
501 var scripts = this._scriptsBySourceURL.get(script.sourceURL);
502 if (!scripts) {
503 scripts = [];
504 this._scriptsBySourceURL.set(script.sourceURL, scripts);
505 }
506 scripts.push(script);
507 },
508
509 /**
510 * @param {!WebInspector.Script} script
511 * @param {number} lineNumber
512 * @param {number} columnNumber
513 * @return {?WebInspector.DebuggerModel.Location}
514 */
515 createRawLocation: function(script, lineNumber, columnNumber)
516 {
517 if (script.sourceURL)
518 return this.createRawLocationByURL(script.sourceURL, lineNumber, col umnNumber);
519 return new WebInspector.DebuggerModel.Location(this, script.scriptId, li neNumber, columnNumber);
520 },
521
522 /**
523 * @param {string} sourceURL
524 * @param {number} lineNumber
525 * @param {number} columnNumber
526 * @return {?WebInspector.DebuggerModel.Location}
527 */
528 createRawLocationByURL: function(sourceURL, lineNumber, columnNumber)
529 {
530 var closestScript = null;
531 var scripts = this._scriptsBySourceURL.get(sourceURL) || [];
532 for (var i = 0, l = scripts.length; i < l; ++i) {
533 var script = scripts[i];
534 if (!closestScript)
535 closestScript = script;
536 if (script.lineOffset > lineNumber || (script.lineOffset === lineNum ber && script.columnOffset > columnNumber))
537 continue;
538 if (script.endLine < lineNumber || (script.endLine === lineNumber && script.endColumn <= columnNumber))
539 continue;
540 closestScript = script;
541 break;
542 }
543 return closestScript ? new WebInspector.DebuggerModel.Location(this, clo sestScript.scriptId, lineNumber, columnNumber) : null;
544 },
545
546 /**
547 * @param {!RuntimeAgent.ScriptId} scriptId
548 * @param {number} lineNumber
549 * @param {number} columnNumber
550 * @return {?WebInspector.DebuggerModel.Location}
551 */
552 createRawLocationByScriptId: function(scriptId, lineNumber, columnNumber)
553 {
554 var script = this.scriptForId(scriptId);
555 return script ? this.createRawLocation(script, lineNumber, columnNumber) : null;
556 },
557
558 /**
559 * @param {!RuntimeAgent.StackTrace} stackTrace
560 * @return {!Array<!WebInspector.DebuggerModel.Location>}
561 */
562 createRawLocationsByStackTrace: function(stackTrace)
563 {
564 var frames = [];
565 while (stackTrace) {
566 for (var frame of stackTrace.callFrames)
567 frames.push(frame);
568 stackTrace = stackTrace.parent;
569 }
570
571 var rawLocations = [];
572 for (var frame of frames) {
573 var rawLocation = this.createRawLocationByScriptId(frame.scriptId, f rame.lineNumber, frame.columnNumber);
574 if (rawLocation)
575 rawLocations.push(rawLocation);
576 }
577 return rawLocations;
578 },
579
580 /**
581 * @return {boolean}
582 */
583 isPaused: function()
584 {
585 return !!this.debuggerPausedDetails();
586 },
587
588 /**
589 * @return {boolean}
590 */
591 isPausing: function()
592 {
593 return this._isPausing;
594 },
595
596 /**
597 * @param {?WebInspector.DebuggerModel.CallFrame} callFrame
598 */
599 setSelectedCallFrame: function(callFrame)
600 {
601 this._selectedCallFrame = callFrame;
602 if (!this._selectedCallFrame)
603 return;
604
605 this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.CallFram eSelected, callFrame);
606 },
607
608 /**
609 * @return {?WebInspector.DebuggerModel.CallFrame}
610 */
611 selectedCallFrame: function()
612 {
613 return this._selectedCallFrame;
614 },
615
616 /**
617 * @param {string} code
618 * @param {string} objectGroup
619 * @param {boolean} includeCommandLineAPI
620 * @param {boolean} silent
621 * @param {boolean} returnByValue
622 * @param {boolean} generatePreview
623 * @param {function(?WebInspector.RemoteObject, !RuntimeAgent.ExceptionDetai ls=)} callback
624 */
625 evaluateOnSelectedCallFrame: function(code, objectGroup, includeCommandLineA PI, silent, returnByValue, generatePreview, callback)
626 {
627 /**
628 * @param {?RuntimeAgent.RemoteObject} result
629 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails
630 * @this {WebInspector.DebuggerModel}
631 */
632 function didEvaluate(result, exceptionDetails)
633 {
634 if (!result)
635 callback(null);
636 else
637 callback(this.target().runtimeModel.createRemoteObject(result), exceptionDetails);
638 }
639
640 this.selectedCallFrame().evaluate(code, objectGroup, includeCommandLineA PI, silent, returnByValue, generatePreview, didEvaluate.bind(this));
641 },
642
643 /**
644 * @param {!WebInspector.RemoteObject} remoteObject
645 * @return {!Promise<?WebInspector.DebuggerModel.FunctionDetails>}
646 */
647 functionDetailsPromise: function(remoteObject)
648 {
649 return remoteObject.getAllPropertiesPromise(/* accessorPropertiesOnly */ false).then(buildDetails.bind(this));
650
651 /**
652 * @param {!{properties: ?Array.<!WebInspector.RemoteObjectProperty>, in ternalProperties: ?Array.<!WebInspector.RemoteObjectProperty>}} response
653 * @return {?WebInspector.DebuggerModel.FunctionDetails}
654 * @this {!WebInspector.DebuggerModel}
655 */
656 function buildDetails(response)
657 {
658 if (!response)
659 return null;
660 var location = null;
661 if (response.internalProperties) {
662 for (var prop of response.internalProperties) {
663 if (prop.name === "[[FunctionLocation]]")
664 location = prop.value;
665 }
666 }
667 var functionName = null;
668 if (response.properties) {
669 for (var prop of response.properties) {
670 if (prop.name === "name" && prop.value && prop.value.type == = "string")
671 functionName = prop.value;
672 if (prop.name === "displayName" && prop.value && prop.value. type === "string") {
673 functionName = prop.value;
674 break;
675 }
676 }
677 }
678 var debuggerLocation = null;
679 if (location)
680 debuggerLocation = this.createRawLocationByScriptId(location.val ue.scriptId, location.value.lineNumber, location.value.columnNumber);
681 return { location: debuggerLocation, functionName: functionName ? fu nctionName.value : "" };
682 }
683 },
684
685 /**
686 * @param {number} scopeNumber
687 * @param {string} variableName
688 * @param {!RuntimeAgent.CallArgument} newValue
689 * @param {string} callFrameId
690 * @param {function(string=)=} callback
691 */
692 setVariableValue: function(scopeNumber, variableName, newValue, callFrameId, callback)
693 {
694 this._agent.setVariableValue(scopeNumber, variableName, newValue, callFr ameId, innerCallback);
695
696 /**
697 * @param {?Protocol.Error} error
698 */
699 function innerCallback(error)
700 {
701 if (error) {
702 console.error(error);
703 if (callback)
704 callback(error);
705 return;
706 }
707 if (callback)
708 callback();
709 }
710 },
711
712 /**
713 * @param {!DebuggerAgent.BreakpointId} breakpointId
714 * @param {function(!WebInspector.Event)} listener
715 * @param {!Object=} thisObject
716 */
717 addBreakpointListener: function(breakpointId, listener, thisObject)
718 {
719 this._breakpointResolvedEventTarget.addEventListener(breakpointId, liste ner, thisObject);
720 },
721
722 /**
723 * @param {!DebuggerAgent.BreakpointId} breakpointId
724 * @param {function(!WebInspector.Event)} listener
725 * @param {!Object=} thisObject
726 */
727 removeBreakpointListener: function(breakpointId, listener, thisObject)
728 {
729 this._breakpointResolvedEventTarget.removeEventListener(breakpointId, li stener, thisObject);
730 },
731
732 /**
733 * @param {!Array<string>} patterns
734 * @return {!Promise<boolean>}
735 */
736 setBlackboxPatterns: function(patterns)
737 {
738 var callback;
739 var promise = new Promise(fulfill => callback = fulfill);
740 this._agent.setBlackboxPatterns(patterns, patternsUpdated);
741 return promise;
742
743 /**
744 * @param {?Protocol.Error} error
745 */
746 function patternsUpdated(error)
747 {
748 if (error)
749 console.error(error);
750 callback(!error);
751 }
752 },
753
754 dispose: function()
755 {
756 WebInspector.moduleSetting("pauseOnExceptionEnabled").removeChangeListen er(this._pauseOnExceptionStateChanged, this);
757 WebInspector.moduleSetting("pauseOnCaughtException").removeChangeListene r(this._pauseOnExceptionStateChanged, this);
758 WebInspector.moduleSetting("enableAsyncStackTraces").removeChangeListene r(this.asyncStackTracesStateChanged, this);
759 },
760
761 /**
762 * @override
763 * @return {!Promise}
764 */
765 suspendModel: function()
766 {
767 return new Promise(promiseBody.bind(this));
768
769 /**
770 * @param {function()} fulfill
771 * @this {WebInspector.DebuggerModel}
772 */
773 function promiseBody(fulfill)
774 {
775 this.disableDebugger(fulfill);
776 }
777 },
778
779 /**
780 * @override
781 * @return {!Promise}
782 */
783 resumeModel: function()
784 {
785 return new Promise(promiseBody.bind(this));
786
787 /**
788 * @param {function()} fulfill
789 * @this {WebInspector.DebuggerModel}
790 */
791 function promiseBody(fulfill)
792 {
793 this.enableDebugger(fulfill);
794 }
795 },
796
797 __proto__: WebInspector.SDKModel.prototype
798 }; 813 };
799 814
800 WebInspector.DebuggerEventTypes = { 815 /**
801 JavaScriptPause: 0, 816 * @implements {DebuggerAgent.Dispatcher}
802 JavaScriptBreakpoint: 1, 817 * @unrestricted
803 NativeBreakpoint: 2 818 */
819 WebInspector.DebuggerDispatcher = class {
820 /**
821 * @param {!WebInspector.DebuggerModel} debuggerModel
822 */
823 constructor(debuggerModel) {
824 this._debuggerModel = debuggerModel;
825 }
826
827 /**
828 * @override
829 * @param {!Array.<!DebuggerAgent.CallFrame>} callFrames
830 * @param {string} reason
831 * @param {!Object=} auxData
832 * @param {!Array.<string>=} breakpointIds
833 * @param {!RuntimeAgent.StackTrace=} asyncStackTrace
834 */
835 paused(callFrames, reason, auxData, breakpointIds, asyncStackTrace) {
836 this._debuggerModel._pausedScript(callFrames, reason, auxData, breakpointIds || [], asyncStackTrace);
837 }
838
839 /**
840 * @override
841 */
842 resumed() {
843 this._debuggerModel._resumedScript();
844 }
845
846 /**
847 * @override
848 * @param {!RuntimeAgent.ScriptId} scriptId
849 * @param {string} sourceURL
850 * @param {number} startLine
851 * @param {number} startColumn
852 * @param {number} endLine
853 * @param {number} endColumn
854 * @param {!RuntimeAgent.ExecutionContextId} executionContextId
855 * @param {string} hash
856 * @param {*=} executionContextAuxData
857 * @param {boolean=} isLiveEdit
858 * @param {string=} sourceMapURL
859 * @param {boolean=} hasSourceURL
860 */
861 scriptParsed(
862 scriptId,
863 sourceURL,
864 startLine,
865 startColumn,
866 endLine,
867 endColumn,
868 executionContextId,
869 hash,
870 executionContextAuxData,
871 isLiveEdit,
872 sourceMapURL,
873 hasSourceURL) {
874 this._debuggerModel._parsedScriptSource(
875 scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executi onContextId, hash,
876 executionContextAuxData, !!isLiveEdit, sourceMapURL, hasSourceURL, false );
877 }
878
879 /**
880 * @override
881 * @param {!RuntimeAgent.ScriptId} scriptId
882 * @param {string} sourceURL
883 * @param {number} startLine
884 * @param {number} startColumn
885 * @param {number} endLine
886 * @param {number} endColumn
887 * @param {!RuntimeAgent.ExecutionContextId} executionContextId
888 * @param {string} hash
889 * @param {*=} executionContextAuxData
890 * @param {string=} sourceMapURL
891 * @param {boolean=} hasSourceURL
892 */
893 scriptFailedToParse(
894 scriptId,
895 sourceURL,
896 startLine,
897 startColumn,
898 endLine,
899 endColumn,
900 executionContextId,
901 hash,
902 executionContextAuxData,
903 sourceMapURL,
904 hasSourceURL) {
905 this._debuggerModel._parsedScriptSource(
906 scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executi onContextId, hash,
907 executionContextAuxData, false, sourceMapURL, hasSourceURL, true);
908 }
909
910 /**
911 * @override
912 * @param {!DebuggerAgent.BreakpointId} breakpointId
913 * @param {!DebuggerAgent.Location} location
914 */
915 breakpointResolved(breakpointId, location) {
916 this._debuggerModel._breakpointResolved(breakpointId, location);
917 }
804 }; 918 };
805 919
806 /** 920 /**
807 * @constructor 921 * @unrestricted
808 * @implements {DebuggerAgent.Dispatcher}
809 * @param {!WebInspector.DebuggerModel} debuggerModel
810 */ 922 */
811 WebInspector.DebuggerDispatcher = function(debuggerModel) 923 WebInspector.DebuggerModel.Location = class extends WebInspector.SDKObject {
812 { 924 /**
813 this._debuggerModel = debuggerModel; 925 * @param {!WebInspector.DebuggerModel} debuggerModel
814 }; 926 * @param {string} scriptId
815 927 * @param {number} lineNumber
816 WebInspector.DebuggerDispatcher.prototype = { 928 * @param {number=} columnNumber
817 /** 929 */
818 * @override 930 constructor(debuggerModel, scriptId, lineNumber, columnNumber) {
819 * @param {!Array.<!DebuggerAgent.CallFrame>} callFrames 931 super(debuggerModel.target());
820 * @param {string} reason
821 * @param {!Object=} auxData
822 * @param {!Array.<string>=} breakpointIds
823 * @param {!RuntimeAgent.StackTrace=} asyncStackTrace
824 */
825 paused: function(callFrames, reason, auxData, breakpointIds, asyncStackTrace )
826 {
827 this._debuggerModel._pausedScript(callFrames, reason, auxData, breakpoin tIds || [], asyncStackTrace);
828 },
829
830 /**
831 * @override
832 */
833 resumed: function()
834 {
835 this._debuggerModel._resumedScript();
836 },
837
838 /**
839 * @override
840 * @param {!RuntimeAgent.ScriptId} scriptId
841 * @param {string} sourceURL
842 * @param {number} startLine
843 * @param {number} startColumn
844 * @param {number} endLine
845 * @param {number} endColumn
846 * @param {!RuntimeAgent.ExecutionContextId} executionContextId
847 * @param {string} hash
848 * @param {*=} executionContextAuxData
849 * @param {boolean=} isLiveEdit
850 * @param {string=} sourceMapURL
851 * @param {boolean=} hasSourceURL
852 */
853 scriptParsed: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, executionContextAuxData, isLiveEdit, sourc eMapURL, hasSourceURL)
854 {
855 this._debuggerModel._parsedScriptSource(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, executionContextAuxDa ta, !!isLiveEdit, sourceMapURL, hasSourceURL, false);
856 },
857
858 /**
859 * @override
860 * @param {!RuntimeAgent.ScriptId} scriptId
861 * @param {string} sourceURL
862 * @param {number} startLine
863 * @param {number} startColumn
864 * @param {number} endLine
865 * @param {number} endColumn
866 * @param {!RuntimeAgent.ExecutionContextId} executionContextId
867 * @param {string} hash
868 * @param {*=} executionContextAuxData
869 * @param {string=} sourceMapURL
870 * @param {boolean=} hasSourceURL
871 */
872 scriptFailedToParse: function(scriptId, sourceURL, startLine, startColumn, e ndLine, endColumn, executionContextId, hash, executionContextAuxData, sourceMapU RL, hasSourceURL)
873 {
874 this._debuggerModel._parsedScriptSource(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, executionContextAuxDa ta, false, sourceMapURL, hasSourceURL, true);
875 },
876
877 /**
878 * @override
879 * @param {!DebuggerAgent.BreakpointId} breakpointId
880 * @param {!DebuggerAgent.Location} location
881 */
882 breakpointResolved: function(breakpointId, location)
883 {
884 this._debuggerModel._breakpointResolved(breakpointId, location);
885 }
886 };
887
888 /**
889 * @constructor
890 * @extends {WebInspector.SDKObject}
891 * @param {!WebInspector.DebuggerModel} debuggerModel
892 * @param {string} scriptId
893 * @param {number} lineNumber
894 * @param {number=} columnNumber
895 */
896 WebInspector.DebuggerModel.Location = function(debuggerModel, scriptId, lineNumb er, columnNumber)
897 {
898 WebInspector.SDKObject.call(this, debuggerModel.target());
899 this._debuggerModel = debuggerModel; 932 this._debuggerModel = debuggerModel;
900 this.scriptId = scriptId; 933 this.scriptId = scriptId;
901 this.lineNumber = lineNumber; 934 this.lineNumber = lineNumber;
902 this.columnNumber = columnNumber || 0; 935 this.columnNumber = columnNumber || 0;
936 }
937
938 /**
939 * @param {!WebInspector.DebuggerModel} debuggerModel
940 * @param {!DebuggerAgent.Location} payload
941 * @return {!WebInspector.DebuggerModel.Location}
942 */
943 static fromPayload(debuggerModel, payload) {
944 return new WebInspector.DebuggerModel.Location(
945 debuggerModel, payload.scriptId, payload.lineNumber, payload.columnNumbe r);
946 }
947
948 /**
949 * @return {!DebuggerAgent.Location}
950 */
951 payload() {
952 return {scriptId: this.scriptId, lineNumber: this.lineNumber, columnNumber: this.columnNumber};
953 }
954
955 /**
956 * @return {?WebInspector.Script}
957 */
958 script() {
959 return this._debuggerModel.scriptForId(this.scriptId);
960 }
961
962 continueToLocation() {
963 this._debuggerModel._agent.continueToLocation(this.payload());
964 }
965
966 /**
967 * @return {string}
968 */
969 id() {
970 return this.target().id() + ':' + this.scriptId + ':' + this.lineNumber + ': ' + this.columnNumber;
971 }
903 }; 972 };
904 973
974
905 /** 975 /**
906 * @param {!WebInspector.DebuggerModel} debuggerModel 976 * @unrestricted
907 * @param {!DebuggerAgent.Location} payload
908 * @return {!WebInspector.DebuggerModel.Location}
909 */ 977 */
910 WebInspector.DebuggerModel.Location.fromPayload = function(debuggerModel, payloa d) 978 WebInspector.DebuggerModel.CallFrame = class extends WebInspector.SDKObject {
911 { 979 /**
912 return new WebInspector.DebuggerModel.Location(debuggerModel, payload.script Id, payload.lineNumber, payload.columnNumber); 980 * @param {!WebInspector.DebuggerModel} debuggerModel
913 }; 981 * @param {!WebInspector.Script} script
914 982 * @param {!DebuggerAgent.CallFrame} payload
915 WebInspector.DebuggerModel.Location.prototype = { 983 */
916 /** 984 constructor(debuggerModel, script, payload) {
917 * @return {!DebuggerAgent.Location}
918 */
919 payload: function()
920 {
921 return { scriptId: this.scriptId, lineNumber: this.lineNumber, columnNum ber: this.columnNumber };
922 },
923
924 /**
925 * @return {?WebInspector.Script}
926 */
927 script: function()
928 {
929 return this._debuggerModel.scriptForId(this.scriptId);
930 },
931
932 continueToLocation: function()
933 {
934 this._debuggerModel._agent.continueToLocation(this.payload());
935 },
936
937 /**
938 * @return {string}
939 */
940 id: function()
941 {
942 return this.target().id() + ":" + this.scriptId + ":" + this.lineNumber + ":" + this.columnNumber;
943 },
944
945 __proto__: WebInspector.SDKObject.prototype
946 };
947
948 /**
949 * @constructor
950 * @extends {WebInspector.SDKObject}
951 * @param {!WebInspector.DebuggerModel} debuggerModel
952 * @param {!WebInspector.Script} script
953 * @param {!DebuggerAgent.CallFrame} payload
954 */
955 WebInspector.DebuggerModel.CallFrame = function(debuggerModel, script, payload)
956 {
957 var target = debuggerModel.target(); 985 var target = debuggerModel.target();
958 WebInspector.SDKObject.call(this, target); 986 super(target);
959 this.debuggerModel = debuggerModel; 987 this.debuggerModel = debuggerModel;
960 this._debuggerAgent = debuggerModel._agent; 988 this._debuggerAgent = debuggerModel._agent;
961 this._script = script; 989 this._script = script;
962 this._payload = payload; 990 this._payload = payload;
963 this._location = WebInspector.DebuggerModel.Location.fromPayload(debuggerMod el, payload.location); 991 this._location = WebInspector.DebuggerModel.Location.fromPayload(debuggerMod el, payload.location);
964 this._scopeChain = []; 992 this._scopeChain = [];
965 this._localScope = null; 993 this._localScope = null;
966 for (var i = 0; i < payload.scopeChain.length; ++i) { 994 for (var i = 0; i < payload.scopeChain.length; ++i) {
967 var scope = new WebInspector.DebuggerModel.Scope(this, i); 995 var scope = new WebInspector.DebuggerModel.Scope(this, i);
968 this._scopeChain.push(scope); 996 this._scopeChain.push(scope);
969 if (scope.type() === DebuggerAgent.ScopeType.Local) 997 if (scope.type() === DebuggerAgent.ScopeType.Local)
970 this._localScope = scope; 998 this._localScope = scope;
971 } 999 }
972 if (payload.functionLocation) 1000 if (payload.functionLocation)
973 this._functionLocation = WebInspector.DebuggerModel.Location.fromPayload (debuggerModel, payload.functionLocation); 1001 this._functionLocation = WebInspector.DebuggerModel.Location.fromPayload(d ebuggerModel, payload.functionLocation);
974 }; 1002 }
975 1003
976 /** 1004 /**
977 * @param {!WebInspector.DebuggerModel} debuggerModel 1005 * @param {!WebInspector.DebuggerModel} debuggerModel
978 * @param {!Array.<!DebuggerAgent.CallFrame>} callFrames 1006 * @param {!Array.<!DebuggerAgent.CallFrame>} callFrames
979 * @return {!Array.<!WebInspector.DebuggerModel.CallFrame>} 1007 * @return {!Array.<!WebInspector.DebuggerModel.CallFrame>}
980 */ 1008 */
981 WebInspector.DebuggerModel.CallFrame.fromPayloadArray = function(debuggerModel, callFrames) 1009 static fromPayloadArray(debuggerModel, callFrames) {
982 {
983 var result = []; 1010 var result = [];
984 for (var i = 0; i < callFrames.length; ++i) { 1011 for (var i = 0; i < callFrames.length; ++i) {
985 var callFrame = callFrames[i]; 1012 var callFrame = callFrames[i];
986 var script = debuggerModel.scriptForId(callFrame.location.scriptId); 1013 var script = debuggerModel.scriptForId(callFrame.location.scriptId);
987 if (script) 1014 if (script)
988 result.push(new WebInspector.DebuggerModel.CallFrame(debuggerModel, script, callFrame)); 1015 result.push(new WebInspector.DebuggerModel.CallFrame(debuggerModel, scri pt, callFrame));
989 } 1016 }
990 return result; 1017 return result;
1018 }
1019
1020 /**
1021 * @return {!WebInspector.Script}
1022 */
1023 get script() {
1024 return this._script;
1025 }
1026
1027 /**
1028 * @return {string}
1029 */
1030 get id() {
1031 return this._payload.callFrameId;
1032 }
1033
1034 /**
1035 * @return {!Array.<!WebInspector.DebuggerModel.Scope>}
1036 */
1037 scopeChain() {
1038 return this._scopeChain;
1039 }
1040
1041 /**
1042 * @return {?WebInspector.DebuggerModel.Scope}
1043 */
1044 localScope() {
1045 return this._localScope;
1046 }
1047
1048 /**
1049 * @return {?WebInspector.RemoteObject}
1050 */
1051 thisObject() {
1052 return this._payload.this ? this.target().runtimeModel.createRemoteObject(th is._payload.this) : null;
1053 }
1054
1055 /**
1056 * @return {?WebInspector.RemoteObject}
1057 */
1058 returnValue() {
1059 return this._payload.returnValue ? this.target().runtimeModel.createRemoteOb ject(this._payload.returnValue) : null;
1060 }
1061
1062 /**
1063 * @return {string}
1064 */
1065 get functionName() {
1066 return this._payload.functionName;
1067 }
1068
1069 /**
1070 * @return {!WebInspector.DebuggerModel.Location}
1071 */
1072 location() {
1073 return this._location;
1074 }
1075
1076 /**
1077 * @return {?WebInspector.DebuggerModel.Location}
1078 */
1079 functionLocation() {
1080 return this._functionLocation || null;
1081 }
1082
1083 /**
1084 * @param {string} code
1085 * @param {string} objectGroup
1086 * @param {boolean} includeCommandLineAPI
1087 * @param {boolean} silent
1088 * @param {boolean} returnByValue
1089 * @param {boolean} generatePreview
1090 * @param {function(?RuntimeAgent.RemoteObject, !RuntimeAgent.ExceptionDetails =)} callback
1091 */
1092 evaluate(code, objectGroup, includeCommandLineAPI, silent, returnByValue, gene ratePreview, callback) {
1093 /**
1094 * @param {?Protocol.Error} error
1095 * @param {!RuntimeAgent.RemoteObject} result
1096 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails
1097 */
1098 function didEvaluateOnCallFrame(error, result, exceptionDetails) {
1099 if (error) {
1100 console.error(error);
1101 callback(null);
1102 return;
1103 }
1104 callback(result, exceptionDetails);
1105 }
1106 this._debuggerAgent.evaluateOnCallFrame(
1107 this._payload.callFrameId, code, objectGroup, includeCommandLineAPI, sil ent, returnByValue, generatePreview,
1108 didEvaluateOnCallFrame);
1109 }
1110
1111 /**
1112 * @param {function(?Protocol.Error=)=} callback
1113 */
1114 restart(callback) {
1115 /**
1116 * @param {?Protocol.Error} error
1117 * @param {!Array.<!DebuggerAgent.CallFrame>=} callFrames
1118 * @param {!RuntimeAgent.StackTrace=} asyncStackTrace
1119 * @this {WebInspector.DebuggerModel.CallFrame}
1120 */
1121 function protocolCallback(error, callFrames, asyncStackTrace) {
1122 if (!error)
1123 this.debuggerModel.stepInto();
1124 if (callback)
1125 callback(error);
1126 }
1127 this._debuggerAgent.restartFrame(this._payload.callFrameId, protocolCallback .bind(this));
1128 }
1129
1130 /**
1131 * @param {function(!Object)} callback
1132 */
1133 variableNames(callback) {
1134 var result = {this: true};
1135
1136 function propertiesCollected(properties) {
1137 for (var i = 0; properties && i < properties.length; ++i)
1138 result[properties[i].name] = true;
1139 if (--pendingRequests === 0)
1140 callback(result);
1141 }
1142
1143 var scopeChain = this.scopeChain();
1144 var pendingRequests = scopeChain.length;
1145 for (var i = 0; i < scopeChain.length; ++i) {
1146 var scope = scopeChain[i];
1147 var object = scope.object();
1148 object.getAllProperties(false, propertiesCollected);
1149 }
1150 }
991 }; 1151 };
992 1152
993 WebInspector.DebuggerModel.CallFrame.prototype = {
994 /**
995 * @return {!WebInspector.Script}
996 */
997 get script()
998 {
999 return this._script;
1000 },
1001
1002 /**
1003 * @return {string}
1004 */
1005 get id()
1006 {
1007 return this._payload.callFrameId;
1008 },
1009
1010 /**
1011 * @return {!Array.<!WebInspector.DebuggerModel.Scope>}
1012 */
1013 scopeChain: function()
1014 {
1015 return this._scopeChain;
1016 },
1017
1018 /**
1019 * @return {?WebInspector.DebuggerModel.Scope}
1020 */
1021 localScope: function()
1022 {
1023 return this._localScope;
1024 },
1025
1026 /**
1027 * @return {?WebInspector.RemoteObject}
1028 */
1029 thisObject: function()
1030 {
1031 return this._payload.this ? this.target().runtimeModel.createRemoteObjec t(this._payload.this) : null;
1032 },
1033
1034 /**
1035 * @return {?WebInspector.RemoteObject}
1036 */
1037 returnValue: function()
1038 {
1039 return this._payload.returnValue ? this.target().runtimeModel.createRem oteObject(this._payload.returnValue) : null;
1040 },
1041
1042 /**
1043 * @return {string}
1044 */
1045 get functionName()
1046 {
1047 return this._payload.functionName;
1048 },
1049
1050 /**
1051 * @return {!WebInspector.DebuggerModel.Location}
1052 */
1053 location: function()
1054 {
1055 return this._location;
1056 },
1057
1058 /**
1059 * @return {?WebInspector.DebuggerModel.Location}
1060 */
1061 functionLocation: function()
1062 {
1063 return this._functionLocation || null;
1064 },
1065
1066 /**
1067 * @param {string} code
1068 * @param {string} objectGroup
1069 * @param {boolean} includeCommandLineAPI
1070 * @param {boolean} silent
1071 * @param {boolean} returnByValue
1072 * @param {boolean} generatePreview
1073 * @param {function(?RuntimeAgent.RemoteObject, !RuntimeAgent.ExceptionDetai ls=)} callback
1074 */
1075 evaluate: function(code, objectGroup, includeCommandLineAPI, silent, returnB yValue, generatePreview, callback)
1076 {
1077 /**
1078 * @param {?Protocol.Error} error
1079 * @param {!RuntimeAgent.RemoteObject} result
1080 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails
1081 */
1082 function didEvaluateOnCallFrame(error, result, exceptionDetails)
1083 {
1084 if (error) {
1085 console.error(error);
1086 callback(null);
1087 return;
1088 }
1089 callback(result, exceptionDetails);
1090 }
1091 this._debuggerAgent.evaluateOnCallFrame(this._payload.callFrameId, code, objectGroup, includeCommandLineAPI, silent, returnByValue, generatePreview, did EvaluateOnCallFrame);
1092 },
1093
1094 /**
1095 * @param {function(?Protocol.Error=)=} callback
1096 */
1097 restart: function(callback)
1098 {
1099 /**
1100 * @param {?Protocol.Error} error
1101 * @param {!Array.<!DebuggerAgent.CallFrame>=} callFrames
1102 * @param {!RuntimeAgent.StackTrace=} asyncStackTrace
1103 * @this {WebInspector.DebuggerModel.CallFrame}
1104 */
1105 function protocolCallback(error, callFrames, asyncStackTrace)
1106 {
1107 if (!error)
1108 this.debuggerModel.stepInto();
1109 if (callback)
1110 callback(error);
1111 }
1112 this._debuggerAgent.restartFrame(this._payload.callFrameId, protocolCall back.bind(this));
1113 },
1114
1115 /**
1116 * @param {function(!Object)} callback
1117 */
1118 variableNames: function(callback)
1119 {
1120 var result = { this: true };
1121
1122 function propertiesCollected(properties)
1123 {
1124 for (var i = 0; properties && i < properties.length; ++i)
1125 result[properties[i].name] = true;
1126 if (--pendingRequests === 0)
1127 callback(result);
1128 }
1129
1130 var scopeChain = this.scopeChain();
1131 var pendingRequests = scopeChain.length;
1132 for (var i = 0; i < scopeChain.length; ++i) {
1133 var scope = scopeChain[i];
1134 var object = scope.object();
1135 object.getAllProperties(false, propertiesCollected);
1136 }
1137 },
1138
1139 __proto__: WebInspector.SDKObject.prototype
1140 };
1141 1153
1142 /** 1154 /**
1143 * @constructor 1155 * @unrestricted
1144 * @param {!WebInspector.DebuggerModel.CallFrame} callFrame
1145 * @param {number} ordinal
1146 */ 1156 */
1147 WebInspector.DebuggerModel.Scope = function(callFrame, ordinal) 1157 WebInspector.DebuggerModel.Scope = class {
1148 { 1158 /**
1159 * @param {!WebInspector.DebuggerModel.CallFrame} callFrame
1160 * @param {number} ordinal
1161 */
1162 constructor(callFrame, ordinal) {
1149 this._callFrame = callFrame; 1163 this._callFrame = callFrame;
1150 this._payload = callFrame._payload.scopeChain[ordinal]; 1164 this._payload = callFrame._payload.scopeChain[ordinal];
1151 this._type = this._payload.type; 1165 this._type = this._payload.type;
1152 this._name = this._payload.name; 1166 this._name = this._payload.name;
1153 this._ordinal = ordinal; 1167 this._ordinal = ordinal;
1154 this._startLocation = this._payload.startLocation ? WebInspector.DebuggerMod el.Location.fromPayload(callFrame.debuggerModel, this._payload.startLocation) : null; 1168 this._startLocation = this._payload.startLocation ?
1155 this._endLocation = this._payload.endLocation ? WebInspector.DebuggerModel.L ocation.fromPayload(callFrame.debuggerModel, this._payload.endLocation) : null; 1169 WebInspector.DebuggerModel.Location.fromPayload(callFrame.debuggerModel, this._payload.startLocation) :
1170 null;
1171 this._endLocation = this._payload.endLocation ?
1172 WebInspector.DebuggerModel.Location.fromPayload(callFrame.debuggerModel, this._payload.endLocation) :
1173 null;
1174 }
1175
1176 /**
1177 * @return {!WebInspector.DebuggerModel.CallFrame}
1178 */
1179 callFrame() {
1180 return this._callFrame;
1181 }
1182
1183 /**
1184 * @return {string}
1185 */
1186 type() {
1187 return this._type;
1188 }
1189
1190 /**
1191 * @return {string|undefined}
1192 */
1193 name() {
1194 return this._name;
1195 }
1196
1197 /**
1198 * @return {?WebInspector.DebuggerModel.Location}
1199 */
1200 startLocation() {
1201 return this._startLocation;
1202 }
1203
1204 /**
1205 * @return {?WebInspector.DebuggerModel.Location}
1206 */
1207 endLocation() {
1208 return this._endLocation;
1209 }
1210
1211 /**
1212 * @return {!WebInspector.RemoteObject}
1213 */
1214 object() {
1215 if (this._object)
1216 return this._object;
1217 var runtimeModel = this._callFrame.target().runtimeModel;
1218
1219 var declarativeScope = this._type !== DebuggerAgent.ScopeType.With && this._ type !== DebuggerAgent.ScopeType.Global;
1220 if (declarativeScope)
1221 this._object = runtimeModel.createScopeRemoteObject(
1222 this._payload.object, new WebInspector.ScopeRef(this._ordinal, this._c allFrame.id));
1223 else
1224 this._object = runtimeModel.createRemoteObject(this._payload.object);
1225
1226 return this._object;
1227 }
1228
1229 /**
1230 * @return {string}
1231 */
1232 description() {
1233 var declarativeScope = this._type !== DebuggerAgent.ScopeType.With && this._ type !== DebuggerAgent.ScopeType.Global;
1234 return declarativeScope ? '' : (this._payload.object.description || '');
1235 }
1156 }; 1236 };
1157 1237
1158 WebInspector.DebuggerModel.Scope.prototype = {
1159 /**
1160 * @return {!WebInspector.DebuggerModel.CallFrame}
1161 */
1162 callFrame: function()
1163 {
1164 return this._callFrame;
1165 },
1166
1167 /**
1168 * @return {string}
1169 */
1170 type: function()
1171 {
1172 return this._type;
1173 },
1174
1175 /**
1176 * @return {string|undefined}
1177 */
1178 name: function()
1179 {
1180 return this._name;
1181 },
1182
1183 /**
1184 * @return {?WebInspector.DebuggerModel.Location}
1185 */
1186 startLocation: function()
1187 {
1188 return this._startLocation;
1189 },
1190
1191 /**
1192 * @return {?WebInspector.DebuggerModel.Location}
1193 */
1194 endLocation: function()
1195 {
1196 return this._endLocation;
1197 },
1198
1199 /**
1200 * @return {!WebInspector.RemoteObject}
1201 */
1202 object: function()
1203 {
1204 if (this._object)
1205 return this._object;
1206 var runtimeModel = this._callFrame.target().runtimeModel;
1207
1208 var declarativeScope = this._type !== DebuggerAgent.ScopeType.With && th is._type !== DebuggerAgent.ScopeType.Global;
1209 if (declarativeScope)
1210 this._object = runtimeModel.createScopeRemoteObject(this._payload.ob ject, new WebInspector.ScopeRef(this._ordinal, this._callFrame.id));
1211 else
1212 this._object = runtimeModel.createRemoteObject(this._payload.object) ;
1213
1214 return this._object;
1215 },
1216
1217 /**
1218 * @return {string}
1219 */
1220 description: function()
1221 {
1222 var declarativeScope = this._type !== DebuggerAgent.ScopeType.With && th is._type !== DebuggerAgent.ScopeType.Global;
1223 return declarativeScope ? "" : (this._payload.object.description || "");
1224 }
1225 };
1226
1227 /** 1238 /**
1228 * @constructor 1239 * @unrestricted
1229 * @extends {WebInspector.SDKObject}
1230 * @param {!WebInspector.DebuggerModel} debuggerModel
1231 * @param {!Array.<!DebuggerAgent.CallFrame>} callFrames
1232 * @param {string} reason
1233 * @param {!Object|undefined} auxData
1234 * @param {!Array.<string>} breakpointIds
1235 * @param {!RuntimeAgent.StackTrace=} asyncStackTrace
1236 */ 1240 */
1237 WebInspector.DebuggerPausedDetails = function(debuggerModel, callFrames, reason, auxData, breakpointIds, asyncStackTrace) 1241 WebInspector.DebuggerPausedDetails = class extends WebInspector.SDKObject {
1238 { 1242 /**
1239 WebInspector.SDKObject.call(this, debuggerModel.target()); 1243 * @param {!WebInspector.DebuggerModel} debuggerModel
1244 * @param {!Array.<!DebuggerAgent.CallFrame>} callFrames
1245 * @param {string} reason
1246 * @param {!Object|undefined} auxData
1247 * @param {!Array.<string>} breakpointIds
1248 * @param {!RuntimeAgent.StackTrace=} asyncStackTrace
1249 */
1250 constructor(debuggerModel, callFrames, reason, auxData, breakpointIds, asyncSt ackTrace) {
1251 super(debuggerModel.target());
1240 this.debuggerModel = debuggerModel; 1252 this.debuggerModel = debuggerModel;
1241 this.callFrames = WebInspector.DebuggerModel.CallFrame.fromPayloadArray(debu ggerModel, callFrames); 1253 this.callFrames = WebInspector.DebuggerModel.CallFrame.fromPayloadArray(debu ggerModel, callFrames);
1242 this.reason = reason; 1254 this.reason = reason;
1243 this.auxData = auxData; 1255 this.auxData = auxData;
1244 this.breakpointIds = breakpointIds; 1256 this.breakpointIds = breakpointIds;
1245 if (asyncStackTrace) 1257 if (asyncStackTrace)
1246 this.asyncStackTrace = this._cleanRedundantFrames(asyncStackTrace); 1258 this.asyncStackTrace = this._cleanRedundantFrames(asyncStackTrace);
1259 }
1260
1261 /**
1262 * @return {?WebInspector.RemoteObject}
1263 */
1264 exception() {
1265 if (this.reason !== WebInspector.DebuggerModel.BreakReason.Exception &&
1266 this.reason !== WebInspector.DebuggerModel.BreakReason.PromiseRejection)
1267 return null;
1268 return this.target().runtimeModel.createRemoteObject(/** @type {!RuntimeAgen t.RemoteObject} */ (this.auxData));
1269 }
1270
1271 /**
1272 * @param {!RuntimeAgent.StackTrace} asyncStackTrace
1273 * @return {!RuntimeAgent.StackTrace}
1274 */
1275 _cleanRedundantFrames(asyncStackTrace) {
1276 var stack = asyncStackTrace;
1277 var previous = null;
1278 while (stack) {
1279 if (stack.description === 'async function' && stack.callFrames.length)
1280 stack.callFrames.shift();
1281 if (previous && !stack.callFrames.length)
1282 previous.parent = stack.parent;
1283 else
1284 previous = stack;
1285 stack = stack.parent;
1286 }
1287 return asyncStackTrace;
1288 }
1247 }; 1289 };
1248 1290
1249 WebInspector.DebuggerPausedDetails.prototype = { 1291
1250 /**
1251 * @return {?WebInspector.RemoteObject}
1252 */
1253 exception: function()
1254 {
1255 if (this.reason !== WebInspector.DebuggerModel.BreakReason.Exception && this.reason !== WebInspector.DebuggerModel.BreakReason.PromiseRejection)
1256 return null;
1257 return this.target().runtimeModel.createRemoteObject(/** @type {!Runtime Agent.RemoteObject} */(this.auxData));
1258 },
1259
1260 /**
1261 * @param {!RuntimeAgent.StackTrace} asyncStackTrace
1262 * @return {!RuntimeAgent.StackTrace}
1263 */
1264 _cleanRedundantFrames: function(asyncStackTrace)
1265 {
1266 var stack = asyncStackTrace;
1267 var previous = null;
1268 while (stack) {
1269 if (stack.description === "async function" && stack.callFrames.lengt h)
1270 stack.callFrames.shift();
1271 if (previous && !stack.callFrames.length)
1272 previous.parent = stack.parent;
1273 else
1274 previous = stack;
1275 stack = stack.parent;
1276 }
1277 return asyncStackTrace;
1278 },
1279
1280 __proto__: WebInspector.SDKObject.prototype
1281 };
1282
1283 /**
1284 * @return {!Array<!WebInspector.DebuggerModel>}
1285 */
1286 WebInspector.DebuggerModel.instances = function()
1287 {
1288 var result = [];
1289 for (var target of WebInspector.targetManager.targets()) {
1290 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
1291 if (debuggerModel)
1292 result.push(debuggerModel);
1293 }
1294 return result;
1295 };
1296
1297 /**
1298 * @param {?WebInspector.Target} target
1299 * @return {?WebInspector.DebuggerModel}
1300 */
1301 WebInspector.DebuggerModel.fromTarget = function(target)
1302 {
1303 if (!target || !target.hasJSCapability())
1304 return null;
1305 return /** @type {?WebInspector.DebuggerModel} */ (target.model(WebInspector .DebuggerModel));
1306 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698