Chromium Code Reviews| 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 tree_ir_nodes; | 5 library tree_ir_nodes; |
| 6 | 6 |
| 7 import '../constants/expressions.dart'; | 7 import '../constants/expressions.dart'; |
| 8 import '../constants/values.dart' as values; | 8 import '../constants/values.dart' as values; |
| 9 import '../dart_types.dart' show DartType, GenericType, InterfaceType, TypeVaria bleType; | 9 import '../dart_types.dart' show DartType, GenericType, InterfaceType, TypeVaria bleType; |
| 10 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
| 11 import '../io/source_information.dart' show SourceInformation; | 11 import '../io/source_information.dart' show SourceInformation; |
| 12 import '../universe/universe.dart'; | 12 import '../universe/universe.dart'; |
| 13 import '../universe/universe.dart' show Selector; | 13 import '../universe/universe.dart' show Selector; |
| 14 import 'optimization/optimization.dart'; | |
| 15 | 14 |
| 16 // The Tree language is the target of translation out of the CPS-based IR. | 15 // The Tree language is the target of translation out of the CPS-based IR. |
| 17 // | 16 // |
| 18 // The translation from CPS to Dart consists of several stages. Among the | 17 // The translation from CPS to Dart consists of several stages. Among the |
| 19 // stages are translation to direct style, translation out of SSA, eliminating | 18 // stages are translation to direct style, translation out of SSA, eliminating |
| 20 // unnecessary names, recognizing high-level control constructs. Combining | 19 // unnecessary names, recognizing high-level control constructs. Combining |
| 21 // these separate concerns is complicated and the constraints of the CPS-based | 20 // these separate concerns is complicated and the constraints of the CPS-based |
| 22 // language do not permit a multi-stage translation. | 21 // language do not permit a multi-stage translation. |
| 23 // | 22 // |
| 24 // For that reason, CPS is translated to the direct-style language Tree. | 23 // For that reason, CPS is translated to the direct-style language Tree. |
| (...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 593 Expression expression; | 592 Expression expression; |
| 594 | 593 |
| 595 ExpressionStatement(this.expression, this.next); | 594 ExpressionStatement(this.expression, this.next); |
| 596 | 595 |
| 597 accept(StatementVisitor visitor) => visitor.visitExpressionStatement(this); | 596 accept(StatementVisitor visitor) => visitor.visitExpressionStatement(this); |
| 598 accept1(StatementVisitor1 visitor, arg) { | 597 accept1(StatementVisitor1 visitor, arg) { |
| 599 return visitor.visitExpressionStatement(this, arg); | 598 return visitor.visitExpressionStatement(this, arg); |
| 600 } | 599 } |
| 601 } | 600 } |
| 602 | 601 |
| 603 // TODO(kmillikin): Do we want this 'TryStatement'? Other than | |
| 604 // LabeledStatement and EmptyStatement, the statement class names are not | |
| 605 // suffixed with 'Statement'. | |
| 606 class Try extends Statement { | 602 class Try extends Statement { |
| 607 Statement tryBody; | 603 Statement tryBody; |
| 608 List<Variable> catchParameters; | 604 List<Variable> catchParameters; |
| 609 Statement catchBody; | 605 Statement catchBody; |
| 610 | 606 |
| 611 Statement get next => null; | 607 Statement get next => null; |
| 612 void set next(Statement s) => throw 'UNREACHABLE'; | 608 void set next(Statement s) => throw 'UNREACHABLE'; |
| 613 | 609 |
| 614 Try(this.tryBody, this.catchParameters, this.catchBody) { | 610 Try(this.tryBody, this.catchParameters, this.catchBody) { |
| 615 for (Variable variable in catchParameters) { | 611 for (Variable variable in catchParameters) { |
| 616 variable.writeCount++; // Being a catch parameter counts as a write. | 612 variable.writeCount++; // Being a catch parameter counts as a write. |
| 617 } | 613 } |
| 618 } | 614 } |
| 619 | 615 |
| 620 accept(StatementVisitor visitor) => visitor.visitTry(this); | 616 accept(StatementVisitor visitor) => visitor.visitTry(this); |
| 621 accept1(StatementVisitor1 visitor, arg) { | 617 accept1(StatementVisitor1 visitor, arg) { |
| 622 return visitor.visitTry(this, arg); | 618 return visitor.visitTry(this, arg); |
| 623 } | 619 } |
| 624 } | 620 } |
| 625 | 621 |
| 626 abstract class ExecutableDefinition { | 622 abstract class RootNode extends Node { |
| 627 ExecutableElement get element; | 623 ExecutableElement get element; |
| 628 Statement body; | 624 List<Variable> get parameters; |
| 629 | 625 |
| 630 applyPass(Pass pass); | 626 /// True if there is no body for this root node. |
| 627 /// | |
| 628 /// In some parts of the compiler, empty root nodes are used as placeholders | |
| 629 /// for abstract methods, external constructors, fields without initializers, | |
| 630 /// etc. | |
| 631 bool get isEmpty; | |
|
Kevin Millikin (Google)
2015/04/08 15:10:15
If this really means it is missing the optional bo
asgerf
2015/04/09 09:58:23
Constructors have multiple bodies (because of init
| |
| 632 | |
| 633 void forEachBody(void action(Statement node)); | |
| 634 void replaceEachBody(Statement transform(Statement node)); | |
| 635 | |
| 636 accept(RootVisitor v); | |
| 637 accept1(RootVisitor1 v, arg); | |
| 631 } | 638 } |
| 632 | 639 |
| 633 class FieldDefinition extends Node implements ExecutableDefinition { | 640 class FieldDefinition extends RootNode implements DartSpecificNode { |
| 634 final FieldElement element; | 641 final FieldElement element; |
| 635 // The `body` of a field is its initializer. | 642 // The `body` of a field is its initializer. |
| 636 Statement body; | 643 Statement body; |
| 644 List<Variable> get parameters => const <Variable>[]; | |
| 637 | 645 |
| 638 FieldDefinition(this.element, this.body); | 646 FieldDefinition(this.element, this.body); |
| 639 applyPass(Pass pass) => pass.rewriteFieldDefinition(this); | |
| 640 | 647 |
| 641 /// `true` if this field has no initializer. | 648 bool get isEmpty => body == null; |
| 642 /// | 649 |
| 643 /// If `true` [body] is `null`. | 650 accept(RootVisitor v) => v.visitFieldDefinition(this); |
| 644 /// | 651 accept1(RootVisitor1 v, arg) => v.visitFieldDefinition(this, arg); |
| 645 /// This is different from a initializer that is `null`. Consider this class: | 652 |
| 646 /// | 653 void forEachBody(void action(Statement node)) { |
| 647 /// class Class { | 654 if (isEmpty) return; |
| 648 /// final field; | 655 action(body); |
| 649 /// Class.a(this.field); | 656 } |
| 650 /// Class.b() : this.field = null; | 657 |
| 651 /// Class.c(); | 658 void replaceEachBody(Statement transform(Statement node)) { |
| 652 /// } | 659 if (isEmpty) return; |
| 653 /// | 660 body = transform(body); |
| 654 /// If `field` had an initializer, possibly `null`, constructors `Class.a` and | 661 } |
| 655 /// `Class.b` would be invalid, and since `field` has no initializer | |
| 656 /// constructor `Class.c` is invalid. We therefore need to distinguish the two | |
| 657 /// cases. | |
| 658 bool get hasInitializer => body != null; | |
| 659 } | 662 } |
| 660 | 663 |
| 661 class FunctionDefinition extends Node implements ExecutableDefinition { | 664 class FunctionDefinition extends RootNode { |
| 662 final FunctionElement element; | 665 final FunctionElement element; |
| 663 final List<Variable> parameters; | 666 final List<Variable> parameters; |
| 664 Statement body; | 667 Statement body; |
| 665 final List<ConstDeclaration> localConstants; | 668 final List<ConstDeclaration> localConstants; |
| 666 final List<ConstantExpression> defaultParameterValues; | 669 final List<ConstantExpression> defaultParameterValues; |
| 667 | 670 |
| 668 /// Creates a function definition and updates `writeCount` for [parameters]. | 671 /// Creates a function definition and updates `writeCount` for [parameters]. |
| 669 FunctionDefinition(this.element, this.parameters, this.body, | 672 FunctionDefinition(this.element, this.parameters, this.body, |
| 670 this.localConstants, this.defaultParameterValues) { | 673 this.localConstants, this.defaultParameterValues) { |
| 671 for (Variable param in parameters) { | 674 for (Variable param in parameters) { |
| 672 param.writeCount++; // Being a parameter counts as a write. | 675 param.writeCount++; // Being a parameter counts as a write. |
| 673 } | 676 } |
| 674 } | 677 } |
| 675 | 678 |
| 676 /// Returns `true` if this function is abstract. | 679 bool get isEmpty => body == null; |
| 677 /// | 680 |
| 678 /// If `true` [body] is `null` and [localConstants] is empty. | 681 accept(RootVisitor v) => v.visitFunctionDefinition(this); |
| 679 bool get isAbstract => body == null; | 682 accept1(RootVisitor1 v, arg) => v.visitFunctionDefinition(this, arg); |
| 680 applyPass(Pass pass) => pass.rewriteFunctionDefinition(this); | 683 |
| 684 void forEachBody(void action(Statement node)) { | |
| 685 if (isEmpty) return; | |
| 686 action(body); | |
| 687 } | |
| 688 | |
| 689 void replaceEachBody(Statement transform(Statement node)) { | |
| 690 if (isEmpty) return; | |
| 691 body = transform(body); | |
| 692 } | |
| 681 } | 693 } |
| 682 | 694 |
| 683 abstract class Initializer implements Expression, DartSpecificNode {} | 695 abstract class Initializer implements DartSpecificNode { |
| 696 accept(InitializerVisitor v); | |
| 697 accept1(InitializerVisitor1 v, arg); | |
| 698 | |
| 699 void forEachBody(void action(Statement node)); | |
|
Kevin Millikin (Google)
2015/04/08 15:10:15
The body of an initializer is a little weird, it d
asgerf
2015/04/09 09:58:23
Initializers are super awkward.
| |
| 700 void replaceEachBody(Statement transform(Statement node)); | |
| 701 } | |
| 684 | 702 |
| 685 class FieldInitializer extends Initializer { | 703 class FieldInitializer extends Initializer { |
| 686 final FieldElement element; | 704 final FieldElement element; |
| 687 Statement body; | 705 Statement body; |
| 688 bool processed = false; | 706 bool processed = false; |
| 689 | 707 |
| 690 FieldInitializer(this.element, this.body); | 708 FieldInitializer(this.element, this.body); |
| 691 | 709 |
| 692 accept(ExpressionVisitor visitor) => visitor.visitFieldInitializer(this); | 710 accept(InitializerVisitor visitor) => visitor.visitFieldInitializer(this); |
| 693 accept1(ExpressionVisitor1 visitor, arg) { | 711 accept1(InitializerVisitor1 visitor, arg) { |
| 694 return visitor.visitFieldInitializer(this, arg); | 712 return visitor.visitFieldInitializer(this, arg); |
| 695 } | 713 } |
| 714 | |
| 715 void forEachBody(void action(Statement node)) { | |
| 716 action(body); | |
| 717 } | |
| 718 | |
| 719 void replaceEachBody(Statement transform(Statement node)) { | |
| 720 body = transform(body); | |
| 721 } | |
| 696 } | 722 } |
| 697 | 723 |
| 698 class SuperInitializer extends Initializer { | 724 class SuperInitializer extends Initializer { |
| 699 final ConstructorElement target; | 725 final ConstructorElement target; |
| 700 final Selector selector; | 726 final Selector selector; |
| 701 final List<Statement> arguments; | 727 final List<Statement> arguments; |
| 702 bool processed = false; | 728 bool processed = false; |
| 703 | 729 |
| 704 SuperInitializer(this.target, this.selector, this.arguments); | 730 SuperInitializer(this.target, this.selector, this.arguments); |
| 705 accept(ExpressionVisitor visitor) => visitor.visitSuperInitializer(this); | 731 accept(InitializerVisitor visitor) => visitor.visitSuperInitializer(this); |
| 706 accept1(ExpressionVisitor1 visitor, arg) { | 732 accept1(InitializerVisitor1 visitor, arg) { |
| 707 return visitor.visitSuperInitializer(this, arg); | 733 return visitor.visitSuperInitializer(this, arg); |
| 708 } | 734 } |
| 735 | |
| 736 void forEachBody(void action(Statement node)) { | |
| 737 arguments.forEach(action); | |
| 738 } | |
| 739 | |
| 740 void replaceEachBody(Statement transform(Statement node)) { | |
| 741 for (int i=0; i < arguments.length; i++) { | |
|
Kevin Millikin (Google)
2015/04/08 15:10:15
There should be spaces around the assignment opera
asgerf
2015/04/09 09:58:23
Done.
| |
| 742 arguments[i] = transform(arguments[i]); | |
| 743 } | |
| 744 } | |
| 709 } | 745 } |
| 710 | 746 |
| 711 class ConstructorDefinition extends FunctionDefinition { | 747 class ConstructorDefinition extends RootNode |
| 748 implements DartSpecificNode { | |
| 749 final ConstructorElement element; | |
| 750 final List<Variable> parameters; | |
| 751 Statement body; | |
| 752 final List<ConstDeclaration> localConstants; | |
| 753 final List<ConstantExpression> defaultParameterValues; | |
| 712 final List<Initializer> initializers; | 754 final List<Initializer> initializers; |
| 713 | 755 |
| 714 ConstructorDefinition(ConstructorElement element, | 756 ConstructorDefinition(this.element, |
| 715 List<Variable> parameters, | 757 this.parameters, |
| 716 Statement body, | 758 this.body, |
| 717 this.initializers, | 759 this.initializers, |
| 718 List<ConstDeclaration> localConstants, | 760 this.localConstants, |
| 719 List<ConstantExpression> defaultParameterValues) | 761 this.defaultParameterValues) { |
| 720 : super(element, parameters, body, localConstants, | 762 for (Variable param in parameters) { |
| 721 defaultParameterValues); | 763 param.writeCount++; // Being a parameter counts as a write. |
| 764 } | |
| 765 } | |
| 722 | 766 |
| 723 applyPass(Pass pass) => pass.rewriteConstructorDefinition(this); | 767 bool get isEmpty => body == null; |
| 768 | |
| 769 accept(RootVisitor v) => v.visitConstructorDefinition(this); | |
| 770 accept1(RootVisitor1 v, arg) => v.visitConstructorDefinition(this, arg); | |
| 771 | |
| 772 void forEachBody(void action(Statement node)) { | |
| 773 if (isEmpty) return; | |
| 774 for (Initializer init in initializers) { | |
| 775 init.forEachBody(action); | |
| 776 } | |
| 777 action(body); | |
| 778 } | |
| 779 | |
| 780 void replaceEachBody(Statement transform(Statement node)) { | |
| 781 if (isEmpty) return; | |
| 782 for (Initializer init in initializers) { | |
| 783 init.replaceEachBody(transform); | |
| 784 } | |
| 785 body = transform(body); | |
| 786 } | |
| 724 } | 787 } |
| 725 | 788 |
| 726 abstract class JsSpecificNode implements Node {} | 789 abstract class JsSpecificNode implements Node {} |
| 727 | 790 |
| 728 abstract class DartSpecificNode implements Node {} | 791 abstract class DartSpecificNode implements Node {} |
| 729 | 792 |
| 730 class CreateBox extends Expression implements JsSpecificNode { | 793 class CreateBox extends Expression implements JsSpecificNode { |
| 731 accept(ExpressionVisitor visitor) => visitor.visitCreateBox(this); | 794 accept(ExpressionVisitor visitor) => visitor.visitCreateBox(this); |
| 732 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitCreateBox(this, arg); | 795 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitCreateBox(this, arg); |
| 733 } | 796 } |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 808 accept(ExpressionVisitor visitor) { | 871 accept(ExpressionVisitor visitor) { |
| 809 return visitor.visitTypeExpression(this); | 872 return visitor.visitTypeExpression(this); |
| 810 } | 873 } |
| 811 | 874 |
| 812 accept1(ExpressionVisitor1 visitor, arg) { | 875 accept1(ExpressionVisitor1 visitor, arg) { |
| 813 return visitor.visitTypeExpression(this, arg); | 876 return visitor.visitTypeExpression(this, arg); |
| 814 } | 877 } |
| 815 } | 878 } |
| 816 | 879 |
| 817 abstract class ExpressionVisitor<E> { | 880 abstract class ExpressionVisitor<E> { |
| 818 E visitExpression(Expression e) => e.accept(this); | 881 E visitExpression(Expression node) => node.accept(this); |
| 819 E visitVariableUse(VariableUse node); | 882 E visitVariableUse(VariableUse node); |
| 820 E visitInvokeStatic(InvokeStatic node); | 883 E visitInvokeStatic(InvokeStatic node); |
| 821 E visitInvokeMethod(InvokeMethod node); | 884 E visitInvokeMethod(InvokeMethod node); |
| 822 E visitInvokeMethodDirectly(InvokeMethodDirectly node); | 885 E visitInvokeMethodDirectly(InvokeMethodDirectly node); |
| 823 E visitInvokeConstructor(InvokeConstructor node); | 886 E visitInvokeConstructor(InvokeConstructor node); |
| 824 E visitConcatenateStrings(ConcatenateStrings node); | 887 E visitConcatenateStrings(ConcatenateStrings node); |
| 825 E visitConstant(Constant node); | 888 E visitConstant(Constant node); |
| 826 E visitThis(This node); | 889 E visitThis(This node); |
| 827 E visitReifyTypeVar(ReifyTypeVar node); | 890 E visitReifyTypeVar(ReifyTypeVar node); |
| 828 E visitConditional(Conditional node); | 891 E visitConditional(Conditional node); |
| 829 E visitLogicalOperator(LogicalOperator node); | 892 E visitLogicalOperator(LogicalOperator node); |
| 830 E visitNot(Not node); | 893 E visitNot(Not node); |
| 831 E visitLiteralList(LiteralList node); | 894 E visitLiteralList(LiteralList node); |
| 832 E visitLiteralMap(LiteralMap node); | 895 E visitLiteralMap(LiteralMap node); |
| 833 E visitTypeOperator(TypeOperator node); | 896 E visitTypeOperator(TypeOperator node); |
| 834 E visitFunctionExpression(FunctionExpression node); | 897 E visitFunctionExpression(FunctionExpression node); |
| 835 E visitFieldInitializer(FieldInitializer node); | |
| 836 E visitSuperInitializer(SuperInitializer node); | |
| 837 E visitGetField(GetField node); | 898 E visitGetField(GetField node); |
| 838 E visitCreateBox(CreateBox node); | 899 E visitCreateBox(CreateBox node); |
| 839 E visitCreateInstance(CreateInstance node); | 900 E visitCreateInstance(CreateInstance node); |
| 840 E visitReifyRuntimeType(ReifyRuntimeType node); | 901 E visitReifyRuntimeType(ReifyRuntimeType node); |
| 841 E visitReadTypeVariable(ReadTypeVariable node); | 902 E visitReadTypeVariable(ReadTypeVariable node); |
| 842 E visitTypeExpression(TypeExpression node); | 903 E visitTypeExpression(TypeExpression node); |
| 843 } | 904 } |
| 844 | 905 |
| 845 abstract class ExpressionVisitor1<E, A> { | 906 abstract class ExpressionVisitor1<E, A> { |
| 846 E visitExpression(Expression e, A arg) => e.accept1(this, arg); | 907 E visitExpression(Expression node, A arg) => node.accept1(this, arg); |
| 847 E visitVariableUse(VariableUse node, A arg); | 908 E visitVariableUse(VariableUse node, A arg); |
| 848 E visitInvokeStatic(InvokeStatic node, A arg); | 909 E visitInvokeStatic(InvokeStatic node, A arg); |
| 849 E visitInvokeMethod(InvokeMethod node, A arg); | 910 E visitInvokeMethod(InvokeMethod node, A arg); |
| 850 E visitInvokeMethodDirectly(InvokeMethodDirectly node, A arg); | 911 E visitInvokeMethodDirectly(InvokeMethodDirectly node, A arg); |
| 851 E visitInvokeConstructor(InvokeConstructor node, A arg); | 912 E visitInvokeConstructor(InvokeConstructor node, A arg); |
| 852 E visitConcatenateStrings(ConcatenateStrings node, A arg); | 913 E visitConcatenateStrings(ConcatenateStrings node, A arg); |
| 853 E visitConstant(Constant node, A arg); | 914 E visitConstant(Constant node, A arg); |
| 854 E visitThis(This node, A arg); | 915 E visitThis(This node, A arg); |
| 855 E visitReifyTypeVar(ReifyTypeVar node, A arg); | 916 E visitReifyTypeVar(ReifyTypeVar node, A arg); |
| 856 E visitConditional(Conditional node, A arg); | 917 E visitConditional(Conditional node, A arg); |
| 857 E visitLogicalOperator(LogicalOperator node, A arg); | 918 E visitLogicalOperator(LogicalOperator node, A arg); |
| 858 E visitNot(Not node, A arg); | 919 E visitNot(Not node, A arg); |
| 859 E visitLiteralList(LiteralList node, A arg); | 920 E visitLiteralList(LiteralList node, A arg); |
| 860 E visitLiteralMap(LiteralMap node, A arg); | 921 E visitLiteralMap(LiteralMap node, A arg); |
| 861 E visitTypeOperator(TypeOperator node, A arg); | 922 E visitTypeOperator(TypeOperator node, A arg); |
| 862 E visitFunctionExpression(FunctionExpression node, A arg); | 923 E visitFunctionExpression(FunctionExpression node, A arg); |
| 863 E visitFieldInitializer(FieldInitializer node, A arg); | |
| 864 E visitSuperInitializer(SuperInitializer node, A arg); | |
| 865 E visitGetField(GetField node, A arg); | 924 E visitGetField(GetField node, A arg); |
| 866 E visitCreateBox(CreateBox node, A arg); | 925 E visitCreateBox(CreateBox node, A arg); |
| 867 E visitCreateInstance(CreateInstance node, A arg); | 926 E visitCreateInstance(CreateInstance node, A arg); |
| 868 E visitReifyRuntimeType(ReifyRuntimeType node, A arg); | 927 E visitReifyRuntimeType(ReifyRuntimeType node, A arg); |
| 869 E visitReadTypeVariable(ReadTypeVariable node, A arg); | 928 E visitReadTypeVariable(ReadTypeVariable node, A arg); |
| 870 E visitTypeExpression(TypeExpression node, A arg); | 929 E visitTypeExpression(TypeExpression node, A arg); |
| 871 } | 930 } |
| 872 | 931 |
| 873 abstract class StatementVisitor<S> { | 932 abstract class StatementVisitor<S> { |
| 874 S visitStatement(Statement s) => s.accept(this); | 933 S visitStatement(Statement node) => node.accept(this); |
| 875 S visitLabeledStatement(LabeledStatement node); | 934 S visitLabeledStatement(LabeledStatement node); |
| 876 S visitAssign(Assign node); | 935 S visitAssign(Assign node); |
| 877 S visitReturn(Return node); | 936 S visitReturn(Return node); |
| 878 S visitBreak(Break node); | 937 S visitBreak(Break node); |
| 879 S visitContinue(Continue node); | 938 S visitContinue(Continue node); |
| 880 S visitIf(If node); | 939 S visitIf(If node); |
| 881 S visitWhileTrue(WhileTrue node); | 940 S visitWhileTrue(WhileTrue node); |
| 882 S visitWhileCondition(WhileCondition node); | 941 S visitWhileCondition(WhileCondition node); |
| 883 S visitFunctionDeclaration(FunctionDeclaration node); | 942 S visitFunctionDeclaration(FunctionDeclaration node); |
| 884 S visitExpressionStatement(ExpressionStatement node); | 943 S visitExpressionStatement(ExpressionStatement node); |
| 885 S visitTry(Try node); | 944 S visitTry(Try node); |
| 886 S visitSetField(SetField node); | 945 S visitSetField(SetField node); |
| 887 } | 946 } |
| 888 | 947 |
| 889 abstract class StatementVisitor1<S, A> { | 948 abstract class StatementVisitor1<S, A> { |
| 890 S visitStatement(Statement s, A arg) => s.accept1(this, arg); | 949 S visitStatement(Statement node, A arg) => node.accept1(this, arg); |
| 891 S visitLabeledStatement(LabeledStatement node, A arg); | 950 S visitLabeledStatement(LabeledStatement node, A arg); |
| 892 S visitAssign(Assign node, A arg); | 951 S visitAssign(Assign node, A arg); |
| 893 S visitReturn(Return node, A arg); | 952 S visitReturn(Return node, A arg); |
| 894 S visitBreak(Break node, A arg); | 953 S visitBreak(Break node, A arg); |
| 895 S visitContinue(Continue node, A arg); | 954 S visitContinue(Continue node, A arg); |
| 896 S visitIf(If node, A arg); | 955 S visitIf(If node, A arg); |
| 897 S visitWhileTrue(WhileTrue node, A arg); | 956 S visitWhileTrue(WhileTrue node, A arg); |
| 898 S visitWhileCondition(WhileCondition node, A arg); | 957 S visitWhileCondition(WhileCondition node, A arg); |
| 899 S visitFunctionDeclaration(FunctionDeclaration node, A arg); | 958 S visitFunctionDeclaration(FunctionDeclaration node, A arg); |
| 900 S visitExpressionStatement(ExpressionStatement node, A arg); | 959 S visitExpressionStatement(ExpressionStatement node, A arg); |
| 901 S visitTry(Try node, A arg); | 960 S visitTry(Try node, A arg); |
| 902 S visitSetField(SetField node, A arg); | 961 S visitSetField(SetField node, A arg); |
| 903 } | 962 } |
| 904 | 963 |
| 905 abstract class Visitor<S, E> implements ExpressionVisitor<E>, | 964 abstract class RootVisitor<T> { |
| 906 StatementVisitor<S> { | 965 T visitRootNode(RootNode node) => node.accept(this); |
| 907 E visitExpression(Expression e) => e.accept(this); | 966 T visitFunctionDefinition(FunctionDefinition node); |
| 908 S visitStatement(Statement s) => s.accept(this); | 967 T visitConstructorDefinition(ConstructorDefinition node); |
| 968 T visitFieldDefinition(FieldDefinition node); | |
| 909 } | 969 } |
| 910 | 970 |
| 911 abstract class Visitor1<S, E, A> implements ExpressionVisitor1<E, A>, | 971 abstract class RootVisitor1<T, A> { |
| 912 StatementVisitor1<S, A> { | 972 T visitRootNode(RootNode node, A arg) => node.accept1(this, arg); |
| 913 E visitExpression(Expression e, A arg) => e.accept1(this, arg); | 973 T visitFunctionDefinition(FunctionDefinition node, A arg); |
| 914 S visitStatement(Statement s, A arg) => s.accept1(this, arg); | 974 T visitConstructorDefinition(ConstructorDefinition node, A arg); |
| 975 T visitFieldDefinition(FieldDefinition node, A arg); | |
| 915 } | 976 } |
| 916 | 977 |
| 917 class RecursiveVisitor extends Visitor { | 978 abstract class InitializerVisitor<T> { |
| 918 // TODO(asgerf): Clean up the tree visitor. | 979 T visitInitializer(Initializer node) => node.accept(this); |
| 919 | 980 T visitFieldInitializer(FieldInitializer node); |
| 920 visitExecutableDefinition(ExecutableDefinition node) { | 981 T visitSuperInitializer(SuperInitializer node); |
| 921 if (node is ConstructorDefinition) return visitConstructorDefinition(node); | 982 } |
| 922 if (node is FunctionDefinition) return visitFunctionDefinition(node); | |
| 923 if (node is FieldDefinition) return visitFieldDefinition(node); | |
| 924 throw 'Unexpected ExecutableDefinition: $node'; | |
| 925 } | |
| 926 | 983 |
| 927 visitFunctionDefinition(FunctionDefinition node) { | 984 abstract class InitializerVisitor1<T, A> { |
| 928 node.parameters.forEach(visitVariable); | 985 T visitInitializer(Initializer node, A arg) => node.accept1(this, arg); |
| 929 if (node.body != null) visitStatement(node.body); | 986 T visitFieldInitializer(FieldInitializer node, A arg); |
| 930 } | 987 T visitSuperInitializer(SuperInitializer node, A arg); |
| 988 } | |
| 931 | 989 |
| 932 visitConstructorDefinition(ConstructorDefinition node) { | 990 abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor { |
| 933 if (node.initializers != null) node.initializers.forEach(visitInitializer); | 991 visitExpression(Expression e) => e.accept(this); |
| 934 visitFunctionDefinition(node); | 992 visitStatement(Statement s) => s.accept(this); |
| 935 } | |
| 936 | 993 |
| 937 visitFieldDefinition(FieldDefinition node) { | 994 visitInnerFunction(FunctionDefinition node); |
| 938 if (node.body != null) { | |
| 939 visitStatement(node.body); | |
| 940 } | |
| 941 } | |
| 942 | |
| 943 visitInitializer(Initializer node) { | |
| 944 if (node is FieldInitializer) { | |
| 945 return visitFieldInitializer(node); | |
| 946 } else { | |
| 947 return visitSuperInitializer(node); | |
| 948 } | |
| 949 } | |
| 950 | |
| 951 visitFieldInitializer(FieldInitializer node) { | |
| 952 visitStatement(node.body); | |
| 953 } | |
| 954 | |
| 955 visitSuperInitializer(SuperInitializer node) { | |
| 956 node.arguments.forEach(visitStatement); | |
| 957 } | |
| 958 | 995 |
| 959 visitVariable(Variable node) {} | 996 visitVariable(Variable node) {} |
| 960 | 997 |
| 961 visitVariableUse(VariableUse node) { | 998 visitVariableUse(VariableUse node) { |
| 962 visitVariable(node.variable); | 999 visitVariable(node.variable); |
| 963 } | 1000 } |
| 964 | 1001 |
| 965 visitInvokeStatic(InvokeStatic node) { | 1002 visitInvokeStatic(InvokeStatic node) { |
| 966 node.arguments.forEach(visitExpression); | 1003 node.arguments.forEach(visitExpression); |
| 967 } | 1004 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1014 visitExpression(entry.key); | 1051 visitExpression(entry.key); |
| 1015 visitExpression(entry.value); | 1052 visitExpression(entry.value); |
| 1016 }); | 1053 }); |
| 1017 } | 1054 } |
| 1018 | 1055 |
| 1019 visitTypeOperator(TypeOperator node) { | 1056 visitTypeOperator(TypeOperator node) { |
| 1020 visitExpression(node.receiver); | 1057 visitExpression(node.receiver); |
| 1021 } | 1058 } |
| 1022 | 1059 |
| 1023 visitFunctionExpression(FunctionExpression node) { | 1060 visitFunctionExpression(FunctionExpression node) { |
| 1024 visitFunctionDefinition(node.definition); | 1061 visitInnerFunction(node.definition); |
| 1025 } | 1062 } |
| 1026 | 1063 |
| 1027 visitLabeledStatement(LabeledStatement node) { | 1064 visitLabeledStatement(LabeledStatement node) { |
| 1028 visitStatement(node.body); | 1065 visitStatement(node.body); |
| 1029 visitStatement(node.next); | 1066 visitStatement(node.next); |
| 1030 } | 1067 } |
| 1031 | 1068 |
| 1032 visitAssign(Assign node) { | 1069 visitAssign(Assign node) { |
| 1033 visitExpression(node.value); | 1070 visitExpression(node.value); |
| 1034 visitVariable(node.variable); | 1071 visitVariable(node.variable); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1053 visitStatement(node.body); | 1090 visitStatement(node.body); |
| 1054 } | 1091 } |
| 1055 | 1092 |
| 1056 visitWhileCondition(WhileCondition node) { | 1093 visitWhileCondition(WhileCondition node) { |
| 1057 visitExpression(node.condition); | 1094 visitExpression(node.condition); |
| 1058 visitStatement(node.body); | 1095 visitStatement(node.body); |
| 1059 visitStatement(node.next); | 1096 visitStatement(node.next); |
| 1060 } | 1097 } |
| 1061 | 1098 |
| 1062 visitFunctionDeclaration(FunctionDeclaration node) { | 1099 visitFunctionDeclaration(FunctionDeclaration node) { |
| 1063 visitFunctionDefinition(node.definition); | 1100 visitInnerFunction(node.definition); |
| 1064 visitStatement(node.next); | 1101 visitStatement(node.next); |
| 1065 } | 1102 } |
| 1066 | 1103 |
| 1067 visitExpressionStatement(ExpressionStatement node) { | 1104 visitExpressionStatement(ExpressionStatement node) { |
| 1068 visitExpression(node.expression); | 1105 visitExpression(node.expression); |
| 1069 visitStatement(node.next); | 1106 visitStatement(node.next); |
| 1070 } | 1107 } |
| 1071 | 1108 |
| 1072 visitTry(Try node) { | 1109 visitTry(Try node) { |
| 1073 visitStatement(node.tryBody); | 1110 visitStatement(node.tryBody); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1093 } | 1130 } |
| 1094 | 1131 |
| 1095 visitReifyRuntimeType(ReifyRuntimeType node) { | 1132 visitReifyRuntimeType(ReifyRuntimeType node) { |
| 1096 visitExpression(node.value); | 1133 visitExpression(node.value); |
| 1097 } | 1134 } |
| 1098 | 1135 |
| 1099 visitReadTypeVariable(ReadTypeVariable node) { | 1136 visitReadTypeVariable(ReadTypeVariable node) { |
| 1100 visitExpression(node.target); | 1137 visitExpression(node.target); |
| 1101 } | 1138 } |
| 1102 | 1139 |
| 1103 @override | |
| 1104 visitTypeExpression(TypeExpression node) { | 1140 visitTypeExpression(TypeExpression node) { |
| 1105 node.arguments.forEach(visitExpression); | 1141 node.arguments.forEach(visitExpression); |
| 1106 } | 1142 } |
| 1107 } | 1143 } |
| 1144 | |
| 1145 abstract class Transformer implements ExpressionVisitor<Expression>, | |
| 1146 StatementVisitor<Statement> { | |
| 1147 Expression visitExpression(Expression e) => e.accept(this); | |
| 1148 Statement visitStatement(Statement s) => s.accept(this); | |
| 1149 } | |
| 1150 | |
| 1151 class RecursiveTransformer extends Transformer { | |
| 1152 void visitInnerFunction(FunctionDefinition node) { | |
| 1153 node.body = visitStatement(node.body); | |
| 1154 } | |
| 1155 | |
| 1156 void _replaceExpressions(List<Expression> list) { | |
| 1157 for (int i=0; i<list.length; i++) { | |
|
Kevin Millikin (Google)
2015/04/08 15:10:16
int i = 0; i < list.length
asgerf
2015/04/09 09:58:23
Done.
| |
| 1158 list[i] = visitExpression(list[i]); | |
| 1159 } | |
| 1160 } | |
| 1161 | |
| 1162 visitVariableUse(VariableUse node) => node; | |
| 1163 | |
| 1164 visitInvokeStatic(InvokeStatic node) { | |
| 1165 _replaceExpressions(node.arguments); | |
| 1166 return node; | |
| 1167 } | |
| 1168 | |
| 1169 visitInvokeMethod(InvokeMethod node) { | |
| 1170 node.receiver = visitExpression(node.receiver); | |
| 1171 _replaceExpressions(node.arguments); | |
| 1172 return node; | |
| 1173 } | |
| 1174 | |
| 1175 visitInvokeMethodDirectly(InvokeMethodDirectly node) { | |
| 1176 node.receiver = visitExpression(node.receiver); | |
| 1177 _replaceExpressions(node.arguments); | |
| 1178 return node; | |
| 1179 } | |
| 1180 | |
| 1181 visitInvokeConstructor(InvokeConstructor node) { | |
| 1182 _replaceExpressions(node.arguments); | |
| 1183 return node; | |
| 1184 } | |
| 1185 | |
| 1186 visitConcatenateStrings(ConcatenateStrings node) { | |
| 1187 _replaceExpressions(node.arguments); | |
| 1188 return node; | |
| 1189 } | |
| 1190 | |
| 1191 visitConstant(Constant node) => node; | |
| 1192 | |
| 1193 visitThis(This node) => node; | |
| 1194 | |
| 1195 visitReifyTypeVar(ReifyTypeVar node) => node; | |
| 1196 | |
| 1197 visitConditional(Conditional node) { | |
| 1198 node.condition = visitExpression(node.condition); | |
| 1199 node.thenExpression = visitExpression(node.thenExpression); | |
| 1200 node.elseExpression = visitExpression(node.elseExpression); | |
| 1201 return node; | |
| 1202 } | |
| 1203 | |
| 1204 visitLogicalOperator(LogicalOperator node) { | |
| 1205 node.left = visitExpression(node.left); | |
| 1206 node.right = visitExpression(node.right); | |
| 1207 return node; | |
| 1208 } | |
| 1209 | |
| 1210 visitNot(Not node) { | |
| 1211 node.operand = visitExpression(node.operand); | |
| 1212 return node; | |
| 1213 } | |
| 1214 | |
| 1215 visitLiteralList(LiteralList node) { | |
| 1216 _replaceExpressions(node.values); | |
| 1217 return node; | |
| 1218 } | |
| 1219 | |
| 1220 visitLiteralMap(LiteralMap node) { | |
| 1221 node.entries.forEach((LiteralMapEntry entry) { | |
| 1222 entry.key = visitExpression(entry.key); | |
| 1223 entry.value = visitExpression(entry.value); | |
| 1224 }); | |
| 1225 return node; | |
| 1226 } | |
| 1227 | |
| 1228 visitTypeOperator(TypeOperator node) { | |
| 1229 node.receiver = visitExpression(node.receiver); | |
| 1230 return node; | |
| 1231 } | |
| 1232 | |
| 1233 visitFunctionExpression(FunctionExpression node) { | |
| 1234 visitInnerFunction(node.definition); | |
| 1235 return node; | |
| 1236 } | |
| 1237 | |
| 1238 visitLabeledStatement(LabeledStatement node) { | |
| 1239 node.body = visitStatement(node.body); | |
| 1240 node.next = visitStatement(node.next); | |
| 1241 return node; | |
| 1242 } | |
| 1243 | |
| 1244 visitAssign(Assign node) { | |
| 1245 node.value = visitExpression(node.value); | |
| 1246 node.next = visitStatement(node.next); | |
| 1247 return node; | |
| 1248 } | |
| 1249 | |
| 1250 visitReturn(Return node) { | |
| 1251 node.value = visitExpression(node.value); | |
| 1252 return node; | |
| 1253 } | |
| 1254 | |
| 1255 visitBreak(Break node) => node; | |
| 1256 | |
| 1257 visitContinue(Continue node) => node; | |
| 1258 | |
| 1259 visitIf(If node) { | |
| 1260 node.condition = visitExpression(node.condition); | |
| 1261 node.thenStatement = visitStatement(node.thenStatement); | |
| 1262 node.elseStatement = visitStatement(node.elseStatement); | |
| 1263 return node; | |
| 1264 } | |
| 1265 | |
| 1266 visitWhileTrue(WhileTrue node) { | |
| 1267 node.body = visitStatement(node.body); | |
| 1268 return node; | |
| 1269 } | |
| 1270 | |
| 1271 visitWhileCondition(WhileCondition node) { | |
| 1272 node.condition = visitExpression(node.condition); | |
| 1273 node.body = visitStatement(node.body); | |
| 1274 node.next = visitStatement(node.next); | |
| 1275 return node; | |
| 1276 } | |
| 1277 | |
| 1278 visitFunctionDeclaration(FunctionDeclaration node) { | |
| 1279 visitInnerFunction(node.definition); | |
| 1280 node.next = visitStatement(node.next); | |
| 1281 return node; | |
| 1282 } | |
| 1283 | |
| 1284 visitExpressionStatement(ExpressionStatement node) { | |
| 1285 node.expression = visitExpression(node.expression); | |
| 1286 node.next = visitStatement(node.next); | |
| 1287 return node; | |
| 1288 } | |
| 1289 | |
| 1290 visitTry(Try node) { | |
| 1291 node.tryBody = visitStatement(node.tryBody); | |
| 1292 node.catchBody = visitStatement(node.catchBody); | |
| 1293 return node; | |
| 1294 } | |
| 1295 | |
| 1296 visitGetField(GetField node) { | |
| 1297 node.object = visitExpression(node.object); | |
| 1298 return node; | |
| 1299 } | |
| 1300 | |
| 1301 visitSetField(SetField node) { | |
| 1302 node.object = visitExpression(node.object); | |
| 1303 node.value = visitExpression(node.value); | |
| 1304 node.next = visitStatement(node.next); | |
| 1305 return node; | |
| 1306 } | |
| 1307 | |
| 1308 visitCreateBox(CreateBox node) => node; | |
| 1309 | |
| 1310 visitCreateInstance(CreateInstance node) { | |
| 1311 _replaceExpressions(node.arguments); | |
| 1312 return node; | |
| 1313 } | |
| 1314 | |
| 1315 visitReifyRuntimeType(ReifyRuntimeType node) { | |
| 1316 node.value = visitExpression(node.value); | |
| 1317 return node; | |
| 1318 } | |
| 1319 | |
| 1320 visitReadTypeVariable(ReadTypeVariable node) { | |
| 1321 node.target = visitExpression(node.target); | |
| 1322 return node; | |
| 1323 } | |
| 1324 | |
| 1325 visitTypeExpression(TypeExpression node) { | |
| 1326 _replaceExpressions(node.arguments); | |
| 1327 return node; | |
| 1328 } | |
| 1329 } | |
| OLD | NEW |