OLD | NEW |
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 }; | |
OLD | NEW |