| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 rewrite_async; | 5 library rewrite_async; |
| 6 | 6 |
| 7 import "dart:math" show max; | 7 import "dart:math" show max; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 | 9 |
| 10 import 'package:_internal/compiler/js_lib/shared/async_await_error_codes.dart' | 10 import 'package:_internal/compiler/js_lib/shared/async_await_error_codes.dart' |
| (...skipping 978 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 [condition, gotoAndBreak(startLabel)])); | 989 [condition, gotoAndBreak(startLabel)])); |
| 990 }, store: false); | 990 }, store: false); |
| 991 beginLabel(afterLabel); | 991 beginLabel(afterLabel); |
| 992 } | 992 } |
| 993 | 993 |
| 994 @override | 994 @override |
| 995 void visitEmptyStatement(js.EmptyStatement node) { | 995 void visitEmptyStatement(js.EmptyStatement node) { |
| 996 addStatement(node); | 996 addStatement(node); |
| 997 } | 997 } |
| 998 | 998 |
| 999 void visitExpressionInStatementContext(js.Expression node) { | 999 |
| 1000 if (node is js.VariableDeclarationList) { | 1000 @override |
| 1001 // Treat js.VariableDeclarationList as a statement. | 1001 void visitExpressionStatement(js.ExpressionStatement node) { |
| 1002 visitVariableDeclarationList(node); | 1002 visitExpressionIgnoreResult(node.expression); |
| 1003 } else { | |
| 1004 visitExpressionIgnoreResult(node); | |
| 1005 } | |
| 1006 } | 1003 } |
| 1007 | 1004 |
| 1008 @override | 1005 @override |
| 1009 void visitExpressionStatement(js.ExpressionStatement node) { | |
| 1010 visitExpressionInStatementContext(node.expression); | |
| 1011 } | |
| 1012 | |
| 1013 @override | |
| 1014 void visitFor(js.For node) { | 1006 void visitFor(js.For node) { |
| 1015 if (!shouldTransform(node)) { | 1007 if (!shouldTransform(node)) { |
| 1016 bool oldInsideUntranslated = insideUntranslatedBreakable; | 1008 bool oldInsideUntranslated = insideUntranslatedBreakable; |
| 1017 insideUntranslatedBreakable = true; | 1009 insideUntranslatedBreakable = true; |
| 1018 // Note that node.init, node.condition, node.update all can be null, but | 1010 // Note that node.init, node.condition, node.update all can be null, but |
| 1019 // withExpressions handles that. | 1011 // withExpressions handles that. |
| 1020 withExpressions([ | 1012 withExpressions([ |
| 1021 node.init, | 1013 node.init, |
| 1022 node.condition, | 1014 node.condition, |
| 1023 node.update | 1015 node.update |
| 1024 ], (List<js.Expression> transformed) { | 1016 ], (List<js.Expression> transformed) { |
| 1025 addStatement(new js.For(transformed[0], transformed[1], transformed[2], | 1017 addStatement(new js.For(transformed[0], transformed[1], transformed[2], |
| 1026 translateInBlock(node.body))); | 1018 translateInBlock(node.body))); |
| 1027 }); | 1019 }); |
| 1028 insideUntranslatedBreakable = oldInsideUntranslated; | 1020 insideUntranslatedBreakable = oldInsideUntranslated; |
| 1029 return; | 1021 return; |
| 1030 } | 1022 } |
| 1031 | 1023 |
| 1032 if (node.init != null) { | 1024 if (node.init != null) { |
| 1033 visitExpressionInStatementContext(node.init); | 1025 addExpressionStatement(visitExpression(node.init)); |
| 1034 } | 1026 } |
| 1035 int startLabel = newLabel("for condition"); | 1027 int startLabel = newLabel("for condition"); |
| 1036 // If there is no update, continuing the loop is the same as going to the | 1028 // If there is no update, continuing the loop is the same as going to the |
| 1037 // start. | 1029 // start. |
| 1038 int continueLabel = | 1030 int continueLabel = |
| 1039 (node.update == null) ? startLabel : newLabel("for update"); | 1031 (node.update == null) ? startLabel : newLabel("for update"); |
| 1040 continueLabels[node] = continueLabel; | 1032 continueLabels[node] = continueLabel; |
| 1041 int afterLabel = newLabel("after for"); | 1033 int afterLabel = newLabel("after for"); |
| 1042 breakLabels[node] = afterLabel; | 1034 breakLabels[node] = afterLabel; |
| 1043 beginLabel(startLabel); | 1035 beginLabel(startLabel); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1147 return unsupported(node); | 1139 return unsupported(node); |
| 1148 } | 1140 } |
| 1149 | 1141 |
| 1150 @override | 1142 @override |
| 1151 void visitLabeledStatement(js.LabeledStatement node) { | 1143 void visitLabeledStatement(js.LabeledStatement node) { |
| 1152 if (!shouldTransform(node)) { | 1144 if (!shouldTransform(node)) { |
| 1153 addStatement( | 1145 addStatement( |
| 1154 new js.LabeledStatement(node.label, translateInBlock(node.body))); | 1146 new js.LabeledStatement(node.label, translateInBlock(node.body))); |
| 1155 return; | 1147 return; |
| 1156 } | 1148 } |
| 1149 // `continue label` is really continuing the nested loop. |
| 1150 // This is set up in [PreTranslationAnalysis.visitContinue]. |
| 1151 // Here we only need a breakLabel: |
| 1157 int breakLabel = newLabel("break ${node.label}"); | 1152 int breakLabel = newLabel("break ${node.label}"); |
| 1158 int continueLabel = newLabel("continue ${node.label}"); | |
| 1159 breakLabels[node] = breakLabel; | 1153 breakLabels[node] = breakLabel; |
| 1160 continueLabels[node] = continueLabel; | |
| 1161 | 1154 |
| 1162 beginLabel(continueLabel); | |
| 1163 jumpTargets.add(node); | 1155 jumpTargets.add(node); |
| 1164 visitStatement(node.body); | 1156 visitStatement(node.body); |
| 1165 jumpTargets.removeLast(); | 1157 jumpTargets.removeLast(); |
| 1166 beginLabel(breakLabel); | 1158 beginLabel(breakLabel); |
| 1167 } | 1159 } |
| 1168 | 1160 |
| 1169 @override | 1161 @override |
| 1170 js.Expression visitLiteralBool(js.LiteralBool node) => node; | 1162 js.Expression visitLiteralBool(js.LiteralBool node) => node; |
| 1171 | 1163 |
| 1172 @override | 1164 @override |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1528 } | 1520 } |
| 1529 beginLabel(afterFinallyLabel); | 1521 beginLabel(afterFinallyLabel); |
| 1530 } | 1522 } |
| 1531 | 1523 |
| 1532 @override | 1524 @override |
| 1533 visitVariableDeclaration(js.VariableDeclaration node) { | 1525 visitVariableDeclaration(js.VariableDeclaration node) { |
| 1534 unreachable(node); | 1526 unreachable(node); |
| 1535 } | 1527 } |
| 1536 | 1528 |
| 1537 @override | 1529 @override |
| 1538 void visitVariableDeclarationList(js.VariableDeclarationList node) { | 1530 js.Expression visitVariableDeclarationList(js.VariableDeclarationList node) { |
| 1531 List<js.Assignment> initializations = new List<js.Assignment>(); |
| 1532 |
| 1539 // Declaration of local variables is hoisted outside the helper but the | 1533 // Declaration of local variables is hoisted outside the helper but the |
| 1540 // initialization is done here. | 1534 // initialization is done here. |
| 1541 for (js.VariableInitialization initialization in node.declarations) { | 1535 for (js.VariableInitialization initialization in node.declarations) { |
| 1542 js.VariableDeclaration declaration = initialization.declaration; | 1536 js.VariableDeclaration declaration = initialization.declaration; |
| 1543 localVariables.add(declaration); | 1537 localVariables.add(declaration); |
| 1544 if (initialization.value != null) { | 1538 if (initialization.value != null) { |
| 1545 withExpression(initialization.value, (js.Expression value) { | 1539 withExpression(initialization.value, (js.Expression value) { |
| 1546 addStatement(new js.ExpressionStatement( | 1540 initializations.add( |
| 1547 new js.Assignment(new js.VariableUse(declaration.name), value))); | 1541 new js.Assignment(new js.VariableUse(declaration.name), value)); |
| 1548 }, store: false); | 1542 }, store: false); |
| 1549 } | 1543 } |
| 1550 } | 1544 } |
| 1545 if (initializations.isEmpty) { |
| 1546 // Dummy expression. Will be dropped by [visitExpressionIgnoreResult]. |
| 1547 return js.number(0); |
| 1548 } else { |
| 1549 return initializations.reduce( |
| 1550 (js.Expression first, js.Expression second) { |
| 1551 return new js.Binary(",", first, second); |
| 1552 }); |
| 1553 } |
| 1551 } | 1554 } |
| 1552 | 1555 |
| 1553 @override | 1556 @override |
| 1554 void visitVariableInitialization(js.VariableInitialization node) { | 1557 void visitVariableInitialization(js.VariableInitialization node) { |
| 1555 unreachable(node); | 1558 unreachable(node); |
| 1556 } | 1559 } |
| 1557 | 1560 |
| 1558 @override | 1561 @override |
| 1559 js.Expression visitVariableUse(js.VariableUse node) { | 1562 js.Expression visitVariableUse(js.VariableUse node) { |
| 1560 Pair<String, String> renaming = variableRenamings.lastWhere( | 1563 Pair<String, String> renaming = variableRenamings.lastWhere( |
| (...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2244 bool visitConditional(js.Conditional node) { | 2247 bool visitConditional(js.Conditional node) { |
| 2245 bool condition = visit(node.condition); | 2248 bool condition = visit(node.condition); |
| 2246 bool then = visit(node.then); | 2249 bool then = visit(node.then); |
| 2247 bool otherwise = visit(node.otherwise); | 2250 bool otherwise = visit(node.otherwise); |
| 2248 return condition || then || otherwise; | 2251 return condition || then || otherwise; |
| 2249 } | 2252 } |
| 2250 | 2253 |
| 2251 @override | 2254 @override |
| 2252 bool visitContinue(js.Continue node) { | 2255 bool visitContinue(js.Continue node) { |
| 2253 if (node.targetLabel != null) { | 2256 if (node.targetLabel != null) { |
| 2254 targets[node] = labelledStatements.lastWhere( | 2257 js.LabeledStatement targetLabel = labelledStatements.lastWhere( |
| 2255 (js.LabeledStatement stm) => stm.label == node.targetLabel); | 2258 (js.LabeledStatement stm) => stm.label == node.targetLabel); |
| 2259 js.Loop targetStatement = targetLabel.body; |
| 2260 targets[node] = targetStatement; |
| 2256 } else { | 2261 } else { |
| 2257 targets[node] = | 2262 targets[node] = |
| 2258 loopsAndSwitches.lastWhere((js.Node node) => node is! js.Switch); | 2263 loopsAndSwitches.lastWhere((js.Node node) => node is! js.Switch); |
| 2259 } | 2264 } |
| 2260 assert(() { | 2265 assert(() { |
| 2261 js.Node target = targets[node]; | 2266 js.Node target = targets[node]; |
| 2262 return target is js.Loop || | 2267 return target is js.Loop || |
| 2263 (target is js.LabeledStatement && target.body is js.Loop); | 2268 (target is js.LabeledStatement && target.body is js.Loop); |
| 2264 }); | 2269 }); |
| 2265 return false; | 2270 return false; |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2524 return condition || body; | 2529 return condition || body; |
| 2525 } | 2530 } |
| 2526 | 2531 |
| 2527 @override | 2532 @override |
| 2528 bool visitDartYield(js.DartYield node) { | 2533 bool visitDartYield(js.DartYield node) { |
| 2529 hasYield = true; | 2534 hasYield = true; |
| 2530 visit(node.expression); | 2535 visit(node.expression); |
| 2531 return true; | 2536 return true; |
| 2532 } | 2537 } |
| 2533 } | 2538 } |
| OLD | NEW |