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.optimization.statement_rewriter; | 5 library tree_ir.optimization.statement_rewriter; |
6 | 6 |
7 import 'optimization.dart' show Pass; | 7 import 'optimization.dart' show Pass; |
8 import '../tree_ir_nodes.dart'; | 8 import '../tree_ir_nodes.dart'; |
9 import '../../io/source_information.dart'; | 9 import '../../io/source_information.dart'; |
10 import '../../elements/elements.dart'; | 10 import '../../elements/elements.dart'; |
| 11 import '../../js/placeholder_safety.dart'; |
11 | 12 |
12 /** | 13 /** |
13 * Translates to direct-style. | 14 * Translates to direct-style. |
14 * | 15 * |
15 * In addition to the general IR constraints (see [CheckTreeIntegrity]), | 16 * In addition to the general IR constraints (see [CheckTreeIntegrity]), |
16 * the input is assumed to satisfy the following criteria: | 17 * the input is assumed to satisfy the following criteria: |
17 * | 18 * |
18 * All expressions other than those nested in [Assign] or [ExpressionStatement] | 19 * All expressions other than those nested in [Assign] or [ExpressionStatement] |
19 * must be simple. A [VariableUse] and [This] is a simple expression. | 20 * must be simple. A [VariableUse] and [This] is a simple expression. |
20 * The right-hand of an [Assign] may not be an [Assign]. | 21 * The right-hand of an [Assign] may not be an [Assign]. |
(...skipping 1112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 | 1134 |
1134 Expression makeCondition(Expression e, bool polarity) { | 1135 Expression makeCondition(Expression e, bool polarity) { |
1135 return polarity ? e : new Not(e); | 1136 return polarity ? e : new Not(e); |
1136 } | 1137 } |
1137 | 1138 |
1138 Statement getBranch(If node, bool polarity) { | 1139 Statement getBranch(If node, bool polarity) { |
1139 return polarity ? node.thenStatement : node.elseStatement; | 1140 return polarity ? node.thenStatement : node.elseStatement; |
1140 } | 1141 } |
1141 | 1142 |
1142 void handleForeignCode(ForeignCode node) { | 1143 void handleForeignCode(ForeignCode node) { |
1143 // Arguments will get inserted in a JS code template. The arguments will | 1144 // Some arguments will get inserted in a JS code template. The arguments |
1144 // not always be evaluated (e.g. if the template is '# && #'). | 1145 // will not always be evaluated (e.g. the second placeholder in the template |
1145 // TODO(asgerf): We could analyze the JS AST to see if arguments are | 1146 // '# && #'). |
1146 // definitely evaluated left-to-right. | 1147 |
| 1148 // TODO(sra): Find out which tree_ir expressions are not nullable. It helps |
| 1149 // a lot with templates like '#.push(#)'. |
| 1150 bool isNullable(e) => true; |
| 1151 |
| 1152 int safeArguments = |
| 1153 PlaceholderSafetyAnalysis.analyze(node.codeTemplate.ast, isNullable); |
1147 inEmptyEnvironment(() { | 1154 inEmptyEnvironment(() { |
1148 _rewriteList(node.arguments); | 1155 for (int i = node.arguments.length - 1; i >= safeArguments; --i) { |
| 1156 node.arguments[i] = visitExpression(node.arguments[i]); |
| 1157 } |
1149 }); | 1158 }); |
| 1159 for (int i = safeArguments - 1; i >= 0; --i) { |
| 1160 node.arguments[i] = visitExpression(node.arguments[i]); |
| 1161 } |
1150 } | 1162 } |
1151 | 1163 |
1152 @override | 1164 @override |
1153 Expression visitForeignExpression(ForeignExpression node) { | 1165 Expression visitForeignExpression(ForeignExpression node) { |
1154 handleForeignCode(node); | 1166 handleForeignCode(node); |
1155 return node; | 1167 return node; |
1156 } | 1168 } |
1157 | 1169 |
1158 @override | 1170 @override |
1159 Statement visitForeignStatement(ForeignStatement node) { | 1171 Statement visitForeignStatement(ForeignStatement node) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1259 VariableUseCallback callback; | 1271 VariableUseCallback callback; |
1260 | 1272 |
1261 VariableUseVisitor(this.callback); | 1273 VariableUseVisitor(this.callback); |
1262 | 1274 |
1263 visitVariableUse(VariableUse use) => callback(use); | 1275 visitVariableUse(VariableUse use) => callback(use); |
1264 | 1276 |
1265 static void visit(Expression node, VariableUseCallback callback) { | 1277 static void visit(Expression node, VariableUseCallback callback) { |
1266 new VariableUseVisitor(callback).visitExpression(node); | 1278 new VariableUseVisitor(callback).visitExpression(node); |
1267 } | 1279 } |
1268 } | 1280 } |
OLD | NEW |