| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library debugger_page_element; | 5 library debugger_page_element; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:svg'; | 8 import 'dart:svg'; |
| 9 import 'dart:html'; | 9 import 'dart:html'; |
| 10 import 'dart:math'; | 10 import 'dart:math'; |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 'break-on-exception': [ | 597 'break-on-exception': [ |
| 598 _boeValues, | 598 _boeValues, |
| 599 _setBreakOnException, | 599 _setBreakOnException, |
| 600 (debugger, _) => debugger.breakOnException | 600 (debugger, _) => debugger.breakOnException |
| 601 ], | 601 ], |
| 602 'up-is-down': [ | 602 'up-is-down': [ |
| 603 _boolValues, | 603 _boolValues, |
| 604 _setUpIsDown, | 604 _setUpIsDown, |
| 605 (debugger, _) => debugger.upIsDown | 605 (debugger, _) => debugger.upIsDown |
| 606 ], | 606 ], |
| 607 'sane-async-stacks': [ |
| 608 _boolValues, |
| 609 _setSaneAsyncStacks, |
| 610 (debugger, _) => debugger.saneAsyncStacks |
| 611 ] |
| 607 }; | 612 }; |
| 608 | 613 |
| 609 static Future _setBreakOnException(debugger, name, value) async { | 614 static Future _setBreakOnException(debugger, name, value) async { |
| 610 var result = await debugger.isolate.setExceptionPauseMode(value); | 615 var result = await debugger.isolate.setExceptionPauseMode(value); |
| 611 if (result.isError) { | 616 if (result.isError) { |
| 612 debugger.console.print(result.toString()); | 617 debugger.console.print(result.toString()); |
| 613 } else { | 618 } else { |
| 614 // Printing will occur elsewhere. | 619 // Printing will occur elsewhere. |
| 615 debugger.breakOnException = value; | 620 debugger.breakOnException = value; |
| 616 } | 621 } |
| 617 } | 622 } |
| 618 | 623 |
| 619 static Future _setUpIsDown(debugger, name, value) async { | 624 static Future _setUpIsDown(debugger, name, value) async { |
| 620 if (value == 'true') { | 625 if (value == 'true') { |
| 621 debugger.upIsDown = true; | 626 debugger.upIsDown = true; |
| 622 } else { | 627 } else { |
| 623 debugger.upIsDown = false; | 628 debugger.upIsDown = false; |
| 624 } | 629 } |
| 625 debugger.console.print('${name} = ${value}'); | 630 debugger.console.print('${name} = ${value}'); |
| 626 } | 631 } |
| 627 | 632 |
| 633 static Future _setSaneAsyncStacks(debugger, name, value) async { |
| 634 if (value == 'true') { |
| 635 debugger.saneAsyncStacks = true; |
| 636 } else { |
| 637 debugger.saneAsyncStacks = false; |
| 638 } |
| 639 debugger.refreshStack(); |
| 640 debugger.console.print('${name} = ${value}'); |
| 641 } |
| 642 |
| 628 Future run(List<String> args) async { | 643 Future run(List<String> args) async { |
| 629 if (args.length == 0) { | 644 if (args.length == 0) { |
| 630 for (var name in _options.keys) { | 645 for (var name in _options.keys) { |
| 631 var getHandler = _options[name][2]; | 646 var getHandler = _options[name][2]; |
| 632 var value = await getHandler(debugger, name); | 647 var value = await getHandler(debugger, name); |
| 633 debugger.console.print("${name} = ${value}"); | 648 debugger.console.print("${name} = ${value}"); |
| 634 } | 649 } |
| 635 } else if (args.length == 1) { | 650 } else if (args.length == 1) { |
| 636 var name = args[0].trim(); | 651 var name = args[0].trim(); |
| 637 var optionInfo = _options[name]; | 652 var optionInfo = _options[name]; |
| (...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1374 int _currentFrame = null; | 1389 int _currentFrame = null; |
| 1375 | 1390 |
| 1376 bool get upIsDown => _upIsDown; | 1391 bool get upIsDown => _upIsDown; |
| 1377 void set upIsDown(bool value) { | 1392 void set upIsDown(bool value) { |
| 1378 settings.set('up-is-down', value); | 1393 settings.set('up-is-down', value); |
| 1379 _upIsDown = value; | 1394 _upIsDown = value; |
| 1380 } | 1395 } |
| 1381 | 1396 |
| 1382 bool _upIsDown; | 1397 bool _upIsDown; |
| 1383 | 1398 |
| 1399 bool get saneAsyncStacks => _saneAsyncStacks; |
| 1400 void set saneAsyncStacks(bool value) { |
| 1401 settings.set('sane-async-stacks', value); |
| 1402 _saneAsyncStacks = value; |
| 1403 } |
| 1404 |
| 1405 bool _saneAsyncStacks; |
| 1406 |
| 1407 static const String kAsyncStackFrames = 'asyncFrames'; |
| 1408 static const String kStackFrames = 'frames'; |
| 1409 |
| 1384 void upFrame(int count) { | 1410 void upFrame(int count) { |
| 1385 if (_upIsDown) { | 1411 if (_upIsDown) { |
| 1386 currentFrame += count; | 1412 currentFrame += count; |
| 1387 } else { | 1413 } else { |
| 1388 currentFrame -= count; | 1414 currentFrame -= count; |
| 1389 } | 1415 } |
| 1390 } | 1416 } |
| 1391 | 1417 |
| 1392 void downFrame(int count) { | 1418 void downFrame(int count) { |
| 1393 if (_upIsDown) { | 1419 if (_upIsDown) { |
| 1394 currentFrame -= count; | 1420 currentFrame -= count; |
| 1395 } else { | 1421 } else { |
| 1396 currentFrame += count; | 1422 currentFrame += count; |
| 1397 } | 1423 } |
| 1398 } | 1424 } |
| 1399 | 1425 |
| 1400 int get stackDepth => stack['frames'].length; | 1426 int get stackDepth { |
| 1427 if (saneAsyncStacks) { |
| 1428 return stack[kAsyncStackFrames].length; |
| 1429 } else { |
| 1430 return stack[kStackFrames].length; |
| 1431 } |
| 1432 } |
| 1433 |
| 1434 List get stackFrames { |
| 1435 if (saneAsyncStacks) { |
| 1436 return stack[kAsyncStackFrames] ?? []; |
| 1437 } else { |
| 1438 return stack[kStackFrames] ?? []; |
| 1439 } |
| 1440 } |
| 1401 | 1441 |
| 1402 static final _history = ['']; | 1442 static final _history = ['']; |
| 1403 | 1443 |
| 1404 ObservatoryDebugger(this.isolate) { | 1444 ObservatoryDebugger(this.isolate) { |
| 1405 _loadSettings(); | 1445 _loadSettings(); |
| 1406 cmd = new RootCommand([ | 1446 cmd = new RootCommand([ |
| 1407 new AsyncNextCommand(this), | 1447 new AsyncNextCommand(this), |
| 1408 new BreakCommand(this), | 1448 new BreakCommand(this), |
| 1409 new ClearCommand(this), | 1449 new ClearCommand(this), |
| 1410 new ClsCommand(this), | 1450 new ClsCommand(this), |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1427 new StepCommand(this), | 1467 new StepCommand(this), |
| 1428 new SyncNextCommand(this), | 1468 new SyncNextCommand(this), |
| 1429 new UpCommand(this), | 1469 new UpCommand(this), |
| 1430 new VmCommand(this), | 1470 new VmCommand(this), |
| 1431 ], _history); | 1471 ], _history); |
| 1432 _consolePrinter = new _ConsoleStreamPrinter(this); | 1472 _consolePrinter = new _ConsoleStreamPrinter(this); |
| 1433 } | 1473 } |
| 1434 | 1474 |
| 1435 void _loadSettings() { | 1475 void _loadSettings() { |
| 1436 _upIsDown = settings.get('up-is-down'); | 1476 _upIsDown = settings.get('up-is-down'); |
| 1477 _saneAsyncStacks = settings.get('sane-async-stacks') ?? true; |
| 1478 print('saneAsyncStacks -> $_saneAsyncStacks'); |
| 1437 } | 1479 } |
| 1438 | 1480 |
| 1439 S.VM get vm => page.app.vm; | 1481 S.VM get vm => page.app.vm; |
| 1440 | 1482 |
| 1441 void init() { | 1483 void init() { |
| 1442 console.printBold('Debugging isolate isolate ${isolate.number} ' | 1484 console.printBold('Debugging isolate isolate ${isolate.number} ' |
| 1443 '\'${isolate.name}\' '); | 1485 '\'${isolate.name}\' '); |
| 1444 console.printBold('Type \'h\' for help'); | 1486 console.printBold('Type \'h\' for help'); |
| 1445 // Wait a bit and if polymer still hasn't set up the isolate, | 1487 // Wait a bit and if polymer still hasn't set up the isolate, |
| 1446 // report this to the user. | 1488 // report this to the user. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1508 | 1550 |
| 1509 Future<S.ServiceMap> _refreshStack(M.DebugEvent pauseEvent) { | 1551 Future<S.ServiceMap> _refreshStack(M.DebugEvent pauseEvent) { |
| 1510 return isolate.getStack().then((result) { | 1552 return isolate.getStack().then((result) { |
| 1511 if (result.isSentinel) { | 1553 if (result.isSentinel) { |
| 1512 // The isolate has gone away. The IsolateExit event will | 1554 // The isolate has gone away. The IsolateExit event will |
| 1513 // clear the isolate for the debugger page. | 1555 // clear the isolate for the debugger page. |
| 1514 return; | 1556 return; |
| 1515 } | 1557 } |
| 1516 stack = result; | 1558 stack = result; |
| 1517 stackElement.updateStack(stack, pauseEvent); | 1559 stackElement.updateStack(stack, pauseEvent); |
| 1518 if (stack['frames'].length > 0) { | 1560 List frames = |
| 1561 saneAsyncStacks ? stack[kAsyncStackFrames] : stack[kStackFrames]; |
| 1562 if (frames.length > 0) { |
| 1519 currentFrame = 0; | 1563 currentFrame = 0; |
| 1520 } else { | 1564 } else { |
| 1521 currentFrame = null; | 1565 currentFrame = null; |
| 1522 } | 1566 } |
| 1523 input.focus(); | 1567 input.focus(); |
| 1524 }); | 1568 }); |
| 1525 } | 1569 } |
| 1526 | 1570 |
| 1527 void reportStatus() { | 1571 void reportStatus() { |
| 1528 flushStdio(); | 1572 flushStdio(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1578 console.print("Paused at isolate start " | 1622 console.print("Paused at isolate start " |
| 1579 "(type 'continue' [F7] or 'step' [F10] to start the isolate')"); | 1623 "(type 'continue' [F7] or 'step' [F10] to start the isolate')"); |
| 1580 } else if (event is M.PauseExitEvent) { | 1624 } else if (event is M.PauseExitEvent) { |
| 1581 console.print("Paused at isolate exit " | 1625 console.print("Paused at isolate exit " |
| 1582 "(type 'continue' or [F7] to exit the isolate')"); | 1626 "(type 'continue' or [F7] to exit the isolate')"); |
| 1583 _reportIsolateError(isolate, event); | 1627 _reportIsolateError(isolate, event); |
| 1584 } else if (event is M.PauseExceptionEvent) { | 1628 } else if (event is M.PauseExceptionEvent) { |
| 1585 console.print("Paused at an unhandled exception " | 1629 console.print("Paused at an unhandled exception " |
| 1586 "(type 'continue' or [F7] to exit the isolate')"); | 1630 "(type 'continue' or [F7] to exit the isolate')"); |
| 1587 _reportIsolateError(isolate, event); | 1631 _reportIsolateError(isolate, event); |
| 1588 } else if (stack['frames'].length > 0) { | 1632 } else if (stackFrames.length > 0) { |
| 1589 S.Frame frame = stack['frames'][0]; | 1633 S.Frame frame = stackFrames[0]; |
| 1590 var script = frame.location.script; | 1634 var script = frame.location.script; |
| 1591 script.load().then((_) { | 1635 script.load().then((_) { |
| 1592 var line = script.tokenToLine(frame.location.tokenPos); | 1636 var line = script.tokenToLine(frame.location.tokenPos); |
| 1593 var col = script.tokenToCol(frame.location.tokenPos); | 1637 var col = script.tokenToCol(frame.location.tokenPos); |
| 1594 if ((event is M.PauseBreakpointEvent) && (event.breakpoint != null)) { | 1638 if ((event is M.PauseBreakpointEvent) && (event.breakpoint != null)) { |
| 1595 var bpId = event.breakpoint.number; | 1639 var bpId = event.breakpoint.number; |
| 1596 console.print('Paused at breakpoint ${bpId} at ' | 1640 console.print('Paused at breakpoint ${bpId} at ' |
| 1597 '${script.name}:${line}:${col}'); | 1641 '${script.name}:${line}:${col}'); |
| 1598 } else if ((event is M.PauseExceptionEvent) && | 1642 } else if ((event is M.PauseExceptionEvent) && |
| 1599 (event.exception != null)) { | 1643 (event.exception != null)) { |
| (...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2244 li.classes.add('list-group-item'); | 2288 li.classes.add('list-group-item'); |
| 2245 li.children.insert(0, messageElement); | 2289 li.children.insert(0, messageElement); |
| 2246 | 2290 |
| 2247 messageList.add(li); | 2291 messageList.add(li); |
| 2248 } | 2292 } |
| 2249 | 2293 |
| 2250 ObservatoryApplication get app => ObservatoryApplication.app; | 2294 ObservatoryApplication get app => ObservatoryApplication.app; |
| 2251 | 2295 |
| 2252 void updateStackFrames(S.ServiceMap newStack) { | 2296 void updateStackFrames(S.ServiceMap newStack) { |
| 2253 List frameElements = _frameList.children; | 2297 List frameElements = _frameList.children; |
| 2254 List newFrames = newStack['frames']; | 2298 List newFrames = _debugger.saneAsyncStacks ? |
| 2299 newStack[ObservatoryDebugger.kAsyncStackFrames] : |
| 2300 newStack[ObservatoryDebugger.kStackFrames]; |
| 2255 | 2301 |
| 2256 // Remove any frames whose functions don't match, starting from | 2302 // Remove any frames whose functions don't match, starting from |
| 2257 // bottom of stack. | 2303 // bottom of stack. |
| 2258 int oldPos = frameElements.length - 1; | 2304 int oldPos = frameElements.length - 1; |
| 2259 int newPos = newFrames.length - 1; | 2305 int newPos = newFrames.length - 1; |
| 2260 while (oldPos >= 0 && newPos >= 0) { | 2306 while (oldPos >= 0 && newPos >= 0) { |
| 2261 if (!frameElements[oldPos].children[0].matchFrame(newFrames[newPos])) { | 2307 if (!frameElements[oldPos].children[0].matchFrame(newFrames[newPos])) { |
| 2262 // The rest of the frame elements no longer match. Remove them. | 2308 // The rest of the frame elements no longer match. Remove them. |
| 2263 for (int i = 0; i <= oldPos; i++) { | 2309 for (int i = 0; i <= oldPos; i++) { |
| 2264 // NOTE(turnidge): removeRange is missing, sadly. | 2310 // NOTE(turnidge): removeRange is missing, sadly. |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2372 | 2418 |
| 2373 // Is this the current frame? | 2419 // Is this the current frame? |
| 2374 bool _current = false; | 2420 bool _current = false; |
| 2375 | 2421 |
| 2376 // Has this frame been pinned open? | 2422 // Has this frame been pinned open? |
| 2377 bool _pinned = false; | 2423 bool _pinned = false; |
| 2378 | 2424 |
| 2379 bool _expanded = false; | 2425 bool _expanded = false; |
| 2380 | 2426 |
| 2381 void setCurrent(bool value) { | 2427 void setCurrent(bool value) { |
| 2382 _frame.function.load().then((func) { | 2428 Future load = |
| 2429 (_frame.function != null) ? |
| 2430 _frame.function.load() : |
| 2431 new Future.value(null); |
| 2432 load.then((func) { |
| 2383 _current = value; | 2433 _current = value; |
| 2384 if (_current) { | 2434 if (_current) { |
| 2385 _expand(); | 2435 _expand(); |
| 2386 scrollIntoView(); | 2436 scrollIntoView(); |
| 2387 } else { | 2437 } else { |
| 2388 if (_pinned) { | 2438 if (_pinned) { |
| 2389 _expand(); | 2439 _expand(); |
| 2390 } else { | 2440 } else { |
| 2391 _unexpand(); | 2441 _unexpand(); |
| 2392 } | 2442 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2425 if (_pinned) { | 2475 if (_pinned) { |
| 2426 classes.add('shadow'); | 2476 classes.add('shadow'); |
| 2427 } else { | 2477 } else { |
| 2428 classes.remove('shadow'); | 2478 classes.remove('shadow'); |
| 2429 } | 2479 } |
| 2430 if (_current) { | 2480 if (_current) { |
| 2431 classes.add('current'); | 2481 classes.add('current'); |
| 2432 } else { | 2482 } else { |
| 2433 classes.remove('current'); | 2483 classes.remove('current'); |
| 2434 } | 2484 } |
| 2485 if (_frame.kind == M.FrameKind.marker) { |
| 2486 final content = <Element>[ |
| 2487 new SpanElement()..children = _createMarkerHeader(_frame.marker) |
| 2488 ]; |
| 2489 children = content; |
| 2490 return; |
| 2491 } |
| 2435 ButtonElement expandButton; | 2492 ButtonElement expandButton; |
| 2436 final content = <Element>[ | 2493 final content = <Element>[ |
| 2437 expandButton = new ButtonElement() | 2494 expandButton = new ButtonElement() |
| 2438 ..children = _createHeader() | 2495 ..children = _createHeader() |
| 2439 ..onClick.listen((e) async { | 2496 ..onClick.listen((e) async { |
| 2440 if (e.target is AnchorElement) { | 2497 if (e.target is AnchorElement) { |
| 2441 return; | 2498 return; |
| 2442 } | 2499 } |
| 2443 expandButton.disabled = true; | 2500 expandButton.disabled = true; |
| 2444 await _toggleExpand(); | 2501 await _toggleExpand(); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2527 collapseButton.disabled = false; | 2584 collapseButton.disabled = false; |
| 2528 }) | 2585 }) |
| 2529 ..children = [iconExpandLess.clone(true)] | 2586 ..children = [iconExpandLess.clone(true)] |
| 2530 ] | 2587 ] |
| 2531 ] | 2588 ] |
| 2532 ]); | 2589 ]); |
| 2533 } | 2590 } |
| 2534 children = content; | 2591 children = content; |
| 2535 } | 2592 } |
| 2536 | 2593 |
| 2594 List<Element> _createMarkerHeader(String marker) { |
| 2595 final content = [ |
| 2596 new DivElement() |
| 2597 ..classes = ['frameSummaryText'] |
| 2598 ..children = [ |
| 2599 new DivElement() |
| 2600 ..classes = ['frameId'] |
| 2601 ..text = 'Frame ${_frame.index}', |
| 2602 new SpanElement()..text = '$marker', |
| 2603 ] |
| 2604 ]; |
| 2605 return [ |
| 2606 new DivElement() |
| 2607 ..classes = ['frameSummary'] |
| 2608 ..children = content |
| 2609 ]; |
| 2610 } |
| 2611 |
| 2537 List<Element> _createHeader() { | 2612 List<Element> _createHeader() { |
| 2538 final content = [ | 2613 final content = [ |
| 2539 new DivElement() | 2614 new DivElement() |
| 2540 ..classes = ['frameSummaryText'] | 2615 ..classes = ['frameSummaryText'] |
| 2541 ..children = [ | 2616 ..children = [ |
| 2542 new DivElement() | 2617 new DivElement() |
| 2543 ..classes = ['frameId'] | 2618 ..classes = ['frameId'] |
| 2544 ..text = 'Frame ${_frame.index}', | 2619 ..text = 'Frame ${_frame.index}', |
| 2545 new SpanElement() | 2620 new SpanElement() |
| 2546 ..children = _frame.function == null | 2621 ..children = _frame.function == null |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2571 ..classes = ['frameSummary'] | 2646 ..classes = ['frameSummary'] |
| 2572 ..children = content | 2647 ..children = content |
| 2573 ]; | 2648 ]; |
| 2574 } | 2649 } |
| 2575 | 2650 |
| 2576 String makeExpandKey(String key) { | 2651 String makeExpandKey(String key) { |
| 2577 return '${_frame.function.qualifiedName}/${key}'; | 2652 return '${_frame.function.qualifiedName}/${key}'; |
| 2578 } | 2653 } |
| 2579 | 2654 |
| 2580 bool matchFrame(S.Frame newFrame) { | 2655 bool matchFrame(S.Frame newFrame) { |
| 2656 if (newFrame.function == null) { |
| 2657 return frame.function == null; |
| 2658 } |
| 2581 return (newFrame.function.id == _frame.function.id && | 2659 return (newFrame.function.id == _frame.function.id && |
| 2582 newFrame.location.script.id == | 2660 newFrame.location.script.id == |
| 2583 frame.location.script.id); | 2661 frame.location.script.id); |
| 2584 } | 2662 } |
| 2585 | 2663 |
| 2586 void updateFrame(S.Frame newFrame) { | 2664 void updateFrame(S.Frame newFrame) { |
| 2587 assert(matchFrame(newFrame)); | 2665 assert(matchFrame(newFrame)); |
| 2588 _frame = newFrame; | 2666 _frame = newFrame; |
| 2589 } | 2667 } |
| 2590 | 2668 |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3257 ..setAttribute('height', '24') | 3335 ..setAttribute('height', '24') |
| 3258 ..children = [ | 3336 ..children = [ |
| 3259 new PathElement() | 3337 new PathElement() |
| 3260 ..setAttribute( | 3338 ..setAttribute( |
| 3261 'd', | 3339 'd', |
| 3262 'M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 ' | 3340 'M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 ' |
| 3263 '10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 ' | 3341 '10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 ' |
| 3264 '0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 ' | 3342 '0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 ' |
| 3265 '9h2V7h-2v2z') | 3343 '9h2V7h-2v2z') |
| 3266 ]; | 3344 ]; |
| OLD | NEW |