| 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 show Element, FunctionElement, FunctionSignature, ParameterElement, | 9 show Element, FunctionElement, FunctionSignature, ParameterElement, |
| 10 ClassElement; | 10 ClassElement; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 final List<Expression> arguments; | 129 final List<Expression> arguments; |
| 130 | 130 |
| 131 InvokeMethod(this.receiver, this.selector, this.arguments) { | 131 InvokeMethod(this.receiver, this.selector, this.arguments) { |
| 132 assert(receiver != null); | 132 assert(receiver != null); |
| 133 } | 133 } |
| 134 | 134 |
| 135 accept(ExpressionVisitor visitor) => visitor.visitInvokeMethod(this); | 135 accept(ExpressionVisitor visitor) => visitor.visitInvokeMethod(this); |
| 136 } | 136 } |
| 137 | 137 |
| 138 /** | 138 /** |
| 139 * Non-const call to a factory or generative constructor. | 139 * Call to a factory or generative constructor. |
| 140 */ | 140 */ |
| 141 class InvokeConstructor extends Expression implements Invoke { | 141 class InvokeConstructor extends Expression implements Invoke { |
| 142 final GenericType type; | 142 final GenericType type; |
| 143 final FunctionElement target; | 143 final FunctionElement target; |
| 144 final List<Expression> arguments; | 144 final List<Expression> arguments; |
| 145 final Selector selector; | 145 final Selector selector; |
| 146 final dart2js.Constant constant; |
| 146 | 147 |
| 147 InvokeConstructor(this.type, this.target, this.selector, this.arguments); | 148 InvokeConstructor(this.type, this.target, this.selector, this.arguments, |
| 149 [this.constant]); |
| 148 | 150 |
| 149 ClassElement get targetClass => target.enclosingElement; | 151 ClassElement get targetClass => target.enclosingElement; |
| 150 | 152 |
| 151 accept(ExpressionVisitor visitor) => visitor.visitInvokeConstructor(this); | 153 accept(ExpressionVisitor visitor) => visitor.visitInvokeConstructor(this); |
| 152 } | 154 } |
| 153 | 155 |
| 154 /// Calls [toString] on each argument and concatenates the results. | 156 /// Calls [toString] on each argument and concatenates the results. |
| 155 class ConcatenateStrings extends Expression { | 157 class ConcatenateStrings extends Expression { |
| 156 final List<Expression> arguments; | 158 final List<Expression> arguments; |
| 159 final dart2js.Constant constant; |
| 157 | 160 |
| 158 ConcatenateStrings(this.arguments); | 161 ConcatenateStrings(this.arguments, [this.constant]); |
| 159 | 162 |
| 160 accept(ExpressionVisitor visitor) => visitor.visitConcatenateStrings(this); | 163 accept(ExpressionVisitor visitor) => visitor.visitConcatenateStrings(this); |
| 161 } | 164 } |
| 162 | 165 |
| 163 /** | 166 /** |
| 164 * A constant. | 167 * A constant. |
| 165 */ | 168 */ |
| 166 class Constant extends Expression { | 169 class Constant extends Expression { |
| 167 dart2js.Constant value; | 170 dart2js.Constant value; |
| 168 | 171 |
| 169 Constant(this.value); | 172 Constant(this.value); |
| 170 | 173 |
| 171 accept(ExpressionVisitor visitor) => visitor.visitConstant(this); | 174 accept(ExpressionVisitor visitor) => visitor.visitConstant(this); |
| 172 } | 175 } |
| 173 | 176 |
| 174 class LiteralList extends Expression { | 177 class LiteralList extends Expression { |
| 178 final GenericType type; |
| 175 final List<Expression> values; | 179 final List<Expression> values; |
| 180 final dart2js.Constant constant; |
| 176 | 181 |
| 177 LiteralList(this.values) ; | 182 LiteralList(this.type, this.values, [this.constant]); |
| 178 | 183 |
| 179 accept(ExpressionVisitor visitor) => visitor.visitLiteralList(this); | 184 accept(ExpressionVisitor visitor) => visitor.visitLiteralList(this); |
| 180 } | 185 } |
| 181 | 186 |
| 182 class LiteralMap extends Expression { | 187 class LiteralMap extends Expression { |
| 188 final GenericType type; |
| 183 final List<Expression> keys; | 189 final List<Expression> keys; |
| 184 final List<Expression> values; | 190 final List<Expression> values; |
| 191 final dart2js.Constant constant; |
| 185 | 192 |
| 186 LiteralMap(this.keys, this.values) ; | 193 LiteralMap(this.type, this.keys, this.values, [this.constant]); |
| 187 | 194 |
| 188 accept(ExpressionVisitor visitor) => visitor.visitLiteralMap(this); | 195 accept(ExpressionVisitor visitor) => visitor.visitLiteralMap(this); |
| 189 } | 196 } |
| 190 | 197 |
| 191 class InvokeConstConstructor extends Expression implements Invoke { | |
| 192 final GenericType type; | |
| 193 final FunctionElement target; | |
| 194 final List<Expression> arguments; | |
| 195 final Selector selector; | |
| 196 | |
| 197 ClassElement get targetClass => target.enclosingElement; | |
| 198 | |
| 199 InvokeConstConstructor(this.type, this.target, this.selector, this.arguments); | |
| 200 | |
| 201 accept(ExpressionVisitor visitor) => visitor.visitInvokeConstConstructor(this)
; | |
| 202 } | |
| 203 | |
| 204 /// A conditional expression. | 198 /// A conditional expression. |
| 205 class Conditional extends Expression { | 199 class Conditional extends Expression { |
| 206 Expression condition; | 200 Expression condition; |
| 207 Expression thenExpression; | 201 Expression thenExpression; |
| 208 Expression elseExpression; | 202 Expression elseExpression; |
| 209 | 203 |
| 210 Conditional(this.condition, this.thenExpression, this.elseExpression); | 204 Conditional(this.condition, this.thenExpression, this.elseExpression); |
| 211 | 205 |
| 212 accept(ExpressionVisitor visitor) => visitor.visitConditional(this); | 206 accept(ExpressionVisitor visitor) => visitor.visitConditional(this); |
| 213 } | 207 } |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 E visitInvokeStatic(InvokeStatic node); | 419 E visitInvokeStatic(InvokeStatic node); |
| 426 E visitInvokeMethod(InvokeMethod node); | 420 E visitInvokeMethod(InvokeMethod node); |
| 427 E visitInvokeConstructor(InvokeConstructor node); | 421 E visitInvokeConstructor(InvokeConstructor node); |
| 428 E visitConcatenateStrings(ConcatenateStrings node); | 422 E visitConcatenateStrings(ConcatenateStrings node); |
| 429 E visitConstant(Constant node); | 423 E visitConstant(Constant node); |
| 430 E visitConditional(Conditional node); | 424 E visitConditional(Conditional node); |
| 431 E visitLogicalOperator(LogicalOperator node); | 425 E visitLogicalOperator(LogicalOperator node); |
| 432 E visitNot(Not node); | 426 E visitNot(Not node); |
| 433 E visitLiteralList(LiteralList node); | 427 E visitLiteralList(LiteralList node); |
| 434 E visitLiteralMap(LiteralMap node); | 428 E visitLiteralMap(LiteralMap node); |
| 435 E visitInvokeConstConstructor(InvokeConstConstructor node); | |
| 436 } | 429 } |
| 437 | 430 |
| 438 abstract class StatementVisitor<S> { | 431 abstract class StatementVisitor<S> { |
| 439 S visitStatement(Statement s) => s.accept(this); | 432 S visitStatement(Statement s) => s.accept(this); |
| 440 S visitLabeledStatement(LabeledStatement node); | 433 S visitLabeledStatement(LabeledStatement node); |
| 441 S visitAssign(Assign node); | 434 S visitAssign(Assign node); |
| 442 S visitReturn(Return node); | 435 S visitReturn(Return node); |
| 443 S visitBreak(Break node); | 436 S visitBreak(Break node); |
| 444 S visitContinue(Continue node); | 437 S visitContinue(Continue node); |
| 445 S visitIf(If node); | 438 S visitIf(If node); |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 659 for (ir.Parameter p in node.parameters) { | 652 for (ir.Parameter p in node.parameters) { |
| 660 Variable parameter = getVariable(p); | 653 Variable parameter = getVariable(p); |
| 661 assert(parameter != null); | 654 assert(parameter != null); |
| 662 parameters.add(parameter); | 655 parameters.add(parameter); |
| 663 } | 656 } |
| 664 function = new FunctionDefinition(parameters, visit(node.body)); | 657 function = new FunctionDefinition(parameters, visit(node.body)); |
| 665 return null; | 658 return null; |
| 666 } | 659 } |
| 667 | 660 |
| 668 Statement visitLetPrim(ir.LetPrim node) { | 661 Statement visitLetPrim(ir.LetPrim node) { |
| 669 // LetPrim is translated to Assign. | |
| 670 Expression definition = visit(node.primitive); | |
| 671 Variable variable = getVariable(node.primitive); | 662 Variable variable = getVariable(node.primitive); |
| 672 if (variable != null) { // Variable is null if primitive is unused. | 663 return variable == null |
| 673 return new Assign(variable, definition, visit(node.body)); | 664 ? visit(node.body) |
| 674 } else if (node.primitive is ir.Constant) { | 665 : new Assign(variable, visit(node.primitive), visit(node.body)); |
| 675 // TODO(kmillikin): Implement more systematic treatment of pure CPS | |
| 676 // values (e.g., as part of a shrinking reductions pass). | |
| 677 return visit(node.body); | |
| 678 } else { | |
| 679 return new ExpressionStatement(definition, visit(node.body)); | |
| 680 } | |
| 681 } | 666 } |
| 682 | 667 |
| 683 Statement visitLetCont(ir.LetCont node) { | 668 Statement visitLetCont(ir.LetCont node) { |
| 684 Label label; | 669 Label label; |
| 685 if (node.continuation.hasMultipleUses) { | 670 if (node.continuation.hasMultipleUses) { |
| 686 label = new Label(); | 671 label = new Label(); |
| 687 labels[node.continuation] = label; | 672 labels[node.continuation] = label; |
| 688 } | 673 } |
| 689 Statement body = visit(node.body); | 674 Statement body = visit(node.body); |
| 690 // The continuation's body is not always translated directly here because | 675 // The continuation's body is not always translated directly here because |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 804 thenStatement = | 789 thenStatement = |
| 805 cont.hasExactlyOneUse ? visit(cont.body) : new Break(labels[cont]); | 790 cont.hasExactlyOneUse ? visit(cont.body) : new Break(labels[cont]); |
| 806 cont = node.falseContinuation.definition; | 791 cont = node.falseContinuation.definition; |
| 807 assert(cont.parameters.isEmpty); | 792 assert(cont.parameters.isEmpty); |
| 808 elseStatement = | 793 elseStatement = |
| 809 cont.hasExactlyOneUse ? visit(cont.body) : new Break(labels[cont]); | 794 cont.hasExactlyOneUse ? visit(cont.body) : new Break(labels[cont]); |
| 810 return new If(condition, thenStatement, elseStatement); | 795 return new If(condition, thenStatement, elseStatement); |
| 811 } | 796 } |
| 812 | 797 |
| 813 Expression visitInvokeConstConstructor(ir.InvokeConstConstructor node) { | 798 Expression visitInvokeConstConstructor(ir.InvokeConstConstructor node) { |
| 814 return new InvokeConstConstructor(node.type, node.constructor, node.selector
, | 799 return new InvokeConstructor( |
| 815 translateArguments(node.arguments)); | 800 node.type, |
| 801 node.constructor, |
| 802 node.selector, |
| 803 translateArguments(node.arguments), |
| 804 node.constant); |
| 816 } | 805 } |
| 817 | 806 |
| 818 Expression visitConstant(ir.Constant node) { | 807 Expression visitConstant(ir.Constant node) { |
| 819 return new Constant(node.value); | 808 return new Constant(node.value); |
| 820 } | 809 } |
| 821 | 810 |
| 822 Expression visitLiteralList(ir.LiteralList node) { | 811 Expression visitLiteralList(ir.LiteralList node) { |
| 823 return new LiteralList(translateArguments(node.values)); | 812 return new LiteralList( |
| 813 node.type, |
| 814 translateArguments(node.values), |
| 815 node.constant); |
| 824 } | 816 } |
| 825 | 817 |
| 826 Expression visitLiteralMap(ir.LiteralMap node) { | 818 Expression visitLiteralMap(ir.LiteralMap node) { |
| 827 return new LiteralMap( | 819 return new LiteralMap( |
| 820 node.type, |
| 828 translateArguments(node.keys), | 821 translateArguments(node.keys), |
| 829 translateArguments(node.values)); | 822 translateArguments(node.values), |
| 823 node.constant); |
| 830 } | 824 } |
| 831 | 825 |
| 832 Expression visitParameter(ir.Parameter node) { | 826 Expression visitParameter(ir.Parameter node) { |
| 833 // Continuation parameters are not visited (continuations themselves are | 827 // Continuation parameters are not visited (continuations themselves are |
| 834 // not visited yet). | 828 // not visited yet). |
| 835 compiler.internalError(compiler.currentElement, 'Unexpected IR node.'); | 829 compiler.internalError(compiler.currentElement, 'Unexpected IR node.'); |
| 836 return null; | 830 return null; |
| 837 } | 831 } |
| 838 | 832 |
| 839 Expression visitContinuation(ir.Continuation node) { | 833 Expression visitContinuation(ir.Continuation node) { |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1010 return node; | 1004 return node; |
| 1011 } | 1005 } |
| 1012 | 1006 |
| 1013 Expression visitInvokeConstructor(InvokeConstructor node) { | 1007 Expression visitInvokeConstructor(InvokeConstructor node) { |
| 1014 for (int i = node.arguments.length - 1; i >= 0; --i) { | 1008 for (int i = node.arguments.length - 1; i >= 0; --i) { |
| 1015 node.arguments[i] = visitExpression(node.arguments[i]); | 1009 node.arguments[i] = visitExpression(node.arguments[i]); |
| 1016 } | 1010 } |
| 1017 return node; | 1011 return node; |
| 1018 } | 1012 } |
| 1019 | 1013 |
| 1020 Expression visitInvokeConstConstructor(InvokeConstConstructor node) { | |
| 1021 for (int i = node.arguments.length - 1; i >= 0; --i) { | |
| 1022 node.arguments[i] = visitExpression(node.arguments[i]); | |
| 1023 } | |
| 1024 return node; | |
| 1025 } | |
| 1026 | |
| 1027 Expression visitConcatenateStrings(ConcatenateStrings node) { | 1014 Expression visitConcatenateStrings(ConcatenateStrings node) { |
| 1028 for (int i = node.arguments.length - 1; i >= 0; --i) { | 1015 for (int i = node.arguments.length - 1; i >= 0; --i) { |
| 1029 node.arguments[i] = visitExpression(node.arguments[i]); | 1016 node.arguments[i] = visitExpression(node.arguments[i]); |
| 1030 } | 1017 } |
| 1031 return node; | 1018 return node; |
| 1032 } | 1019 } |
| 1033 | 1020 |
| 1034 Expression visitConditional(Conditional node) { | 1021 Expression visitConditional(Conditional node) { |
| 1035 node.condition = visitExpression(node.condition); | 1022 node.condition = visitExpression(node.condition); |
| 1036 | 1023 |
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1733 if (node.condition is Not) { | 1720 if (node.condition is Not) { |
| 1734 node.condition = (node.condition as Not).operand; | 1721 node.condition = (node.condition as Not).operand; |
| 1735 Expression tmp = node.thenExpression; | 1722 Expression tmp = node.thenExpression; |
| 1736 node.thenExpression = node.elseExpression; | 1723 node.thenExpression = node.elseExpression; |
| 1737 node.elseExpression = tmp; | 1724 node.elseExpression = tmp; |
| 1738 } | 1725 } |
| 1739 | 1726 |
| 1740 return node; | 1727 return node; |
| 1741 } | 1728 } |
| 1742 | 1729 |
| 1743 Expression visitInvokeConstConstructor(InvokeConstConstructor node) { | |
| 1744 _rewriteList(node.arguments); | |
| 1745 return node; | |
| 1746 } | |
| 1747 | |
| 1748 Expression visitLogicalOperator(LogicalOperator node) { | 1730 Expression visitLogicalOperator(LogicalOperator node) { |
| 1749 node.left = makeCondition(node.left, true); | 1731 node.left = makeCondition(node.left, true); |
| 1750 node.right = makeCondition(node.right, true); | 1732 node.right = makeCondition(node.right, true); |
| 1751 return node; | 1733 return node; |
| 1752 } | 1734 } |
| 1753 | 1735 |
| 1754 /// True if the given expression is known to evaluate to a boolean. | 1736 /// True if the given expression is known to evaluate to a boolean. |
| 1755 /// This will not recursively traverse [Conditional] expressions, but if | 1737 /// This will not recursively traverse [Conditional] expressions, but if |
| 1756 /// applied to the result of [visitExpression] conditionals will have been | 1738 /// applied to the result of [visitExpression] conditionals will have been |
| 1757 /// rewritten anyway. | 1739 /// rewritten anyway. |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1895 } | 1877 } |
| 1896 } | 1878 } |
| 1897 | 1879 |
| 1898 /// Destructively updates each entry of [l] with the result of visiting it. | 1880 /// Destructively updates each entry of [l] with the result of visiting it. |
| 1899 void _rewriteList(List<Expression> l) { | 1881 void _rewriteList(List<Expression> l) { |
| 1900 for (int i = 0; i < l.length; i++) { | 1882 for (int i = 0; i < l.length; i++) { |
| 1901 l[i] = visitExpression(l[i]); | 1883 l[i] = visitExpression(l[i]); |
| 1902 } | 1884 } |
| 1903 } | 1885 } |
| 1904 } | 1886 } |
| OLD | NEW |