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

Side by Side Diff: third_party/WebKit/Source/core/inspector/DebuggerScript.js

Issue 1648523002: DevTools: move InjectedScript* to inspector/v8. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
29 */
30 "use strict";
31
32 (function () {
33
34 var DebuggerScript = {};
35
36 DebuggerScript.PauseOnExceptionsState = {
37 DontPauseOnExceptions: 0,
38 PauseOnAllExceptions: 1,
39 PauseOnUncaughtExceptions: 2
40 };
41
42 DebuggerScript.ScopeInfoDetails = {
43 AllScopes: 0,
44 FastAsyncScopes: 1,
45 NoScopes: 2
46 };
47
48 DebuggerScript._pauseOnExceptionsState = DebuggerScript.PauseOnExceptionsState.D ontPauseOnExceptions;
49 Debug.clearBreakOnException();
50 Debug.clearBreakOnUncaughtException();
51
52 DebuggerScript.getAfterCompileScript = function(eventData)
53 {
54 return DebuggerScript._formatScript(eventData.script_.script_);
55 }
56
57 DebuggerScript.getFunctionScopes = function(fun)
58 {
59 var mirror = MakeMirror(fun);
60 if (!mirror.isFunction())
61 return null;
62 var count = mirror.scopeCount();
63 if (count == 0)
64 return null;
65 var result = [];
66 for (var i = 0; i < count; i++) {
67 var scopeDetails = mirror.scope(i).details();
68 var scopeObject = DebuggerScript._buildScopeObject(scopeDetails.type(), scopeDetails.object());
69 if (!scopeObject)
70 continue;
71 result.push({
72 type: scopeDetails.type(),
73 object: scopeObject,
74 name: scopeDetails.name()
75 });
76 }
77 return result;
78 }
79
80 DebuggerScript.getGeneratorObjectDetails = function(object)
81 {
82 var mirror = MakeMirror(object, true /* transient */);
83 if (!mirror.isGenerator())
84 return null;
85 var funcMirror = mirror.func();
86 if (!funcMirror.resolved())
87 return null;
88 var result = {
89 "function": funcMirror.value(),
90 "functionName": funcMirror.debugName(),
91 "status": mirror.status()
92 };
93 var script = funcMirror.script();
94 var location = mirror.sourceLocation() || funcMirror.sourceLocation();
95 if (script && location) {
96 result["location"] = {
97 "scriptId": String(script.id()),
98 "lineNumber": location.line,
99 "columnNumber": location.column
100 };
101 }
102 return result;
103 }
104
105 DebuggerScript.getCollectionEntries = function(object)
106 {
107 var mirror = MakeMirror(object, true /* transient */);
108 if (mirror.isMap())
109 return mirror.entries();
110 if (mirror.isSet() || mirror.isIterator()) {
111 var result = [];
112 var values = mirror.isSet() ? mirror.values() : mirror.preview();
113 for (var i = 0; i < values.length; ++i)
114 result.push({ value: values[i] });
115 return result;
116 }
117 }
118
119 DebuggerScript.setFunctionVariableValue = function(functionValue, scopeIndex, va riableName, newValue)
120 {
121 var mirror = MakeMirror(functionValue);
122 if (!mirror.isFunction())
123 throw new Error("Function value has incorrect type");
124 return DebuggerScript._setScopeVariableValue(mirror, scopeIndex, variableNam e, newValue);
125 }
126
127 DebuggerScript._setScopeVariableValue = function(scopeHolder, scopeIndex, variab leName, newValue)
128 {
129 var scopeMirror = scopeHolder.scope(scopeIndex);
130 if (!scopeMirror)
131 throw new Error("Incorrect scope index");
132 scopeMirror.setVariableValue(variableName, newValue);
133 return undefined;
134 }
135
136 DebuggerScript.getScripts = function(contextGroupId)
137 {
138 var result = [];
139 var scripts = Debug.scripts();
140 var contextDataPrefix = null;
141 if (contextGroupId)
142 contextDataPrefix = contextGroupId + ",";
143 for (var i = 0; i < scripts.length; ++i) {
144 var script = scripts[i];
145 if (contextDataPrefix) {
146 if (!script.context_data)
147 continue;
148 // Context data is a string in the following format:
149 // <id>,<contextId>,("page"|"injected"|"worker")
150 if (script.context_data.indexOf(contextDataPrefix) !== 0)
151 continue;
152 }
153 result.push(DebuggerScript._formatScript(script));
154 }
155 return result;
156 }
157
158 DebuggerScript._formatScript = function(script)
159 {
160 var lineEnds = script.line_ends;
161 var lineCount = lineEnds.length;
162 var endLine = script.line_offset + lineCount - 1;
163 var endColumn;
164 // V8 will not count last line if script source ends with \n.
165 if (script.source[script.source.length - 1] === '\n') {
166 endLine += 1;
167 endColumn = 0;
168 } else {
169 if (lineCount === 1)
170 endColumn = script.source.length + script.column_offset;
171 else
172 endColumn = script.source.length - (lineEnds[lineCount - 2] + 1);
173 }
174
175 /**
176 * @return {number}
177 */
178 function executionContextId()
179 {
180 var context_data = script.context_data;
181 if (!context_data)
182 return 0;
183 var firstComma = context_data.indexOf(",");
184 if (firstComma === -1)
185 return 0;
186 var secondComma = context_data.indexOf(",", firstComma + 1);
187 if (secondComma === -1)
188 return 0;
189
190 return parseInt(context_data.substring(firstComma + 1, secondComma), 10) || 0;
191 }
192
193 return {
194 id: script.id,
195 name: script.nameOrSourceURL(),
196 sourceURL: script.source_url,
197 sourceMappingURL: script.source_mapping_url,
198 source: script.source,
199 startLine: script.line_offset,
200 startColumn: script.column_offset,
201 endLine: endLine,
202 endColumn: endColumn,
203 executionContextId: executionContextId(),
204 isContentScript: !!script.context_data && script.context_data.endsWith(" ,injected"),
205 isInternalScript: script.is_debugger_script
206 };
207 }
208
209 DebuggerScript.setBreakpoint = function(execState, info)
210 {
211 var positionAlignment = info.interstatementLocation ? Debug.BreakPositionAli gnment.BreakPosition : Debug.BreakPositionAlignment.Statement;
212 var breakId = Debug.setScriptBreakPointById(info.sourceID, info.lineNumber, info.columnNumber, info.condition, undefined, positionAlignment);
213
214 var locations = Debug.findBreakPointActualLocations(breakId);
215 if (!locations.length)
216 return undefined;
217 info.lineNumber = locations[0].line;
218 info.columnNumber = locations[0].column;
219 return breakId.toString();
220 }
221
222 DebuggerScript.removeBreakpoint = function(execState, info)
223 {
224 Debug.findBreakPoint(info.breakpointId, true);
225 }
226
227 DebuggerScript.pauseOnExceptionsState = function()
228 {
229 return DebuggerScript._pauseOnExceptionsState;
230 }
231
232 DebuggerScript.setPauseOnExceptionsState = function(newState)
233 {
234 DebuggerScript._pauseOnExceptionsState = newState;
235
236 if (DebuggerScript.PauseOnExceptionsState.PauseOnAllExceptions === newState)
237 Debug.setBreakOnException();
238 else
239 Debug.clearBreakOnException();
240
241 if (DebuggerScript.PauseOnExceptionsState.PauseOnUncaughtExceptions === newS tate)
242 Debug.setBreakOnUncaughtException();
243 else
244 Debug.clearBreakOnUncaughtException();
245 }
246
247 DebuggerScript.frameCount = function(execState)
248 {
249 return execState.frameCount();
250 }
251
252 DebuggerScript.currentCallFrame = function(execState, data)
253 {
254 var maximumLimit = data >> 2;
255 var scopeDetailsLevel = data & 3;
256
257 var frameCount = execState.frameCount();
258 if (maximumLimit && maximumLimit < frameCount)
259 frameCount = maximumLimit;
260 var topFrame = undefined;
261 for (var i = frameCount - 1; i >= 0; i--) {
262 var frameMirror = execState.frame(i);
263 topFrame = DebuggerScript._frameMirrorToJSCallFrame(frameMirror, topFram e, scopeDetailsLevel);
264 }
265 return topFrame;
266 }
267
268 DebuggerScript.currentCallFrameByIndex = function(execState, index)
269 {
270 if (index < 0)
271 return undefined;
272 var frameCount = execState.frameCount();
273 if (index >= frameCount)
274 return undefined;
275 return DebuggerScript._frameMirrorToJSCallFrame(execState.frame(index), unde fined, DebuggerScript.ScopeInfoDetails.NoScopes);
276 }
277
278 DebuggerScript.stepIntoStatement = function(execState)
279 {
280 execState.prepareStep(Debug.StepAction.StepIn);
281 }
282
283 DebuggerScript.stepFrameStatement = function(execState)
284 {
285 execState.prepareStep(Debug.StepAction.StepFrame);
286 }
287
288 DebuggerScript.stepOverStatement = function(execState, callFrame)
289 {
290 execState.prepareStep(Debug.StepAction.StepNext);
291 }
292
293 DebuggerScript.stepOutOfFunction = function(execState, callFrame)
294 {
295 execState.prepareStep(Debug.StepAction.StepOut);
296 }
297
298 DebuggerScript.clearStepping = function()
299 {
300 Debug.clearStepping();
301 }
302
303 // Returns array in form:
304 // [ 0, <v8_result_report> ] in case of success
305 // or [ 1, <general_error_message>, <compiler_message>, <line_number>, <column _number> ] in case of compile error, numbers are 1-based.
306 // or throws exception with message.
307 DebuggerScript.liveEditScriptSource = function(scriptId, newSource, preview)
308 {
309 var scripts = Debug.scripts();
310 var scriptToEdit = null;
311 for (var i = 0; i < scripts.length; i++) {
312 if (scripts[i].id == scriptId) {
313 scriptToEdit = scripts[i];
314 break;
315 }
316 }
317 if (!scriptToEdit)
318 throw("Script not found");
319
320 var changeLog = [];
321 try {
322 var result = Debug.LiveEdit.SetScriptSource(scriptToEdit, newSource, pre view, changeLog);
323 return [0, result.stack_modified];
324 } catch (e) {
325 if (e instanceof Debug.LiveEdit.Failure && "details" in e) {
326 var details = e.details;
327 if (details.type === "liveedit_compile_error") {
328 var startPosition = details.position.start;
329 return [1, String(e), String(details.syntaxErrorMessage), Number (startPosition.line), Number(startPosition.column)];
330 }
331 }
332 throw e;
333 }
334 }
335
336 DebuggerScript.clearBreakpoints = function(execState, info)
337 {
338 Debug.clearAllBreakPoints();
339 }
340
341 DebuggerScript.setBreakpointsActivated = function(execState, info)
342 {
343 Debug.debuggerFlags().breakPointsActive.setValue(info.enabled);
344 }
345
346 DebuggerScript.getScriptSource = function(eventData)
347 {
348 return eventData.script().source();
349 }
350
351 DebuggerScript.setScriptSource = function(eventData, source)
352 {
353 if (eventData.script().data() === "injected-script")
354 return;
355 eventData.script().setSource(source);
356 }
357
358 DebuggerScript.getScriptName = function(eventData)
359 {
360 return eventData.script().script_.nameOrSourceURL();
361 }
362
363 DebuggerScript.getBreakpointNumbers = function(eventData)
364 {
365 var breakpoints = eventData.breakPointsHit();
366 var numbers = [];
367 if (!breakpoints)
368 return numbers;
369
370 for (var i = 0; i < breakpoints.length; i++) {
371 var breakpoint = breakpoints[i];
372 var scriptBreakPoint = breakpoint.script_break_point();
373 numbers.push(scriptBreakPoint ? scriptBreakPoint.number() : breakpoint.n umber());
374 }
375 return numbers;
376 }
377
378 DebuggerScript.isEvalCompilation = function(eventData)
379 {
380 var script = eventData.script();
381 return (script.compilationType() === Debug.ScriptCompilationType.Eval);
382 }
383
384 // NOTE: This function is performance critical, as it can be run on every
385 // statement that generates an async event (like addEventListener) to support
386 // asynchronous call stacks. Thus, when possible, initialize the data lazily.
387 DebuggerScript._frameMirrorToJSCallFrame = function(frameMirror, callerFrame, sc opeDetailsLevel)
388 {
389 // Stuff that can not be initialized lazily (i.e. valid while paused with a valid break_id).
390 // The frameMirror and scopeMirror can be accessed only while paused on the debugger.
391 var frameDetails = frameMirror.details();
392
393 var funcObject = frameDetails.func();
394 var sourcePosition = frameDetails.sourcePosition();
395 var thisObject = frameDetails.receiver();
396
397 var isAtReturn = !!frameDetails.isAtReturn();
398 var returnValue = isAtReturn ? frameDetails.returnValue() : undefined;
399
400 var scopeMirrors = (scopeDetailsLevel === DebuggerScript.ScopeInfoDetails.No Scopes ? [] : frameMirror.allScopes(scopeDetailsLevel === DebuggerScript.ScopeIn foDetails.FastAsyncScopes));
401 var scopeTypes = new Array(scopeMirrors.length);
402 var scopeObjects = new Array(scopeMirrors.length);
403 var scopeNames = new Array(scopeMirrors.length);
404 for (var i = 0; i < scopeMirrors.length; ++i) {
405 var scopeDetails = scopeMirrors[i].details();
406 scopeTypes[i] = scopeDetails.type();
407 scopeObjects[i] = scopeDetails.object();
408 scopeNames[i] = scopeDetails.name();
409 }
410
411 // Calculated lazily.
412 var scopeChain;
413 var funcMirror;
414 var location;
415
416 function lazyScopeChain()
417 {
418 if (!scopeChain) {
419 scopeChain = [];
420 for (var i = 0, j = 0; i < scopeObjects.length; ++i) {
421 var scopeObject = DebuggerScript._buildScopeObject(scopeTypes[i] , scopeObjects[i], scopeNames[i]);
422 if (scopeObject) {
423 scopeTypes[j] = scopeTypes[i];
424 scopeNames[j] = scopeNames[i];
425 scopeChain[j] = scopeObject;
426 ++j;
427 }
428 }
429 scopeTypes.length = scopeChain.length;
430 scopeNames.length = scopeChain.length;
431 scopeObjects = null; // Free for GC.
432 }
433 return scopeChain;
434 }
435
436 function lazyScopeTypes()
437 {
438 if (!scopeChain)
439 lazyScopeChain();
440 return scopeTypes;
441 }
442
443 function lazyScopeNames()
444 {
445 if (!scopeChain)
446 lazyScopeChain();
447 return scopeNames;
448 }
449
450 function ensureFuncMirror()
451 {
452 if (!funcMirror) {
453 funcMirror = MakeMirror(funcObject);
454 if (!funcMirror.isFunction())
455 funcMirror = new UnresolvedFunctionMirror(funcObject);
456 }
457 return funcMirror;
458 }
459
460 function ensureLocation()
461 {
462 if (!location) {
463 var script = ensureFuncMirror().script();
464 if (script)
465 location = script.locationFromPosition(sourcePosition, true);
466 if (!location)
467 location = { line: 0, column: 0 };
468 }
469 return location;
470 }
471
472 function line()
473 {
474 return ensureLocation().line;
475 }
476
477 function column()
478 {
479 return ensureLocation().column;
480 }
481
482 function sourceID()
483 {
484 var script = ensureFuncMirror().script();
485 return script && script.id();
486 }
487
488 function scriptName()
489 {
490 var script = ensureFuncMirror().script();
491 return script && script.name();
492 }
493
494 function functionName()
495 {
496 return ensureFuncMirror().debugName();
497 }
498
499 function functionLine()
500 {
501 var location = ensureFuncMirror().sourceLocation();
502 return location ? location.line : 0;
503 }
504
505 function functionColumn()
506 {
507 var location = ensureFuncMirror().sourceLocation();
508 return location ? location.column : 0;
509 }
510
511 function evaluate(expression, scopeExtension)
512 {
513 return frameMirror.evaluate(expression, false, scopeExtension).value();
514 }
515
516 function restart()
517 {
518 return frameMirror.restart();
519 }
520
521 function setVariableValue(scopeNumber, variableName, newValue)
522 {
523 return DebuggerScript._setScopeVariableValue(frameMirror, scopeNumber, v ariableName, newValue);
524 }
525
526 function stepInPositions()
527 {
528 var stepInPositionsV8 = frameMirror.stepInPositions();
529 var stepInPositionsProtocol;
530 if (stepInPositionsV8) {
531 stepInPositionsProtocol = [];
532 var script = ensureFuncMirror().script();
533 if (script) {
534 var scriptId = String(script.id());
535 for (var i = 0; i < stepInPositionsV8.length; i++) {
536 var item = {
537 scriptId: scriptId,
538 lineNumber: stepInPositionsV8[i].position.line,
539 columnNumber: stepInPositionsV8[i].position.column
540 };
541 stepInPositionsProtocol.push(item);
542 }
543 }
544 }
545 return JSON.stringify(stepInPositionsProtocol);
546 }
547
548 return {
549 "sourceID": sourceID,
550 "line": line,
551 "column": column,
552 "scriptName": scriptName,
553 "functionName": functionName,
554 "functionLine": functionLine,
555 "functionColumn": functionColumn,
556 "thisObject": thisObject,
557 "scopeChain": lazyScopeChain,
558 "scopeType": lazyScopeTypes,
559 "scopeName": lazyScopeNames,
560 "evaluate": evaluate,
561 "caller": callerFrame,
562 "restart": restart,
563 "setVariableValue": setVariableValue,
564 "stepInPositions": stepInPositions,
565 "isAtReturn": isAtReturn,
566 "returnValue": returnValue
567 };
568 }
569
570 DebuggerScript._buildScopeObject = function(scopeType, scopeObject)
571 {
572 var result;
573 switch (scopeType) {
574 case ScopeType.Local:
575 case ScopeType.Closure:
576 case ScopeType.Catch:
577 case ScopeType.Block:
578 case ScopeType.Script:
579 // For transient objects we create a "persistent" copy that contains
580 // the same properties.
581 // Reset scope object prototype to null so that the proto properties
582 // don't appear in the local scope section.
583 var properties = MakeMirror(scopeObject, true /* transient */).propertie s();
584 // Almost always Script scope will be empty, so just filter out that noi se.
585 // Also drop empty Block scopes, should we get any.
586 if (!properties.length && (scopeType === ScopeType.Script || scopeType = == ScopeType.Block))
587 break;
588 result = { __proto__: null };
589 for (var j = 0; j < properties.length; j++) {
590 var name = properties[j].name();
591 if (name.charAt(0) === ".")
592 continue; // Skip internal variables like ".arguments"
593 result[name] = properties[j].value_;
594 }
595 break;
596 case ScopeType.Global:
597 case ScopeType.With:
598 result = scopeObject;
599 break;
600 }
601 return result;
602 }
603
604 DebuggerScript.getPromiseDetails = function(eventData)
605 {
606 return {
607 "promise": eventData.promise().value(),
608 "parentPromise": eventData.parentPromise().value(),
609 "status": eventData.status()
610 };
611 }
612
613 // We never resolve Mirror by its handle so to avoid memory leaks caused by Mirr ors in the cache we disable it.
614 ToggleMirrorCache(false);
615
616 return DebuggerScript;
617 })();
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/core.gypi ('k') | third_party/WebKit/Source/core/inspector/InjectedScript.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698