| 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 dart_tree; | 5 library dart_tree; |
| 6 | 6 |
| 7 import '../dart2jslib.dart' as dart2js; | 7 import '../dart2jslib.dart' as dart2js; |
| 8 import '../elements/elements.dart'; | 8 import '../elements/elements.dart'; |
| 9 import '../universe/universe.dart'; | 9 import '../universe/universe.dart'; |
| 10 import '../ir/ir_nodes.dart' as ir; | 10 import '../ir/ir_nodes.dart' as ir; |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 final Selector selector; | 127 final Selector selector; |
| 128 final List<Expression> arguments; | 128 final List<Expression> arguments; |
| 129 | 129 |
| 130 InvokeMethod(this.receiver, this.selector, this.arguments) { | 130 InvokeMethod(this.receiver, this.selector, this.arguments) { |
| 131 assert(receiver != null); | 131 assert(receiver != null); |
| 132 } | 132 } |
| 133 | 133 |
| 134 accept(ExpressionVisitor visitor) => visitor.visitInvokeMethod(this); | 134 accept(ExpressionVisitor visitor) => visitor.visitInvokeMethod(this); |
| 135 } | 135 } |
| 136 | 136 |
| 137 class InvokeSuperMethod extends Expression implements Invoke { |
| 138 final Selector selector; |
| 139 final List<Expression> arguments; |
| 140 |
| 141 InvokeSuperMethod(this.selector, this.arguments) ; |
| 142 |
| 143 accept(Visitor visitor) => visitor.visitInvokeSuperMethod(this); |
| 144 } |
| 145 |
| 137 /** | 146 /** |
| 138 * Call to a factory or generative constructor. | 147 * Call to a factory or generative constructor. |
| 139 */ | 148 */ |
| 140 class InvokeConstructor extends Expression implements Invoke { | 149 class InvokeConstructor extends Expression implements Invoke { |
| 141 final GenericType type; | 150 final GenericType type; |
| 142 final FunctionElement target; | 151 final FunctionElement target; |
| 143 final List<Expression> arguments; | 152 final List<Expression> arguments; |
| 144 final Selector selector; | 153 final Selector selector; |
| 145 final dart2js.Constant constant; | 154 final dart2js.Constant constant; |
| 146 | 155 |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 final List<ConstDeclaration> localConstants; | 445 final List<ConstDeclaration> localConstants; |
| 437 | 446 |
| 438 FunctionDefinition(this.parameters, this.body, this.localConstants); | 447 FunctionDefinition(this.parameters, this.body, this.localConstants); |
| 439 } | 448 } |
| 440 | 449 |
| 441 abstract class ExpressionVisitor<E> { | 450 abstract class ExpressionVisitor<E> { |
| 442 E visitExpression(Expression e) => e.accept(this); | 451 E visitExpression(Expression e) => e.accept(this); |
| 443 E visitVariable(Variable node); | 452 E visitVariable(Variable node); |
| 444 E visitInvokeStatic(InvokeStatic node); | 453 E visitInvokeStatic(InvokeStatic node); |
| 445 E visitInvokeMethod(InvokeMethod node); | 454 E visitInvokeMethod(InvokeMethod node); |
| 455 E visitInvokeSuperMethod(InvokeSuperMethod node); |
| 446 E visitInvokeConstructor(InvokeConstructor node); | 456 E visitInvokeConstructor(InvokeConstructor node); |
| 447 E visitConcatenateStrings(ConcatenateStrings node); | 457 E visitConcatenateStrings(ConcatenateStrings node); |
| 448 E visitConstant(Constant node); | 458 E visitConstant(Constant node); |
| 449 E visitThis(This node); | 459 E visitThis(This node); |
| 450 E visitReifyTypeVar(ReifyTypeVar node); | 460 E visitReifyTypeVar(ReifyTypeVar node); |
| 451 E visitConditional(Conditional node); | 461 E visitConditional(Conditional node); |
| 452 E visitLogicalOperator(LogicalOperator node); | 462 E visitLogicalOperator(LogicalOperator node); |
| 453 E visitNot(Not node); | 463 E visitNot(Not node); |
| 454 E visitLiteralList(LiteralList node); | 464 E visitLiteralList(LiteralList node); |
| 455 E visitLiteralMap(LiteralMap node); | 465 E visitLiteralMap(LiteralMap node); |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 if (cont == returnContinuation) { | 745 if (cont == returnContinuation) { |
| 736 return new Return(invoke); | 746 return new Return(invoke); |
| 737 } else { | 747 } else { |
| 738 assert(cont.hasExactlyOneUse); | 748 assert(cont.hasExactlyOneUse); |
| 739 assert(cont.parameters.length == 1); | 749 assert(cont.parameters.length == 1); |
| 740 return buildContinuationAssignment(cont.parameters.single, invoke, | 750 return buildContinuationAssignment(cont.parameters.single, invoke, |
| 741 () => visit(cont.body)); | 751 () => visit(cont.body)); |
| 742 } | 752 } |
| 743 } | 753 } |
| 744 | 754 |
| 755 Statement visitInvokeSuperMethod(ir.InvokeSuperMethod node) { |
| 756 List<Expression> arguments = translateArguments(node.arguments); |
| 757 Expression invoke = new InvokeSuperMethod(node.selector, arguments); |
| 758 ir.Continuation cont = node.continuation.definition; |
| 759 if (cont == returnContinuation) { |
| 760 return new Return(invoke); |
| 761 } else { |
| 762 assert(cont.hasExactlyOneUse); |
| 763 assert(cont.parameters.length == 1); |
| 764 return buildContinuationAssignment(cont.parameters.single, invoke, |
| 765 () => visit(cont.body)); |
| 766 } |
| 767 } |
| 768 |
| 745 Statement visitConcatenateStrings(ir.ConcatenateStrings node) { | 769 Statement visitConcatenateStrings(ir.ConcatenateStrings node) { |
| 746 List<Expression> arguments = translateArguments(node.arguments); | 770 List<Expression> arguments = translateArguments(node.arguments); |
| 747 Expression concat = new ConcatenateStrings(arguments); | 771 Expression concat = new ConcatenateStrings(arguments); |
| 748 ir.Continuation cont = node.continuation.definition; | 772 ir.Continuation cont = node.continuation.definition; |
| 749 if (cont == returnContinuation) { | 773 if (cont == returnContinuation) { |
| 750 return new Return(concat); | 774 return new Return(concat); |
| 751 } else { | 775 } else { |
| 752 assert(cont.hasExactlyOneUse); | 776 assert(cont.hasExactlyOneUse); |
| 753 assert(cont.parameters.length == 1); | 777 assert(cont.parameters.length == 1); |
| 754 return buildContinuationAssignment(cont.parameters.single, concat, | 778 return buildContinuationAssignment(cont.parameters.single, concat, |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 978 // The binding environment. The rightmost element of the list is the nearest | 1002 // The binding environment. The rightmost element of the list is the nearest |
| 979 // available enclosing binding. | 1003 // available enclosing binding. |
| 980 List<Assign> environment; | 1004 List<Assign> environment; |
| 981 | 1005 |
| 982 /// Substitution map for labels. Any break to a label L should be substituted | 1006 /// Substitution map for labels. Any break to a label L should be substituted |
| 983 /// for a break to L' if L maps to L'. | 1007 /// for a break to L' if L maps to L'. |
| 984 Map<Label, Jump> labelRedirects = <Label, Jump>{}; | 1008 Map<Label, Jump> labelRedirects = <Label, Jump>{}; |
| 985 | 1009 |
| 986 /// Returns the redirect target of [label] or [label] itself if it should not | 1010 /// Returns the redirect target of [label] or [label] itself if it should not |
| 987 /// be redirected. | 1011 /// be redirected. |
| 988 Jump redirect(Break jump) { | 1012 Jump redirect(Jump jump) { |
| 989 Jump newJump = labelRedirects[jump.target]; | 1013 Jump newJump = labelRedirects[jump.target]; |
| 990 return newJump != null ? newJump : jump; | 1014 return newJump != null ? newJump : jump; |
| 991 } | 1015 } |
| 992 | 1016 |
| 993 void rewrite(FunctionDefinition definition) { | 1017 void rewrite(FunctionDefinition definition) { |
| 994 environment = <Assign>[]; | 1018 environment = <Assign>[]; |
| 995 definition.body = visitStatement(definition.body); | 1019 definition.body = visitStatement(definition.body); |
| 996 | 1020 |
| 997 // TODO(kmillikin): Allow definitions that are not propagated. Here, | 1021 // TODO(kmillikin): Allow definitions that are not propagated. Here, |
| 998 // this means rebuilding the binding with a recursively unnamed definition, | 1022 // this means rebuilding the binding with a recursively unnamed definition, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1042 } | 1066 } |
| 1043 | 1067 |
| 1044 Expression visitInvokeMethod(InvokeMethod node) { | 1068 Expression visitInvokeMethod(InvokeMethod node) { |
| 1045 for (int i = node.arguments.length - 1; i >= 0; --i) { | 1069 for (int i = node.arguments.length - 1; i >= 0; --i) { |
| 1046 node.arguments[i] = visitExpression(node.arguments[i]); | 1070 node.arguments[i] = visitExpression(node.arguments[i]); |
| 1047 } | 1071 } |
| 1048 node.receiver = visitExpression(node.receiver); | 1072 node.receiver = visitExpression(node.receiver); |
| 1049 return node; | 1073 return node; |
| 1050 } | 1074 } |
| 1051 | 1075 |
| 1076 Expression visitInvokeSuperMethod(InvokeSuperMethod node) { |
| 1077 for (int i = node.arguments.length - 1; i >= 0; --i) { |
| 1078 node.arguments[i] = visitExpression(node.arguments[i]); |
| 1079 } |
| 1080 return node; |
| 1081 } |
| 1082 |
| 1052 Expression visitInvokeConstructor(InvokeConstructor node) { | 1083 Expression visitInvokeConstructor(InvokeConstructor node) { |
| 1053 for (int i = node.arguments.length - 1; i >= 0; --i) { | 1084 for (int i = node.arguments.length - 1; i >= 0; --i) { |
| 1054 node.arguments[i] = visitExpression(node.arguments[i]); | 1085 node.arguments[i] = visitExpression(node.arguments[i]); |
| 1055 } | 1086 } |
| 1056 return node; | 1087 return node; |
| 1057 } | 1088 } |
| 1058 | 1089 |
| 1059 Expression visitConcatenateStrings(ConcatenateStrings node) { | 1090 Expression visitConcatenateStrings(ConcatenateStrings node) { |
| 1060 for (int i = node.arguments.length - 1; i >= 0; --i) { | 1091 for (int i = node.arguments.length - 1; i >= 0; --i) { |
| 1061 node.arguments[i] = visitExpression(node.arguments[i]); | 1092 node.arguments[i] = visitExpression(node.arguments[i]); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1095 Statement visitReturn(Return node) { | 1126 Statement visitReturn(Return node) { |
| 1096 node.value = visitExpression(node.value); | 1127 node.value = visitExpression(node.value); |
| 1097 return node; | 1128 return node; |
| 1098 } | 1129 } |
| 1099 | 1130 |
| 1100 | 1131 |
| 1101 Statement visitBreak(Break node) { | 1132 Statement visitBreak(Break node) { |
| 1102 // Redirect through chain of breaks. | 1133 // Redirect through chain of breaks. |
| 1103 // Note that useCount was accounted for at visitLabeledStatement. | 1134 // Note that useCount was accounted for at visitLabeledStatement. |
| 1104 // Note redirect may return either a Break or Continue statement. | 1135 // Note redirect may return either a Break or Continue statement. |
| 1105 node = redirect(node); | 1136 Jump jump = redirect(node); |
| 1106 if (node is Break && node.target.useCount == 1) { | 1137 if (jump is Break && jump.target.useCount == 1) { |
| 1107 --node.target.useCount; | 1138 --jump.target.useCount; |
| 1108 return visitStatement(node.target.binding.next); | 1139 return visitStatement(jump.target.binding.next); |
| 1109 } | 1140 } |
| 1110 return node; | 1141 return jump; |
| 1111 } | 1142 } |
| 1112 | 1143 |
| 1113 Statement visitContinue(Continue node) { | 1144 Statement visitContinue(Continue node) { |
| 1114 return node; | 1145 return node; |
| 1115 } | 1146 } |
| 1116 | 1147 |
| 1117 Statement visitLabeledStatement(LabeledStatement node) { | 1148 Statement visitLabeledStatement(LabeledStatement node) { |
| 1118 if (node.next is Jump) { | 1149 if (node.next is Jump) { |
| 1119 // Eliminate label if next is a break or continue statement | 1150 // Eliminate label if next is a break or continue statement |
| 1120 // Breaks to this label are redirected to the outer label. | 1151 // Breaks to this label are redirected to the outer label. |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1693 _rewriteList(node.arguments); | 1724 _rewriteList(node.arguments); |
| 1694 return node; | 1725 return node; |
| 1695 } | 1726 } |
| 1696 | 1727 |
| 1697 Expression visitInvokeMethod(InvokeMethod node) { | 1728 Expression visitInvokeMethod(InvokeMethod node) { |
| 1698 node.receiver = visitExpression(node.receiver); | 1729 node.receiver = visitExpression(node.receiver); |
| 1699 _rewriteList(node.arguments); | 1730 _rewriteList(node.arguments); |
| 1700 return node; | 1731 return node; |
| 1701 } | 1732 } |
| 1702 | 1733 |
| 1734 Expression visitInvokeSuperMethod(InvokeSuperMethod node) { |
| 1735 _rewriteList(node.arguments); |
| 1736 return node; |
| 1737 } |
| 1738 |
| 1703 Expression visitInvokeConstructor(InvokeConstructor node) { | 1739 Expression visitInvokeConstructor(InvokeConstructor node) { |
| 1704 _rewriteList(node.arguments); | 1740 _rewriteList(node.arguments); |
| 1705 return node; | 1741 return node; |
| 1706 } | 1742 } |
| 1707 | 1743 |
| 1708 Expression visitConcatenateStrings(ConcatenateStrings node) { | 1744 Expression visitConcatenateStrings(ConcatenateStrings node) { |
| 1709 _rewriteList(node.arguments); | 1745 _rewriteList(node.arguments); |
| 1710 return node; | 1746 return node; |
| 1711 } | 1747 } |
| 1712 | 1748 |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1949 } | 1985 } |
| 1950 } | 1986 } |
| 1951 | 1987 |
| 1952 /// Destructively updates each entry of [l] with the result of visiting it. | 1988 /// Destructively updates each entry of [l] with the result of visiting it. |
| 1953 void _rewriteList(List<Expression> l) { | 1989 void _rewriteList(List<Expression> l) { |
| 1954 for (int i = 0; i < l.length; i++) { | 1990 for (int i = 0; i < l.length; i++) { |
| 1955 l[i] = visitExpression(l[i]); | 1991 l[i] = visitExpression(l[i]); |
| 1956 } | 1992 } |
| 1957 } | 1993 } |
| 1958 } | 1994 } |
| OLD | NEW |