| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 script_inset_element; | 5 library script_inset_element; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:html'; | 8 import 'dart:html'; |
| 9 import 'observatory_element.dart'; | 9 import 'observatory_element.dart'; |
| 10 import 'service_ref.dart'; | 10 import 'service_ref.dart'; |
| 11 import 'package:observatory/service.dart'; | 11 import 'package:observatory/service.dart'; |
| 12 import 'package:observatory/utils.dart'; | 12 import 'package:observatory/utils.dart'; |
| 13 import 'package:polymer/polymer.dart'; | 13 import 'package:polymer/polymer.dart'; |
| 14 import 'package:logging/logging.dart'; |
| 14 | 15 |
| 15 const nbsp = "\u00A0"; | 16 const nbsp = "\u00A0"; |
| 16 | 17 |
| 17 void addInfoBox(Element content, Function infoBoxGenerator) { | 18 void addInfoBox(Element content, Function infoBoxGenerator) { |
| 18 var infoBox; | 19 var infoBox; |
| 19 var show = false; | 20 var show = false; |
| 20 var originalBackground = content.style.backgroundColor; | 21 var originalBackground = content.style.backgroundColor; |
| 21 buildInfoBox() { | 22 buildInfoBox() { |
| 22 infoBox = infoBoxGenerator(); | 23 infoBox = infoBoxGenerator(); |
| 23 infoBox.style.position = 'absolute'; | 24 infoBox.style.position = 'absolute'; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 class CurrentExecutionAnnotation extends Annotation { | 92 class CurrentExecutionAnnotation extends Annotation { |
| 92 void applyStyleTo(element) { | 93 void applyStyleTo(element) { |
| 93 if (element == null) { | 94 if (element == null) { |
| 94 return; // TODO(rmacnak): Handling overlapping annotations. | 95 return; // TODO(rmacnak): Handling overlapping annotations. |
| 95 } | 96 } |
| 96 element.classes.add("currentCol"); | 97 element.classes.add("currentCol"); |
| 97 element.title = "Current execution"; | 98 element.title = "Current execution"; |
| 98 } | 99 } |
| 99 } | 100 } |
| 100 | 101 |
| 102 class LibraryAnnotation extends Annotation { |
| 103 Library target; |
| 104 LibraryAnnotation(this.target); |
| 105 |
| 106 void applyStyleTo(element) { |
| 107 if (element == null) { |
| 108 return; // TODO(rmacnak): Handling overlapping annotations. |
| 109 } |
| 110 element.style.fontWeight = "bold"; |
| 111 element.title = "library ${target.uri}"; |
| 112 |
| 113 addInfoBox(element, () { |
| 114 var details = table(); |
| 115 var r = row(); |
| 116 r.append(cell("Library")); |
| 117 r.append(cell(serviceRef(target))); |
| 118 details.append(r); |
| 119 |
| 120 return details; |
| 121 }); |
| 122 } |
| 123 } |
| 124 |
| 125 class PartAnnotation extends Annotation { |
| 126 Script part; |
| 127 PartAnnotation(this.part); |
| 128 |
| 129 void applyStyleTo(element) { |
| 130 if (element == null) { |
| 131 return; // TODO(rmacnak): Handling overlapping annotations. |
| 132 } |
| 133 element.style.fontWeight = "bold"; |
| 134 element.title = "script ${part.uri}"; |
| 135 |
| 136 addInfoBox(element, () { |
| 137 var details = table(); |
| 138 var r = row(); |
| 139 r.append(cell("Script")); |
| 140 r.append(cell(serviceRef(part))); |
| 141 details.append(r); |
| 142 |
| 143 return details; |
| 144 }); |
| 145 } |
| 146 } |
| 147 |
| 101 class LocalVariableAnnotation extends Annotation { | 148 class LocalVariableAnnotation extends Annotation { |
| 102 final value; | 149 final value; |
| 103 | 150 |
| 104 LocalVariableAnnotation(LocalVarLocation location, this.value) { | 151 LocalVariableAnnotation(LocalVarLocation location, this.value) { |
| 105 line = location.line; | 152 line = location.line; |
| 106 columnStart = location.column; | 153 columnStart = location.column; |
| 107 columnStop = location.endColumn; | 154 columnStop = location.endColumn; |
| 108 } | 155 } |
| 109 | 156 |
| 110 void applyStyleTo(element) { | 157 void applyStyleTo(element) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 abstract class DeclarationAnnotation extends Annotation { | 209 abstract class DeclarationAnnotation extends Annotation { |
| 163 DeclarationAnnotation(decl) { | 210 DeclarationAnnotation(decl) { |
| 164 assert(decl.loaded); | 211 assert(decl.loaded); |
| 165 SourceLocation location = decl.location; | 212 SourceLocation location = decl.location; |
| 166 if (location == null) { | 213 if (location == null) { |
| 167 line = 0; | 214 line = 0; |
| 168 columnStart = 0; | 215 columnStart = 0; |
| 169 columnStop = 0; | 216 columnStop = 0; |
| 170 return; | 217 return; |
| 171 } | 218 } |
| 219 |
| 172 Script script = location.script; | 220 Script script = location.script; |
| 173 line = script.tokenToLine(location.tokenPos); | 221 line = script.tokenToLine(location.tokenPos); |
| 174 columnStart = script.tokenToCol(location.tokenPos); | 222 columnStart = script.tokenToCol(location.tokenPos); |
| 175 if ((line == null) || (columnStart == null)) { | 223 if ((line == null) || (columnStart == null)) { |
| 176 line = 0; | 224 line = 0; |
| 177 columnStart = 0; | 225 columnStart = 0; |
| 178 columnStop = 0; | 226 columnStop = 0; |
| 179 } else { | 227 } else { |
| 180 columnStart--; // 1-origin -> 0-origin. | 228 columnStart--; // 1-origin -> 0-origin. |
| 181 | 229 |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 _endLine = (endPos != null | 496 _endLine = (endPos != null |
| 449 ? script.tokenToLine(endPos) | 497 ? script.tokenToLine(endPos) |
| 450 : script.lines.length + script.lineOffset); | 498 : script.lines.length + script.lineOffset); |
| 451 | 499 |
| 452 annotations.clear(); | 500 annotations.clear(); |
| 453 | 501 |
| 454 addCurrentExecutionAnnotation(); | 502 addCurrentExecutionAnnotation(); |
| 455 | 503 |
| 456 if (!inDebuggerContext && script.library != null) { | 504 if (!inDebuggerContext && script.library != null) { |
| 457 loadDeclarationsOfLibrary(script.library); | 505 loadDeclarationsOfLibrary(script.library); |
| 458 | 506 addLibraryAnnotations(); |
| 459 // Add fields before functions so they beat out conflicting | 507 addDependencyAnnotations(); |
| 460 // implicit g/setters. | 508 addPartAnnotations(); |
| 461 addClassAnnotations(); | 509 addClassAnnotations(); |
| 462 addFieldAnnotations(); | 510 addFieldAnnotations(); |
| 463 addFunctionAnnotations(); | 511 addFunctionAnnotations(); |
| 464 addCallSiteAnnotations(); | 512 addCallSiteAnnotations(); |
| 465 } | 513 } |
| 466 | 514 |
| 467 addLocalVariableAnnotations(); | 515 addLocalVariableAnnotations(); |
| 468 | 516 |
| 469 annotations.sort(); | 517 annotations.sort(); |
| 470 } | 518 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 493 func.load(); | 541 func.load(); |
| 494 } | 542 } |
| 495 for (var field in cls.fields) { | 543 for (var field in cls.fields) { |
| 496 field.load(); | 544 field.load(); |
| 497 } | 545 } |
| 498 }); | 546 }); |
| 499 } | 547 } |
| 500 }); | 548 }); |
| 501 } | 549 } |
| 502 | 550 |
| 551 void addLibraryAnnotations() { |
| 552 for (ScriptLine line in script.lines) { |
| 553 // TODO(rmacnak): Use a real scanner. |
| 554 var pattern = new RegExp("library ${script.library.name}"); |
| 555 var match = pattern.firstMatch(line.text); |
| 556 if (match != null) { |
| 557 var anno = new LibraryAnnotation(script.library); |
| 558 anno.line = line.line; |
| 559 anno.columnStart = match.start + 8; |
| 560 anno.columnStop = match.end; |
| 561 annotations.add(anno); |
| 562 } |
| 563 // TODO(rmacnak): Use a real scanner. |
| 564 pattern = new RegExp("part of ${script.library.name}"); |
| 565 match = pattern.firstMatch(line.text); |
| 566 if (match != null) { |
| 567 var anno = new LibraryAnnotation(script.library); |
| 568 anno.line = line.line; |
| 569 anno.columnStart = match.start + 8; |
| 570 anno.columnStop = match.end; |
| 571 annotations.add(anno); |
| 572 } |
| 573 } |
| 574 } |
| 575 |
| 576 Library resolveDependency(String relativeUri) { |
| 577 var targetUri = Uri.parse(script.library.uri).resolve(relativeUri); |
| 578 for (Library l in script.isolate.libraries) { |
| 579 if (targetUri.toString() == l.uri) { |
| 580 return l; |
| 581 } |
| 582 } |
| 583 Logger.root.info("Could not resolve library dependency: $relativeUri"); |
| 584 return null; |
| 585 } |
| 586 |
| 587 void addDependencyAnnotations() { |
| 588 // TODO(rmacnak): Use a real scanner. |
| 589 var patterns = [ |
| 590 new RegExp("import '(.*)'"), |
| 591 new RegExp('import "(.*)"'), |
| 592 new RegExp("export '(.*)'"), |
| 593 new RegExp('export "(.*)"'), |
| 594 ]; |
| 595 for (ScriptLine line in script.lines) { |
| 596 for (var pattern in patterns) { |
| 597 var match = pattern.firstMatch(line.text); |
| 598 if (match != null) { |
| 599 Library target = resolveDependency(match[1]); |
| 600 if (target != null) { |
| 601 var anno = new LibraryAnnotation(target); |
| 602 anno.line = line.line; |
| 603 anno.columnStart = match.start + 8; |
| 604 anno.columnStop = match.end - 1; |
| 605 annotations.add(anno); |
| 606 } |
| 607 } |
| 608 } |
| 609 } |
| 610 } |
| 611 |
| 612 Script resolvePart(String relativeUri) { |
| 613 var rootUri = Uri.parse(script.library.uri); |
| 614 if (rootUri.scheme == 'dart') { |
| 615 // The relative paths from dart:* libraries to their parts are not valid. |
| 616 rootUri = new Uri.directory(script.library.uri); |
| 617 } |
| 618 var targetUri = rootUri.resolve(relativeUri); |
| 619 for (Script s in script.library.scripts) { |
| 620 if (targetUri.toString() == s.uri) { |
| 621 return s; |
| 622 } |
| 623 } |
| 624 Logger.root.info("Could not resolve part: $relativeUri"); |
| 625 return null; |
| 626 } |
| 627 |
| 628 void addPartAnnotations() { |
| 629 // TODO(rmacnak): Use a real scanner. |
| 630 var patterns = [ |
| 631 new RegExp("part '(.*)'"), |
| 632 new RegExp('part "(.*)"'), |
| 633 ]; |
| 634 for (ScriptLine line in script.lines) { |
| 635 for (var pattern in patterns) { |
| 636 var match = pattern.firstMatch(line.text); |
| 637 if (match != null) { |
| 638 Script part = resolvePart(match[1]); |
| 639 if (part != null) { |
| 640 var anno = new PartAnnotation(part); |
| 641 anno.line = line.line; |
| 642 anno.columnStart = match.start + 6; |
| 643 anno.columnStop = match.end - 1; |
| 644 annotations.add(anno); |
| 645 } |
| 646 } |
| 647 } |
| 648 } |
| 649 } |
| 650 |
| 503 void addClassAnnotations() { | 651 void addClassAnnotations() { |
| 504 for (var cls in script.library.classes) { | 652 for (var cls in script.library.classes) { |
| 505 if ((cls.location != null) && (cls.location.script == script)) { | 653 if ((cls.location != null) && (cls.location.script == script)) { |
| 506 annotations.add(new ClassDeclarationAnnotation(cls)); | 654 annotations.add(new ClassDeclarationAnnotation(cls)); |
| 507 } | 655 } |
| 508 } | 656 } |
| 509 } | 657 } |
| 510 | 658 |
| 511 void addFieldAnnotations() { | 659 void addFieldAnnotations() { |
| 512 for (var field in script.library.variables) { | 660 for (var field in script.library.variables) { |
| 513 if ((field.location != null) && (field.location.script == script)) { | 661 if ((field.location != null) && (field.location.script == script)) { |
| 514 annotations.add(new FieldDeclarationAnnotation(field)); | 662 annotations.add(new FieldDeclarationAnnotation(field)); |
| 515 } | 663 } |
| 516 } | 664 } |
| 517 for (var cls in script.library.classes) { | 665 for (var cls in script.library.classes) { |
| 518 for (var field in cls.fields) { | 666 for (var field in cls.fields) { |
| 519 if ((field.location != null) && (field.location.script == script)) { | 667 if ((field.location != null) && (field.location.script == script)) { |
| 520 annotations.add(new FieldDeclarationAnnotation(field)); | 668 annotations.add(new FieldDeclarationAnnotation(field)); |
| 521 } | 669 } |
| 522 } | 670 } |
| 523 } | 671 } |
| 524 } | 672 } |
| 525 | 673 |
| 526 void addFunctionAnnotations() { | 674 void addFunctionAnnotations() { |
| 527 for (var func in script.library.functions) { | 675 for (var func in script.library.functions) { |
| 528 if ((func.location != null) && (func.location.script == script)) { | 676 if ((func.location != null) && |
| 677 (func.location.script == script) && |
| 678 (func.kind != FunctionKind.kImplicitGetterFunction) && |
| 679 (func.kind != FunctionKind.kImplicitSetterFunction)) { |
| 680 // We annotate a field declaration with the field instead of the |
| 681 // implicit getter or setter. |
| 529 annotations.add(new FunctionDeclarationAnnotation(func)); | 682 annotations.add(new FunctionDeclarationAnnotation(func)); |
| 530 } | 683 } |
| 531 } | 684 } |
| 532 for (var cls in script.library.classes) { | 685 for (var cls in script.library.classes) { |
| 533 for (var func in cls.functions) { | 686 for (var func in cls.functions) { |
| 534 if ((func.location != null) && (func.location.script == script)) { | 687 if ((func.location != null) && |
| 688 (func.location.script == script) && |
| 689 (func.kind != FunctionKind.kImplicitGetterFunction) && |
| 690 (func.kind != FunctionKind.kImplicitSetterFunction)) { |
| 691 // We annotate a field declaration with the field instead of the |
| 692 // implicit getter or setter. |
| 535 annotations.add(new FunctionDeclarationAnnotation(func)); | 693 annotations.add(new FunctionDeclarationAnnotation(func)); |
| 536 } | 694 } |
| 537 } | 695 } |
| 538 } | 696 } |
| 539 } | 697 } |
| 540 | 698 |
| 541 void addCallSiteAnnotations() { | 699 void addCallSiteAnnotations() { |
| 542 for (var callSite in script.callSites) { | 700 for (var callSite in script.callSites) { |
| 543 annotations.add(new CallSiteAnnotation(callSite)); | 701 annotations.add(new CallSiteAnnotation(callSite)); |
| 544 } | 702 } |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 class SourceInsetElement extends PolymerElement { | 927 class SourceInsetElement extends PolymerElement { |
| 770 SourceInsetElement.created() : super.created(); | 928 SourceInsetElement.created() : super.created(); |
| 771 | 929 |
| 772 @published SourceLocation location; | 930 @published SourceLocation location; |
| 773 @published String height = null; | 931 @published String height = null; |
| 774 @published int currentPos; | 932 @published int currentPos; |
| 775 @published bool inDebuggerContext = false; | 933 @published bool inDebuggerContext = false; |
| 776 @published ObservableList variables; | 934 @published ObservableList variables; |
| 777 } | 935 } |
| 778 | 936 |
| OLD | NEW |