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 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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 128 final Selector selector; | 128 final Selector selector; |
| 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 class InvokeSuperMethod extends Expression implements Invoke { | |
| 139 Expression receiver; | |
|
asgerf
2014/06/26 07:44:40
There should be no receiver
| |
| 140 final Selector selector; | |
| 141 final List<Expression> arguments; | |
| 142 | |
| 143 InvokeSuperMethod(this.selector, this.arguments) ; | |
| 144 | |
| 145 accept(Visitor visitor) => visitor.visitInvokeSuperMethod(this); | |
| 146 } | |
| 147 | |
| 138 /** | 148 /** |
| 139 * Call to a factory or generative constructor. | 149 * Call to a factory or generative constructor. |
| 140 */ | 150 */ |
| 141 class InvokeConstructor extends Expression implements Invoke { | 151 class InvokeConstructor extends Expression implements Invoke { |
| 142 final GenericType type; | 152 final GenericType type; |
| 143 final FunctionElement target; | 153 final FunctionElement target; |
| 144 final List<Expression> arguments; | 154 final List<Expression> arguments; |
| 145 final Selector selector; | 155 final Selector selector; |
| 146 final dart2js.Constant constant; | 156 final dart2js.Constant constant; |
| 147 | 157 |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 415 Statement body; | 425 Statement body; |
| 416 | 426 |
| 417 FunctionDefinition(this.parameters, this.body); | 427 FunctionDefinition(this.parameters, this.body); |
| 418 } | 428 } |
| 419 | 429 |
| 420 abstract class ExpressionVisitor<E> { | 430 abstract class ExpressionVisitor<E> { |
| 421 E visitExpression(Expression e) => e.accept(this); | 431 E visitExpression(Expression e) => e.accept(this); |
| 422 E visitVariable(Variable node); | 432 E visitVariable(Variable node); |
| 423 E visitInvokeStatic(InvokeStatic node); | 433 E visitInvokeStatic(InvokeStatic node); |
| 424 E visitInvokeMethod(InvokeMethod node); | 434 E visitInvokeMethod(InvokeMethod node); |
| 435 E visitInvokeSuperMethod(InvokeSuperMethod node); | |
| 425 E visitInvokeConstructor(InvokeConstructor node); | 436 E visitInvokeConstructor(InvokeConstructor node); |
| 426 E visitConcatenateStrings(ConcatenateStrings node); | 437 E visitConcatenateStrings(ConcatenateStrings node); |
| 427 E visitConstant(Constant node); | 438 E visitConstant(Constant node); |
| 428 E visitThis(This node); | 439 E visitThis(This node); |
| 429 E visitConditional(Conditional node); | 440 E visitConditional(Conditional node); |
| 430 E visitLogicalOperator(LogicalOperator node); | 441 E visitLogicalOperator(LogicalOperator node); |
| 431 E visitNot(Not node); | 442 E visitNot(Not node); |
| 432 E visitLiteralList(LiteralList node); | 443 E visitLiteralList(LiteralList node); |
| 433 E visitLiteralMap(LiteralMap node); | 444 E visitLiteralMap(LiteralMap node); |
| 434 } | 445 } |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 712 if (cont == returnContinuation) { | 723 if (cont == returnContinuation) { |
| 713 return new Return(invoke); | 724 return new Return(invoke); |
| 714 } else { | 725 } else { |
| 715 assert(cont.hasExactlyOneUse); | 726 assert(cont.hasExactlyOneUse); |
| 716 assert(cont.parameters.length == 1); | 727 assert(cont.parameters.length == 1); |
| 717 return buildContinuationAssignment(cont.parameters.single, invoke, | 728 return buildContinuationAssignment(cont.parameters.single, invoke, |
| 718 () => visit(cont.body)); | 729 () => visit(cont.body)); |
| 719 } | 730 } |
| 720 } | 731 } |
| 721 | 732 |
| 733 Statement visitInvokeSuperMethod(ir.InvokeSuperMethod node) { | |
| 734 List<Expression> arguments = translateArguments(node.arguments); | |
| 735 Expression invoke = new InvokeSuperMethod(node.selector, arguments); | |
| 736 ir.Continuation cont = node.continuation.definition; | |
| 737 if (cont == returnContinuation) { | |
| 738 return new Return(invoke); | |
| 739 } else { | |
| 740 assert(cont.hasExactlyOneUse); | |
| 741 assert(cont.parameters.length == 1); | |
| 742 return buildContinuationAssignment(cont.parameters.single, invoke, | |
| 743 () => visit(cont.body)); | |
| 744 } | |
| 745 } | |
| 746 | |
| 722 Statement visitConcatenateStrings(ir.ConcatenateStrings node) { | 747 Statement visitConcatenateStrings(ir.ConcatenateStrings node) { |
| 723 List<Expression> arguments = translateArguments(node.arguments); | 748 List<Expression> arguments = translateArguments(node.arguments); |
| 724 Expression concat = new ConcatenateStrings(arguments); | 749 Expression concat = new ConcatenateStrings(arguments); |
| 725 ir.Continuation cont = node.continuation.definition; | 750 ir.Continuation cont = node.continuation.definition; |
| 726 if (cont == returnContinuation) { | 751 if (cont == returnContinuation) { |
| 727 return new Return(concat); | 752 return new Return(concat); |
| 728 } else { | 753 } else { |
| 729 assert(cont.hasExactlyOneUse); | 754 assert(cont.hasExactlyOneUse); |
| 730 assert(cont.parameters.length == 1); | 755 assert(cont.parameters.length == 1); |
| 731 return buildContinuationAssignment(cont.parameters.single, concat, | 756 return buildContinuationAssignment(cont.parameters.single, concat, |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 942 // The binding environment. The rightmost element of the list is the nearest | 967 // The binding environment. The rightmost element of the list is the nearest |
| 943 // available enclosing binding. | 968 // available enclosing binding. |
| 944 List<Assign> environment; | 969 List<Assign> environment; |
| 945 | 970 |
| 946 /// Substitution map for labels. Any break to a label L should be substituted | 971 /// Substitution map for labels. Any break to a label L should be substituted |
| 947 /// for a break to L' if L maps to L'. | 972 /// for a break to L' if L maps to L'. |
| 948 Map<Label, Jump> labelRedirects = <Label, Jump>{}; | 973 Map<Label, Jump> labelRedirects = <Label, Jump>{}; |
| 949 | 974 |
| 950 /// Returns the redirect target of [label] or [label] itself if it should not | 975 /// Returns the redirect target of [label] or [label] itself if it should not |
| 951 /// be redirected. | 976 /// be redirected. |
| 952 Jump redirect(Break jump) { | 977 Jump redirect(Jump jump) { |
| 953 Jump newJump = labelRedirects[jump.target]; | 978 Jump newJump = labelRedirects[jump.target]; |
| 954 return newJump != null ? newJump : jump; | 979 return newJump != null ? newJump : jump; |
| 955 } | 980 } |
| 956 | 981 |
| 957 void rewrite(FunctionDefinition definition) { | 982 void rewrite(FunctionDefinition definition) { |
| 958 environment = <Assign>[]; | 983 environment = <Assign>[]; |
| 959 definition.body = visitStatement(definition.body); | 984 definition.body = visitStatement(definition.body); |
| 960 | 985 |
| 961 // TODO(kmillikin): Allow definitions that are not propagated. Here, | 986 // TODO(kmillikin): Allow definitions that are not propagated. Here, |
| 962 // this means rebuilding the binding with a recursively unnamed definition, | 987 // this means rebuilding the binding with a recursively unnamed definition, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1006 } | 1031 } |
| 1007 | 1032 |
| 1008 Expression visitInvokeMethod(InvokeMethod node) { | 1033 Expression visitInvokeMethod(InvokeMethod node) { |
| 1009 for (int i = node.arguments.length - 1; i >= 0; --i) { | 1034 for (int i = node.arguments.length - 1; i >= 0; --i) { |
| 1010 node.arguments[i] = visitExpression(node.arguments[i]); | 1035 node.arguments[i] = visitExpression(node.arguments[i]); |
| 1011 } | 1036 } |
| 1012 node.receiver = visitExpression(node.receiver); | 1037 node.receiver = visitExpression(node.receiver); |
| 1013 return node; | 1038 return node; |
| 1014 } | 1039 } |
| 1015 | 1040 |
| 1041 Expression visitInvokeSuperMethod(InvokeSuperMethod node) { | |
| 1042 for (int i = node.arguments.length - 1; i >= 0; --i) { | |
| 1043 node.arguments[i] = visitExpression(node.arguments[i]); | |
| 1044 } | |
| 1045 return node; | |
| 1046 } | |
| 1047 | |
| 1016 Expression visitInvokeConstructor(InvokeConstructor node) { | 1048 Expression visitInvokeConstructor(InvokeConstructor node) { |
| 1017 for (int i = node.arguments.length - 1; i >= 0; --i) { | 1049 for (int i = node.arguments.length - 1; i >= 0; --i) { |
| 1018 node.arguments[i] = visitExpression(node.arguments[i]); | 1050 node.arguments[i] = visitExpression(node.arguments[i]); |
| 1019 } | 1051 } |
| 1020 return node; | 1052 return node; |
| 1021 } | 1053 } |
| 1022 | 1054 |
| 1023 Expression visitConcatenateStrings(ConcatenateStrings node) { | 1055 Expression visitConcatenateStrings(ConcatenateStrings node) { |
| 1024 for (int i = node.arguments.length - 1; i >= 0; --i) { | 1056 for (int i = node.arguments.length - 1; i >= 0; --i) { |
| 1025 node.arguments[i] = visitExpression(node.arguments[i]); | 1057 node.arguments[i] = visitExpression(node.arguments[i]); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1059 Statement visitReturn(Return node) { | 1091 Statement visitReturn(Return node) { |
| 1060 node.value = visitExpression(node.value); | 1092 node.value = visitExpression(node.value); |
| 1061 return node; | 1093 return node; |
| 1062 } | 1094 } |
| 1063 | 1095 |
| 1064 | 1096 |
| 1065 Statement visitBreak(Break node) { | 1097 Statement visitBreak(Break node) { |
| 1066 // Redirect through chain of breaks. | 1098 // Redirect through chain of breaks. |
| 1067 // Note that useCount was accounted for at visitLabeledStatement. | 1099 // Note that useCount was accounted for at visitLabeledStatement. |
| 1068 // Note redirect may return either a Break or Continue statement. | 1100 // Note redirect may return either a Break or Continue statement. |
| 1069 node = redirect(node); | 1101 Jump jump = redirect(node); |
| 1070 if (node is Break && node.target.useCount == 1) { | 1102 if (jump is Break && jump.target.useCount == 1) { |
| 1071 --node.target.useCount; | 1103 --jump.target.useCount; |
| 1072 return visitStatement(node.target.binding.next); | 1104 return visitStatement(jump.target.binding.next); |
| 1073 } | 1105 } |
| 1074 return node; | 1106 return jump; |
| 1075 } | 1107 } |
| 1076 | 1108 |
| 1077 Statement visitContinue(Continue node) { | 1109 Statement visitContinue(Continue node) { |
| 1078 return node; | 1110 return node; |
| 1079 } | 1111 } |
| 1080 | 1112 |
| 1081 Statement visitLabeledStatement(LabeledStatement node) { | 1113 Statement visitLabeledStatement(LabeledStatement node) { |
| 1082 if (node.next is Jump) { | 1114 if (node.next is Jump) { |
| 1083 // Eliminate label if next is a break or continue statement | 1115 // Eliminate label if next is a break or continue statement |
| 1084 // Breaks to this label are redirected to the outer label. | 1116 // Breaks to this label are redirected to the outer label. |
| (...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1648 _rewriteList(node.arguments); | 1680 _rewriteList(node.arguments); |
| 1649 return node; | 1681 return node; |
| 1650 } | 1682 } |
| 1651 | 1683 |
| 1652 Expression visitInvokeMethod(InvokeMethod node) { | 1684 Expression visitInvokeMethod(InvokeMethod node) { |
| 1653 node.receiver = visitExpression(node.receiver); | 1685 node.receiver = visitExpression(node.receiver); |
| 1654 _rewriteList(node.arguments); | 1686 _rewriteList(node.arguments); |
| 1655 return node; | 1687 return node; |
| 1656 } | 1688 } |
| 1657 | 1689 |
| 1690 Expression visitInvokeSuperMethod(InvokeSuperMethod node) { | |
| 1691 _rewriteList(node.arguments); | |
| 1692 return node; | |
| 1693 } | |
| 1694 | |
| 1658 Expression visitInvokeConstructor(InvokeConstructor node) { | 1695 Expression visitInvokeConstructor(InvokeConstructor node) { |
| 1659 _rewriteList(node.arguments); | 1696 _rewriteList(node.arguments); |
| 1660 return node; | 1697 return node; |
| 1661 } | 1698 } |
| 1662 | 1699 |
| 1663 Expression visitConcatenateStrings(ConcatenateStrings node) { | 1700 Expression visitConcatenateStrings(ConcatenateStrings node) { |
| 1664 _rewriteList(node.arguments); | 1701 _rewriteList(node.arguments); |
| 1665 return node; | 1702 return node; |
| 1666 } | 1703 } |
| 1667 | 1704 |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1894 } | 1931 } |
| 1895 } | 1932 } |
| 1896 | 1933 |
| 1897 /// Destructively updates each entry of [l] with the result of visiting it. | 1934 /// Destructively updates each entry of [l] with the result of visiting it. |
| 1898 void _rewriteList(List<Expression> l) { | 1935 void _rewriteList(List<Expression> l) { |
| 1899 for (int i = 0; i < l.length; i++) { | 1936 for (int i = 0; i < l.length; i++) { |
| 1900 l[i] = visitExpression(l[i]); | 1937 l[i] = visitExpression(l[i]); |
| 1901 } | 1938 } |
| 1902 } | 1939 } |
| 1903 } | 1940 } |
| OLD | NEW |