Chromium Code Reviews| 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 // IrNodes are kept in a separate library to have precise control over their | 5 // IrNodes are kept in a separate library to have precise control over their |
| 6 // dependencies on other parts of the system. | 6 // dependencies on other parts of the system. |
| 7 library dart2js.ir_nodes; | 7 library dart2js.ir_nodes; |
| 8 | 8 |
| 9 import '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
| 10 import '../constants/values.dart' as values show ConstantValue; | 10 import '../constants/values.dart' as values show ConstantValue; |
| (...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 722 | 722 |
| 723 bool get isReturnContinuation => body == null; | 723 bool get isReturnContinuation => body == null; |
| 724 | 724 |
| 725 Continuation(this.parameters); | 725 Continuation(this.parameters); |
| 726 | 726 |
| 727 Continuation.retrn() : parameters = <Parameter>[new Parameter(null)]; | 727 Continuation.retrn() : parameters = <Parameter>[new Parameter(null)]; |
| 728 | 728 |
| 729 accept(Visitor visitor) => visitor.visitContinuation(this); | 729 accept(Visitor visitor) => visitor.visitContinuation(this); |
| 730 } | 730 } |
| 731 | 731 |
| 732 abstract class ExecutableDefinition implements Node { | 732 abstract class RootNode extends Node { |
| 733 RunnableBody get body; | |
| 734 Element get element; | 733 Element get element; |
| 735 | 734 bool get isEmpty; |
|
Kevin Millikin (Google)
2015/04/08 15:10:15
This makes me wonder what it means to be an empty
asgerf
2015/04/09 09:58:23
I removed the body getter because constructors hav
| |
| 736 applyPass(Pass pass); | 735 List<Definition> get parameters; |
|
Kevin Millikin (Google)
2015/04/08 15:10:15
It looks like at the cost of a field per FieldDefi
asgerf
2015/04/09 09:58:23
But then we don't get to use an initializing forma
| |
| 737 } | 736 } |
| 738 | 737 |
| 739 // This is basically a function definition with an empty parameter list and a | 738 // This is basically a function definition with an empty parameter list and a |
| 740 // field element instead of a function element and no const declarations, and | 739 // field element instead of a function element and no const declarations, and |
| 741 // never a getter or setter, though that's less important. | 740 // never a getter or setter, though that's less important. |
| 742 class FieldDefinition extends Node implements ExecutableDefinition { | 741 class FieldDefinition extends RootNode implements DartSpecificNode { |
| 743 final FieldElement element; | 742 final FieldElement element; |
| 744 RunnableBody body; | 743 List<Definition> get parameters => const <Definition>[]; |
| 744 Body body; | |
|
Kevin Millikin (Google)
2015/04/08 15:10:15
Can this be final?
asgerf
2015/04/09 09:58:23
Yes.
| |
| 745 | 745 |
| 746 FieldDefinition(this.element, this.body); | 746 FieldDefinition(this.element, this.body); |
| 747 | 747 |
| 748 FieldDefinition.withoutInitializer(this.element) | 748 FieldDefinition.withoutInitializer(this.element) |
| 749 : this.body = null; | 749 : this.body = null; |
| 750 | 750 |
| 751 accept(Visitor visitor) => visitor.visitFieldDefinition(this); | 751 accept(Visitor visitor) => visitor.visitFieldDefinition(this); |
| 752 applyPass(Pass pass) => pass.rewriteFieldDefinition(this); | |
| 753 | 752 |
| 754 /// `true` if this field has no initializer. | 753 bool get isEmpty => body == null; |
| 755 /// | |
| 756 /// If `true` [body] is `null`. | |
| 757 /// | |
| 758 /// This is different from a initializer that is `null`. Consider this class: | |
| 759 /// | |
| 760 /// class Class { | |
| 761 /// final field; | |
| 762 /// Class.a(this.field); | |
| 763 /// Class.b() : this.field = null; | |
| 764 /// Class.c(); | |
| 765 /// } | |
| 766 /// | |
| 767 /// If `field` had an initializer, possibly `null`, constructors `Class.a` and | |
| 768 /// `Class.b` would be invalid, and since `field` has no initializer | |
| 769 /// constructor `Class.c` is invalid. We therefore need to distinguish the two | |
| 770 /// cases. | |
| 771 bool get hasInitializer => body != null; | |
| 772 } | 754 } |
| 773 | 755 |
| 774 /// Identifies a mutable variable. | 756 /// Identifies a mutable variable. |
| 775 class MutableVariable extends Definition { | 757 class MutableVariable extends Definition { |
| 776 /// Body of source code that declares this mutable variable. | 758 /// Body of source code that declares this mutable variable. |
| 777 ExecutableElement host; | 759 ExecutableElement host; |
| 778 Entity hint; | 760 Entity hint; |
| 779 | 761 |
| 780 MutableVariable(this.host, this.hint); | 762 MutableVariable(this.host, this.hint); |
| 781 | 763 |
| 782 accept(Visitor v) => v.visitMutableVariable(this); | 764 accept(Visitor v) => v.visitMutableVariable(this); |
| 783 } | 765 } |
| 784 | 766 |
| 785 class RunnableBody extends InteriorNode { | 767 class Body extends InteriorNode { |
| 786 Expression body; | 768 Expression body; |
|
Kevin Millikin (Google)
2015/04/08 15:10:15
This is still weird: Body has a field body which i
asgerf
2015/04/09 09:58:23
The field overrides InteriorNode.body so this woul
| |
| 787 final Continuation returnContinuation; | 769 final Continuation returnContinuation; |
| 788 RunnableBody(this.body, this.returnContinuation); | 770 Body(this.body, this.returnContinuation); |
| 789 accept(Visitor visitor) => visitor.visitRunnableBody(this); | 771 accept(Visitor visitor) => visitor.visitBody(this); |
| 790 } | 772 } |
| 791 | 773 |
| 792 /// A function definition, consisting of parameters and a body. The parameters | 774 /// A function definition, consisting of parameters and a body. The parameters |
| 793 /// include a distinguished continuation parameter (held by the body). | 775 /// include a distinguished continuation parameter (held by the body). |
| 794 class FunctionDefinition extends Node | 776 class FunctionDefinition extends RootNode { |
| 795 implements ExecutableDefinition { | |
| 796 final FunctionElement element; | 777 final FunctionElement element; |
| 797 final Parameter thisParameter; | 778 final Parameter thisParameter; |
| 798 /// Mixed list of [Parameter]s and [MutableVariable]s. | 779 /// Mixed list of [Parameter]s and [MutableVariable]s. |
| 799 final List<Definition> parameters; | 780 final List<Definition> parameters; |
| 800 final RunnableBody body; | 781 final Body body; |
| 801 final List<ConstDeclaration> localConstants; | 782 final List<ConstDeclaration> localConstants; |
| 802 | 783 |
| 803 /// Values for optional parameters. | 784 /// Values for optional parameters. |
| 804 final List<ConstantExpression> defaultParameterValues; | 785 final List<ConstantExpression> defaultParameterValues; |
| 805 | 786 |
| 806 FunctionDefinition(this.element, | 787 FunctionDefinition(this.element, |
| 807 this.thisParameter, | 788 this.thisParameter, |
| 808 this.parameters, | 789 this.parameters, |
| 809 this.body, | 790 this.body, |
| 810 this.localConstants, | 791 this.localConstants, |
| 811 this.defaultParameterValues); | 792 this.defaultParameterValues); |
| 812 | 793 |
| 813 FunctionDefinition.abstract(this.element, | 794 FunctionDefinition.abstract(this.element, |
| 814 this.thisParameter, | |
| 815 this.parameters, | 795 this.parameters, |
| 816 this.defaultParameterValues) | 796 this.defaultParameterValues) |
| 817 : body = null, | 797 : body = null, |
| 798 thisParameter = null, | |
| 818 localConstants = const <ConstDeclaration>[]; | 799 localConstants = const <ConstDeclaration>[]; |
| 819 | 800 |
| 820 accept(Visitor visitor) => visitor.visitFunctionDefinition(this); | 801 accept(Visitor visitor) => visitor.visitFunctionDefinition(this); |
| 821 applyPass(Pass pass) => pass.rewriteFunctionDefinition(this); | |
| 822 | 802 |
| 823 /// Returns `true` if this function is abstract or external. | 803 bool get isEmpty => body == null; |
| 824 /// | |
| 825 /// If `true`, [body] is `null` and [localConstants] is empty. | |
| 826 bool get isAbstract => body == null; | |
| 827 } | 804 } |
| 828 | 805 |
| 829 abstract class Initializer extends Node implements DartSpecificNode {} | 806 abstract class Initializer extends Node implements DartSpecificNode {} |
| 830 | 807 |
| 831 class FieldInitializer extends Initializer { | 808 class FieldInitializer extends Initializer { |
| 832 final FieldElement element; | 809 final FieldElement element; |
| 833 final RunnableBody body; | 810 final Body body; |
| 834 | 811 |
| 835 FieldInitializer(this.element, this.body); | 812 FieldInitializer(this.element, this.body); |
| 836 accept(Visitor visitor) => visitor.visitFieldInitializer(this); | 813 accept(Visitor visitor) => visitor.visitFieldInitializer(this); |
| 837 } | 814 } |
| 838 | 815 |
| 839 class SuperInitializer extends Initializer { | 816 class SuperInitializer extends Initializer { |
| 840 final ConstructorElement target; | 817 final ConstructorElement target; |
| 841 final List<RunnableBody> arguments; | 818 final List<Body> arguments; |
| 842 final Selector selector; | 819 final Selector selector; |
| 843 SuperInitializer(this.target, this.arguments, this.selector); | 820 SuperInitializer(this.target, this.arguments, this.selector); |
| 844 accept(Visitor visitor) => visitor.visitSuperInitializer(this); | 821 accept(Visitor visitor) => visitor.visitSuperInitializer(this); |
| 845 } | 822 } |
| 846 | 823 |
| 847 class ConstructorDefinition extends FunctionDefinition { | 824 class ConstructorDefinition extends RootNode implements DartSpecificNode { |
| 825 final ConstructorElement element; | |
| 826 final Parameter thisParameter; | |
| 827 /// Mixed list of [Parameter]s and [MutableVariable]s. | |
| 828 final List<Definition> parameters; | |
| 829 final Body body; | |
| 830 final List<ConstDeclaration> localConstants; | |
| 848 final List<Initializer> initializers; | 831 final List<Initializer> initializers; |
| 849 | 832 |
| 850 ConstructorDefinition(ConstructorElement element, | 833 /// Values for optional parameters. |
| 851 Definition thisParameter, // only Dart | 834 final List<ConstantExpression> defaultParameterValues; |
| 852 List<Definition> parameters, | 835 |
| 853 RunnableBody body, | 836 ConstructorDefinition(this.element, |
| 837 this.thisParameter, | |
| 838 this.parameters, | |
| 839 this.body, | |
| 854 this.initializers, | 840 this.initializers, |
| 855 List<ConstDeclaration> localConstants, | 841 this.localConstants, |
| 856 List<ConstantExpression> defaultParameterValues) | 842 this.defaultParameterValues); |
| 857 : super(element, thisParameter, parameters, body, localConstants, | |
| 858 defaultParameterValues); | |
| 859 | 843 |
| 860 // 'Abstract' here means "has no body" and is used to represent external | 844 // 'Abstract' here means "has no body" and is used to represent external |
| 861 // constructors. | 845 // constructors. |
| 862 ConstructorDefinition.abstract( | 846 ConstructorDefinition.abstract( |
| 863 ConstructorElement element, | 847 this.element, |
| 864 List<Definition> parameters, | 848 this.parameters, |
| 865 List<ConstantExpression> defaultParameterValues) | 849 this.defaultParameterValues) |
| 866 : initializers = null, | 850 : body = null, |
| 867 super.abstract(element, null, parameters, defaultParameterValues); | 851 initializers = null, |
| 852 thisParameter = null, | |
| 853 localConstants = const <ConstDeclaration>[]; | |
| 868 | 854 |
| 869 accept(Visitor visitor) => visitor.visitConstructorDefinition(this); | 855 accept(Visitor visitor) => visitor.visitConstructorDefinition(this); |
| 870 applyPass(Pass pass) => pass.rewriteConstructorDefinition(this); | 856 |
| 857 bool get isEmpty => body == null; | |
| 871 } | 858 } |
| 872 | 859 |
| 873 /// Converts the internal representation of a type to a Dart object of type | 860 /// Converts the internal representation of a type to a Dart object of type |
| 874 /// [Type]. | 861 /// [Type]. |
| 875 class ReifyRuntimeType extends Primitive implements JsSpecificNode { | 862 class ReifyRuntimeType extends Primitive implements JsSpecificNode { |
| 876 /// Reference to the internal representation of a type (as produced, for | 863 /// Reference to the internal representation of a type (as produced, for |
| 877 /// example, by [ReadTypeVariable]). | 864 /// example, by [ReadTypeVariable]). |
| 878 final Reference<Primitive> value; | 865 final Reference<Primitive> value; |
| 879 ReifyRuntimeType(Primitive value) | 866 ReifyRuntimeType(Primitive value) |
| 880 : this.value = new Reference<Primitive>(value); | 867 : this.value = new Reference<Primitive>(value); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 927 | 914 |
| 928 abstract class Visitor<T> { | 915 abstract class Visitor<T> { |
| 929 const Visitor(); | 916 const Visitor(); |
| 930 | 917 |
| 931 T visit(Node node); | 918 T visit(Node node); |
| 932 | 919 |
| 933 // Concrete classes. | 920 // Concrete classes. |
| 934 T visitFieldDefinition(FieldDefinition node); | 921 T visitFieldDefinition(FieldDefinition node); |
| 935 T visitFunctionDefinition(FunctionDefinition node); | 922 T visitFunctionDefinition(FunctionDefinition node); |
| 936 T visitConstructorDefinition(ConstructorDefinition node); | 923 T visitConstructorDefinition(ConstructorDefinition node); |
| 937 T visitRunnableBody(RunnableBody node); | 924 T visitBody(Body node); |
| 938 | 925 |
| 939 // Initializers | 926 // Initializers |
| 940 T visitFieldInitializer(FieldInitializer node); | 927 T visitFieldInitializer(FieldInitializer node); |
| 941 T visitSuperInitializer(SuperInitializer node); | 928 T visitSuperInitializer(SuperInitializer node); |
| 942 | 929 |
| 943 // Expressions. | 930 // Expressions. |
| 944 T visitLetPrim(LetPrim node); | 931 T visitLetPrim(LetPrim node); |
| 945 T visitLetCont(LetCont node); | 932 T visitLetCont(LetCont node); |
| 946 T visitLetHandler(LetHandler node); | 933 T visitLetHandler(LetHandler node); |
| 947 T visitLetMutable(LetMutable node); | 934 T visitLetMutable(LetMutable node); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 988 | 975 |
| 989 /// Recursively visits the entire CPS term, and calls abstract `process*` | 976 /// Recursively visits the entire CPS term, and calls abstract `process*` |
| 990 /// (i.e. `processLetPrim`) functions in pre-order. | 977 /// (i.e. `processLetPrim`) functions in pre-order. |
| 991 class RecursiveVisitor implements Visitor { | 978 class RecursiveVisitor implements Visitor { |
| 992 const RecursiveVisitor(); | 979 const RecursiveVisitor(); |
| 993 | 980 |
| 994 visit(Node node) => node.accept(this); | 981 visit(Node node) => node.accept(this); |
| 995 | 982 |
| 996 processReference(Reference ref) {} | 983 processReference(Reference ref) {} |
| 997 | 984 |
| 998 processRunnableBody(RunnableBody node) {} | 985 processBody(Body node) {} |
| 999 visitRunnableBody(RunnableBody node) { | 986 visitBody(Body node) { |
| 1000 processRunnableBody(node); | 987 processBody(node); |
| 1001 visit(node.returnContinuation); | 988 visit(node.returnContinuation); |
| 1002 visit(node.body); | 989 visit(node.body); |
| 1003 } | 990 } |
| 1004 | 991 |
| 1005 processFieldDefinition(FieldDefinition node) {} | 992 processFieldDefinition(FieldDefinition node) {} |
| 1006 visitFieldDefinition(FieldDefinition node) { | 993 visitFieldDefinition(FieldDefinition node) { |
| 1007 processFieldDefinition(node); | 994 processFieldDefinition(node); |
| 1008 if (node.hasInitializer) { | 995 if (node.body != null) { |
| 1009 visit(node.body); | 996 visit(node.body); |
| 1010 } | 997 } |
| 1011 } | 998 } |
| 1012 | 999 |
| 1013 processFunctionDefinition(FunctionDefinition node) {} | 1000 processFunctionDefinition(FunctionDefinition node) {} |
| 1014 visitFunctionDefinition(FunctionDefinition node) { | 1001 visitFunctionDefinition(FunctionDefinition node) { |
| 1015 processFunctionDefinition(node); | 1002 processFunctionDefinition(node); |
| 1016 if (node.thisParameter != null) visit(node.thisParameter); | 1003 if (node.thisParameter != null) visit(node.thisParameter); |
| 1017 node.parameters.forEach(visit); | 1004 node.parameters.forEach(visit); |
| 1018 if (!node.isAbstract) { | 1005 if (node.body != null) { |
| 1019 visit(node.body); | 1006 visit(node.body); |
| 1020 } | 1007 } |
| 1021 } | 1008 } |
| 1022 | 1009 |
| 1023 processConstructorDefinition(ConstructorDefinition node) {} | 1010 processConstructorDefinition(ConstructorDefinition node) {} |
| 1024 visitConstructorDefinition(ConstructorDefinition node) { | 1011 visitConstructorDefinition(ConstructorDefinition node) { |
| 1025 processConstructorDefinition(node); | 1012 processConstructorDefinition(node); |
| 1026 if (node.thisParameter != null) visit(node.thisParameter); | 1013 if (node.thisParameter != null) visit(node.thisParameter); |
| 1027 node.parameters.forEach(visit); | 1014 node.parameters.forEach(visit); |
| 1028 if (!node.isAbstract) { | 1015 if (node.body != null) { |
| 1029 node.initializers.forEach(visit); | 1016 node.initializers.forEach(visit); |
|
Kevin Millikin (Google)
2015/04/08 15:10:15
It might be better not to assume that (node.body =
asgerf
2015/04/09 09:58:23
Done.
There are other places where we depend on a
| |
| 1030 visit(node.body); | 1017 visit(node.body); |
| 1031 } | 1018 } |
| 1032 } | 1019 } |
| 1033 | 1020 |
| 1034 processFieldInitializer(FieldInitializer node) {} | 1021 processFieldInitializer(FieldInitializer node) {} |
| 1035 visitFieldInitializer(FieldInitializer node) { | 1022 visitFieldInitializer(FieldInitializer node) { |
| 1036 processFieldInitializer(node); | 1023 processFieldInitializer(node); |
| 1037 visit(node.body); | 1024 visit(node.body); |
| 1038 } | 1025 } |
| 1039 | 1026 |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1259 processReference(node.target); | 1246 processReference(node.target); |
| 1260 } | 1247 } |
| 1261 | 1248 |
| 1262 processTypeExpression(TypeExpression node) {} | 1249 processTypeExpression(TypeExpression node) {} |
| 1263 @override | 1250 @override |
| 1264 visitTypeExpression(TypeExpression node) { | 1251 visitTypeExpression(TypeExpression node) { |
| 1265 processTypeExpression(node); | 1252 processTypeExpression(node); |
| 1266 node.arguments.forEach(processReference); | 1253 node.arguments.forEach(processReference); |
| 1267 } | 1254 } |
| 1268 } | 1255 } |
| OLD | NEW |