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 trydart.poi; | 5 library trydart.poi.scope_information_visitor; |
6 | 6 |
7 import 'dart:async' show | 7 import 'package:compiler/src/elements/modelx.dart' as modelx; |
8 Completer, | |
9 Future; | |
10 | 8 |
11 import 'dart:io' as io; | 9 import 'package:compiler/src/elements/modelx.dart' show |
12 | 10 CompilationUnitElementX, |
13 import 'dart:convert' show | 11 FieldElementX; |
14 UTF8; | |
15 | |
16 import 'package:dart2js_incremental/dart2js_incremental.dart' show | |
17 reuseCompiler; | |
18 | |
19 import 'package:dart2js_incremental/library_updater.dart' show | |
20 LibraryUpdater; | |
21 | |
22 import 'package:compiler/src/source_file_provider.dart' show | |
23 FormattingDiagnosticHandler; | |
24 | |
25 import 'package:compiler/compiler.dart' as api; | |
26 | |
27 import 'package:compiler/src/dart2jslib.dart' show | |
28 Compiler, | |
29 CompilerTask, | |
30 Enqueuer, | |
31 QueueFilter, | |
32 WorkItem; | |
33 | 12 |
34 import 'package:compiler/src/elements/visitor.dart' show | 13 import 'package:compiler/src/elements/visitor.dart' show |
35 ElementVisitor; | 14 ElementVisitor; |
36 | 15 |
| 16 import 'package:compiler/src/dart2jslib.dart' show |
| 17 Compiler; |
| 18 |
37 import 'package:compiler/src/elements/elements.dart' show | 19 import 'package:compiler/src/elements/elements.dart' show |
38 AbstractFieldElement, | 20 AbstractFieldElement, |
39 ClassElement, | 21 ClassElement, |
40 CompilationUnitElement, | 22 CompilationUnitElement, |
41 Element, | 23 Element, |
42 ElementCategory, | 24 ElementCategory, |
43 FunctionElement, | 25 FunctionElement, |
44 LibraryElement, | 26 LibraryElement, |
45 ScopeContainerElement; | 27 ScopeContainerElement; |
46 | 28 |
47 import 'package:compiler/src/elements/modelx.dart' as modelx; | |
48 | |
49 import 'package:compiler/src/elements/modelx.dart' show | |
50 DeclarationSite; | |
51 | |
52 import 'package:compiler/src/dart_types.dart' show | 29 import 'package:compiler/src/dart_types.dart' show |
53 DartType; | 30 DartType; |
54 | 31 |
55 import 'package:compiler/src/scanner/scannerlib.dart' show | 32 /****************** IGNORE THIS ONLY FOR SMALL DIFF **************************** |
56 EOF_TOKEN, | |
57 IDENTIFIER_TOKEN, | |
58 KEYWORD_TOKEN, | |
59 PartialClassElement, | |
60 PartialElement, | |
61 Token; | |
62 | |
63 import 'package:compiler/src/js/js.dart' show | |
64 js; | |
65 | 33 |
66 /// Enabled by the option --enable-dart-mind. Controls if this program should | 34 /// Enabled by the option --enable-dart-mind. Controls if this program should |
67 /// be querying Dart Mind. | 35 /// be querying Dart Mind. |
68 bool isDartMindEnabled = false; | 36 bool isDartMindEnabled = false; |
69 | 37 |
70 /// Iterator over lines from standard input (or the argument array). | 38 /// Iterator over lines from standard input (or the argument array). |
71 Iterator<String> stdin; | 39 Iterator<String> stdin; |
72 | 40 |
73 /// Enabled by the option --simulate-mutation. When true, this program will | 41 /// Enabled by the option --simulate-mutation. When true, this program will |
74 /// only prompt for one file name, and subsequent runs will read | 42 /// only prompt for one file name, and subsequent runs will read |
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 void processWorkItem(void f(WorkItem work), WorkItem work) { | 506 void processWorkItem(void f(WorkItem work), WorkItem work) { |
539 if (work.element.library.canonicalUri == script) { | 507 if (work.element.library.canonicalUri == script) { |
540 f(work); | 508 f(work); |
541 printWallClock('Processed ${work.element}.'); | 509 printWallClock('Processed ${work.element}.'); |
542 } else { | 510 } else { |
543 printWallClock('Skipped ${work.element}.'); | 511 printWallClock('Skipped ${work.element}.'); |
544 } | 512 } |
545 } | 513 } |
546 } | 514 } |
547 | 515 |
| 516 *******************************************************************************/ |
| 517 |
548 /** | 518 /** |
549 * Serializes scope information about an element. This is accomplished by | 519 * Serializes scope information about an element. This is accomplished by |
550 * calling the [serialize] method on each element. Some elements need special | 520 * calling the [serialize] method on each element. Some elements need special |
551 * treatment, as their enclosing scope must also be serialized. | 521 * treatment, as their enclosing scope must also be serialized. |
552 */ | 522 */ |
553 class ScopeInformationVisitor extends ElementVisitor/* <void> */ { | 523 class ScopeInformationVisitor extends ElementVisitor/* <void> */ { |
554 // TODO(ahe): Include function parameters and local variables. | 524 // TODO(ahe): Include function parameters and local variables. |
555 | 525 |
| 526 final Compiler compiler; |
556 final Element currentElement; | 527 final Element currentElement; |
557 final int position; | 528 final int position; |
558 final StringBuffer buffer = new StringBuffer(); | 529 final StringBuffer buffer = new StringBuffer(); |
559 int indentationLevel = 0; | 530 int indentationLevel = 0; |
560 ClassElement currentClass; | 531 ClassElement currentClass; |
561 | 532 |
562 ScopeInformationVisitor(this.currentElement, this.position); | 533 bool ignoreImports = false; |
| 534 |
| 535 ScopeInformationVisitor(this.compiler, this.currentElement, this.position); |
563 | 536 |
564 String get indentation => ' ' * indentationLevel; | 537 String get indentation => ' ' * indentationLevel; |
565 | 538 |
566 StringBuffer get indented => buffer..write(indentation); | 539 StringBuffer get indented => buffer..write(indentation); |
567 | 540 |
568 void visitElement(Element e) { | 541 void visitElement(Element e) { |
569 serialize(e, omitEnclosing: false); | 542 serialize(e, omitEnclosing: false); |
570 } | 543 } |
571 | 544 |
572 void visitLibraryElement(LibraryElement e) { | 545 void visitLibraryElement(LibraryElement e) { |
573 bool isFirst = true; | 546 bool isFirst = true; |
574 forEach(Element member) { | 547 forEach(Element member) { |
575 if (!isFirst) { | 548 if (!isFirst) { |
576 buffer.write(','); | 549 buffer.write(','); |
577 } | 550 } |
578 buffer.write('\n'); | 551 buffer.write('\n'); |
579 indented; | 552 indented; |
580 serialize(member); | 553 serialize(member); |
581 isFirst = false; | 554 isFirst = false; |
582 } | 555 } |
583 serialize( | 556 serialize( |
584 e, | 557 e, |
585 // TODO(ahe): We omit the import scope if there is no current | 558 // TODO(ahe): We omit the import scope if there is no current |
586 // class. That's wrong. | 559 // class. That's wrong. |
587 omitEnclosing: currentClass == null, | 560 omitEnclosing: ignoreImports || currentClass == null, |
588 name: e.getLibraryName(), | 561 name: e.getLibraryName(), |
589 serializeEnclosing: () { | 562 serializeEnclosing: () { |
590 // The enclosing scope of a library is a scope which contains all the | 563 // The enclosing scope of a library is a scope which contains all the |
591 // imported names. | 564 // imported names. |
592 isFirst = true; | 565 isFirst = true; |
593 buffer.write('{\n'); | 566 buffer.write('{\n'); |
594 indentationLevel++; | 567 indentationLevel++; |
595 indented.write('"kind": "imports",\n'); | 568 indented.write('"kind": "imports",\n'); |
596 indented.write('"members": ['); | 569 indented.write('"members": ['); |
597 indentationLevel++; | 570 indentationLevel++; |
598 importScope(e).importScope.values.forEach(forEach); | 571 sortElements(importScope(e).importScope.values).forEach(forEach); |
599 indentationLevel--; | 572 indentationLevel--; |
600 buffer.write('\n'); | 573 buffer.write('\n'); |
601 indented.write('],\n'); | 574 indented.write('],\n'); |
602 // The enclosing scope of the imported names scope is the superclass | 575 // The enclosing scope of the imported names scope is the superclass |
603 // scope of the current class. | 576 // scope of the current class. |
604 indented.write('"enclosing": '); | 577 indented.write('"enclosing": '); |
605 serializeClassSide( | 578 serializeClassSide( |
606 currentClass.superclass, isStatic: false, includeSuper: true); | 579 currentClass.superclass, isStatic: false, includeSuper: true); |
607 buffer.write('\n'); | 580 buffer.write('\n'); |
608 indentationLevel--; | 581 indentationLevel--; |
609 indented.write('}'); | 582 indented.write('}'); |
610 }, | 583 }, |
611 serializeMembers: () { | 584 serializeMembers: () { |
612 isFirst = true; | 585 isFirst = true; |
613 localScope(e).values.forEach(forEach); | 586 sortElements(localScope(e).values).forEach(forEach); |
614 }); | 587 }); |
615 } | 588 } |
616 | 589 |
617 void visitClassElement(ClassElement e) { | 590 void visitClassElement(ClassElement e) { |
618 currentClass = e; | 591 currentClass = e; |
619 serializeClassSide(e, isStatic: true); | 592 serializeClassSide(e, isStatic: true); |
620 } | 593 } |
621 | 594 |
622 /// Serializes one of the "sides" a class. The sides of a class are "instance | 595 /// Serializes one of the "sides" a class. The sides of a class are "instance |
623 /// side" and "class side". These terms are from Smalltalk. The instance side | 596 /// side" and "class side". These terms are from Smalltalk. The instance side |
624 /// is all the local instance members of the class (the members of the | 597 /// is all the local instance members of the class (the members of the |
625 /// mixin), and the class side is the equivalent for static members and | 598 /// mixin), and the class side is the equivalent for static members and |
626 /// constructors. | 599 /// constructors. |
627 /// The scope chain is ordered so that the "class side" is searched before | 600 /// The scope chain is ordered so that the "class side" is searched before |
628 /// the "instance side". | 601 /// the "instance side". |
629 void serializeClassSide( | 602 void serializeClassSide( |
630 ClassElement e, | 603 ClassElement e, |
631 {bool isStatic: false, | 604 {bool isStatic: false, |
632 bool omitEnclosing: false, | 605 bool omitEnclosing: false, |
633 bool includeSuper: false}) { | 606 bool includeSuper: false}) { |
| 607 e.ensureResolved(compiler); |
634 bool isFirst = true; | 608 bool isFirst = true; |
635 var serializeEnclosing; | 609 var serializeEnclosing; |
636 String kind; | 610 String kind; |
637 if (isStatic) { | 611 if (isStatic) { |
638 kind = 'class side'; | 612 kind = 'class side'; |
639 serializeEnclosing = () { | 613 serializeEnclosing = () { |
640 serializeClassSide(e, isStatic: false, omitEnclosing: omitEnclosing); | 614 serializeClassSide(e, isStatic: false, omitEnclosing: omitEnclosing); |
641 }; | 615 }; |
642 } else { | 616 } else { |
643 kind = 'instance side'; | 617 kind = 'instance side'; |
644 } | 618 } |
645 if (includeSuper) { | 619 if (includeSuper) { |
646 assert(!omitEnclosing && !isStatic); | 620 assert(!omitEnclosing && !isStatic); |
647 if (e.superclass == null) { | 621 if (e.superclass == null) { |
648 omitEnclosing = true; | 622 omitEnclosing = true; |
649 } else { | 623 } else { |
650 // Members of the superclass are represented as a separate scope. | 624 // Members of the superclass are represented as a separate scope. |
651 serializeEnclosing = () { | 625 serializeEnclosing = () { |
652 serializeClassSide( | 626 serializeClassSide( |
653 e.superclass, isStatic: false, omitEnclosing: false, | 627 e.superclass, isStatic: false, omitEnclosing: false, |
654 includeSuper: true); | 628 includeSuper: true); |
655 }; | 629 }; |
656 } | 630 } |
657 } | 631 } |
658 serialize( | 632 serialize( |
659 e, omitEnclosing: omitEnclosing, serializeEnclosing: serializeEnclosing, | 633 e, omitEnclosing: omitEnclosing, serializeEnclosing: serializeEnclosing, |
660 kind: kind, serializeMembers: () { | 634 kind: kind, serializeMembers: () { |
661 e.forEachLocalMember((Element member) { | 635 localMembersSorted(e).forEach((Element member) { |
662 // Filter out members that don't belong to this "side". | 636 // Filter out members that don't belong to this "side". |
663 if (member.isConstructor) { | 637 if (member.isConstructor) { |
664 // In dart2js, some constructors aren't static, but that isn't | 638 // In dart2js, some constructors aren't static, but that isn't |
665 // convenient here. | 639 // convenient here. |
666 if (!isStatic) return; | 640 if (!isStatic) return; |
667 } else if (member.isStatic != isStatic) { | 641 } else if (member.isStatic != isStatic) { |
668 return; | 642 return; |
669 } | 643 } |
670 if (!isFirst) { | 644 if (!isFirst) { |
671 buffer.write(','); | 645 buffer.write(','); |
672 } | 646 } |
673 buffer.write('\n'); | 647 buffer.write('\n'); |
674 indented; | 648 indented; |
675 serialize(member); | 649 serialize(member); |
676 isFirst = false; | 650 isFirst = false; |
677 }); | 651 }); |
678 }); | 652 }); |
679 } | 653 } |
680 | 654 |
681 void visitScopeContainerElement(ScopeContainerElement e) { | 655 void visitScopeContainerElement(ScopeContainerElement e) { |
682 bool isFirst = true; | 656 bool isFirst = true; |
683 serialize(e, omitEnclosing: false, serializeMembers: () { | 657 serialize(e, omitEnclosing: false, serializeMembers: () { |
684 e.forEachLocalMember((Element member) { | 658 localMembersSorted(e).forEach((Element member) { |
685 if (!isFirst) { | 659 if (!isFirst) { |
686 buffer.write(','); | 660 buffer.write(','); |
687 } | 661 } |
688 buffer.write('\n'); | 662 buffer.write('\n'); |
689 indented; | 663 indented; |
690 serialize(member); | 664 serialize(member); |
691 isFirst = false; | 665 isFirst = false; |
692 }); | 666 }); |
693 }); | 667 }); |
694 } | 668 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 kind: kind, | 708 kind: kind, |
735 name: name); | 709 name: name); |
736 } | 710 } |
737 return; | 711 return; |
738 } | 712 } |
739 DartType type; | 713 DartType type; |
740 int category = element.kind.category; | 714 int category = element.kind.category; |
741 if (category == ElementCategory.FUNCTION || | 715 if (category == ElementCategory.FUNCTION || |
742 category == ElementCategory.VARIABLE || | 716 category == ElementCategory.VARIABLE || |
743 element.isConstructor) { | 717 element.isConstructor) { |
744 type = element.computeType(cachedCompiler); | 718 type = element.computeType(compiler); |
745 } | 719 } |
746 if (name == null) { | 720 if (name == null) { |
747 name = element.name; | 721 name = element.name; |
748 } | 722 } |
749 if (kind == null) { | 723 if (kind == null) { |
750 kind = '${element.kind}'; | 724 kind = '${element.kind}'; |
751 } | 725 } |
752 buffer.write('{\n'); | 726 buffer.write('{\n'); |
753 indentationLevel++; | 727 indentationLevel++; |
754 if (name != '') { | 728 if (name != '') { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
791 indented.write('}'); | 765 indented.write('}'); |
792 } | 766 } |
793 } | 767 } |
794 | 768 |
795 modelx.ScopeX localScope(modelx.LibraryElementX element) => element.localScope; | 769 modelx.ScopeX localScope(modelx.LibraryElementX element) => element.localScope; |
796 | 770 |
797 modelx.ImportScope importScope(modelx.LibraryElementX element) { | 771 modelx.ImportScope importScope(modelx.LibraryElementX element) { |
798 return element.importScope; | 772 return element.importScope; |
799 } | 773 } |
800 | 774 |
801 class PoiTask extends CompilerTask { | 775 List<Element> localMembersSorted(ScopeContainerElement element) { |
802 PoiTask(Compiler compiler) : super(compiler); | 776 List<Element> result = <Element>[]; |
| 777 element.forEachLocalMember((Element member) { |
| 778 result.add(member); |
| 779 }); |
| 780 return sortElements(result); |
| 781 } |
803 | 782 |
804 String get name => 'POI'; | 783 List<Element> sortElements(Iterable<Element> elements) { |
| 784 return new List<Element>.from(elements) |
| 785 ..sort((Element a, Element b) => a.name.compareTo(b.name)); |
805 } | 786 } |
OLD | NEW |