OLD | NEW |
---|---|
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 tra// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
sigurdm
2016/04/26 05:15:05
This looks like a mistake
| |
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:js_runtime/shared/async_await_error_codes.dart' as error_codes; | 10 import 'package:js_runtime/shared/async_await_error_codes.dart' as error_codes; |
11 | 11 |
(...skipping 948 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
960 | 960 |
961 @override | 961 @override |
962 void visitDefault(js.Default node) => unreachable(node); | 962 void visitDefault(js.Default node) => unreachable(node); |
963 | 963 |
964 @override | 964 @override |
965 void visitDo(js.Do node) { | 965 void visitDo(js.Do node) { |
966 if (!shouldTransform(node)) { | 966 if (!shouldTransform(node)) { |
967 bool oldInsideUntranslatedBreakable = insideUntranslatedBreakable; | 967 bool oldInsideUntranslatedBreakable = insideUntranslatedBreakable; |
968 insideUntranslatedBreakable = true; | 968 insideUntranslatedBreakable = true; |
969 addStatement(js.js.statement('do {#} while (#)', | 969 addStatement(js.js.statement('do {#} while (#)', |
970 [translateInBlock(node.body), visitExpression(node.condition)])); | 970 [translateToStatement(node.body), visitExpression(node.condition)])); |
971 insideUntranslatedBreakable = oldInsideUntranslatedBreakable; | 971 insideUntranslatedBreakable = oldInsideUntranslatedBreakable; |
972 return; | 972 return; |
973 } | 973 } |
974 int startLabel = newLabel("do body"); | 974 int startLabel = newLabel("do body"); |
975 | 975 |
976 int continueLabel = newLabel("do condition"); | 976 int continueLabel = newLabel("do condition"); |
977 continueLabels[node] = continueLabel; | 977 continueLabels[node] = continueLabel; |
978 | 978 |
979 int afterLabel = newLabel("after do"); | 979 int afterLabel = newLabel("after do"); |
980 breakLabels[node] = afterLabel; | 980 breakLabels[node] = afterLabel; |
(...skipping 25 matching lines...) Expand all Loading... | |
1006 @override | 1006 @override |
1007 void visitFor(js.For node) { | 1007 void visitFor(js.For node) { |
1008 if (!shouldTransform(node)) { | 1008 if (!shouldTransform(node)) { |
1009 bool oldInsideUntranslated = insideUntranslatedBreakable; | 1009 bool oldInsideUntranslated = insideUntranslatedBreakable; |
1010 insideUntranslatedBreakable = true; | 1010 insideUntranslatedBreakable = true; |
1011 // Note that node.init, node.condition, node.update all can be null, but | 1011 // Note that node.init, node.condition, node.update all can be null, but |
1012 // withExpressions handles that. | 1012 // withExpressions handles that. |
1013 withExpressions([node.init, node.condition, node.update], | 1013 withExpressions([node.init, node.condition, node.update], |
1014 (List<js.Expression> transformed) { | 1014 (List<js.Expression> transformed) { |
1015 addStatement(new js.For(transformed[0], transformed[1], transformed[2], | 1015 addStatement(new js.For(transformed[0], transformed[1], transformed[2], |
1016 translateInBlock(node.body))); | 1016 translateToStatement(node.body))); |
1017 }); | 1017 }); |
1018 insideUntranslatedBreakable = oldInsideUntranslated; | 1018 insideUntranslatedBreakable = oldInsideUntranslated; |
1019 return; | 1019 return; |
1020 } | 1020 } |
1021 | 1021 |
1022 if (node.init != null) { | 1022 if (node.init != null) { |
1023 visitExpressionIgnoreResult(node.init); | 1023 visitExpressionIgnoreResult(node.init); |
1024 } | 1024 } |
1025 int startLabel = newLabel("for condition"); | 1025 int startLabel = newLabel("for condition"); |
1026 // If there is no update, continuing the loop is the same as going to the | 1026 // If there is no update, continuing the loop is the same as going to the |
(...skipping 30 matching lines...) Expand all Loading... | |
1057 // The dart output currently never uses for-in loops. | 1057 // The dart output currently never uses for-in loops. |
1058 throw "Javascript for-in not implemented yet in the await transformation"; | 1058 throw "Javascript for-in not implemented yet in the await transformation"; |
1059 } | 1059 } |
1060 | 1060 |
1061 @override | 1061 @override |
1062 void visitFunctionDeclaration(js.FunctionDeclaration node) { | 1062 void visitFunctionDeclaration(js.FunctionDeclaration node) { |
1063 unsupported(node); | 1063 unsupported(node); |
1064 } | 1064 } |
1065 | 1065 |
1066 // Only used for code where `!shouldTransform(node)`. | 1066 // Only used for code where `!shouldTransform(node)`. |
1067 js.Block translateInBlock(js.Statement node) { | 1067 js.Block translateToStatement(js.Statement node) { |
sigurdm
2016/04/26 05:15:04
I think the return type should be `js.Statement` n
| |
1068 assert(!shouldTransform(node)); | 1068 assert(!shouldTransform(node)); |
1069 List<js.Statement> oldBuffer = currentStatementBuffer; | 1069 List<js.Statement> oldBuffer = currentStatementBuffer; |
1070 currentStatementBuffer = new List(); | 1070 currentStatementBuffer = new List(); |
1071 List<js.Statement> resultBuffer = currentStatementBuffer; | 1071 List<js.Statement> resultBuffer = currentStatementBuffer; |
1072 visitStatement(node); | 1072 visitStatement(node); |
1073 currentStatementBuffer = oldBuffer; | 1073 currentStatementBuffer = oldBuffer; |
1074 if (resultBuffer.length == 1) | |
1075 return resultBuffer.single; | |
sigurdm
2016/04/26 05:15:04
Either put the return on the same line as the if,
sigurdm
2016/04/26 05:15:05
For the case where `node` is an empty block (can t
| |
1074 return new js.Block(resultBuffer); | 1076 return new js.Block(resultBuffer); |
1075 } | 1077 } |
1076 | 1078 |
1077 @override | 1079 @override |
1078 void visitIf(js.If node) { | 1080 void visitIf(js.If node) { |
1079 if (!shouldTransform(node.then) && !shouldTransform(node.otherwise)) { | 1081 if (!shouldTransform(node.then) && !shouldTransform(node.otherwise)) { |
1080 withExpression(node.condition, (js.Expression condition) { | 1082 withExpression(node.condition, (js.Expression condition) { |
1081 addStatement(new js.If(condition, translateInBlock(node.then), | 1083 js.Ast translatedThen = translateToStatement(node.then); |
1082 translateInBlock(node.otherwise))); | 1084 js.Ast translatedElse = translateToStatement(node.otherwise); |
1085 addStatement(new js.If(condition, translatedThen, translatedElse)); | |
1083 }, store: false); | 1086 }, store: false); |
1084 return; | 1087 return; |
1085 } | 1088 } |
1086 int thenLabel = newLabel("then"); | 1089 int thenLabel = newLabel("then"); |
1087 int joinLabel = newLabel("join"); | 1090 int joinLabel = newLabel("join"); |
1088 int elseLabel = | 1091 int elseLabel = |
1089 (node.otherwise is js.EmptyStatement) ? joinLabel : newLabel("else"); | 1092 (node.otherwise is js.EmptyStatement) ? joinLabel : newLabel("else"); |
1090 | 1093 |
1091 withExpression(node.condition, (js.Expression condition) { | 1094 withExpression(node.condition, (js.Expression condition) { |
1092 addExpressionStatement(new js.Assignment( | 1095 addExpressionStatement(new js.Assignment( |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1130 | 1133 |
1131 @override | 1134 @override |
1132 visitInterpolatedStatement(js.InterpolatedStatement node) { | 1135 visitInterpolatedStatement(js.InterpolatedStatement node) { |
1133 return unsupported(node); | 1136 return unsupported(node); |
1134 } | 1137 } |
1135 | 1138 |
1136 @override | 1139 @override |
1137 void visitLabeledStatement(js.LabeledStatement node) { | 1140 void visitLabeledStatement(js.LabeledStatement node) { |
1138 if (!shouldTransform(node)) { | 1141 if (!shouldTransform(node)) { |
1139 addStatement( | 1142 addStatement( |
1140 new js.LabeledStatement(node.label, translateInBlock(node.body))); | 1143 new js.LabeledStatement(node.label, translateToStatement(node.body))); |
1141 return; | 1144 return; |
1142 } | 1145 } |
1143 // `continue label` is really continuing the nested loop. | 1146 // `continue label` is really continuing the nested loop. |
1144 // This is set up in [PreTranslationAnalysis.visitContinue]. | 1147 // This is set up in [PreTranslationAnalysis.visitContinue]. |
1145 // Here we only need a breakLabel: | 1148 // Here we only need a breakLabel: |
1146 int breakLabel = newLabel("break ${node.label}"); | 1149 int breakLabel = newLabel("break ${node.label}"); |
1147 breakLabels[node] = breakLabel; | 1150 breakLabels[node] = breakLabel; |
1148 | 1151 |
1149 jumpTargets.add(node); | 1152 jumpTargets.add(node); |
1150 visitStatement(node.body); | 1153 visitStatement(node.body); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1295 @override | 1298 @override |
1296 void visitSwitch(js.Switch node) { | 1299 void visitSwitch(js.Switch node) { |
1297 if (!node.cases.any(shouldTransform)) { | 1300 if (!node.cases.any(shouldTransform)) { |
1298 // If only the key has an await, translation can be simplified. | 1301 // If only the key has an await, translation can be simplified. |
1299 bool oldInsideUntranslated = insideUntranslatedBreakable; | 1302 bool oldInsideUntranslated = insideUntranslatedBreakable; |
1300 insideUntranslatedBreakable = true; | 1303 insideUntranslatedBreakable = true; |
1301 withExpression(node.key, (js.Expression key) { | 1304 withExpression(node.key, (js.Expression key) { |
1302 List<js.SwitchClause> cases = node.cases.map((js.SwitchClause clause) { | 1305 List<js.SwitchClause> cases = node.cases.map((js.SwitchClause clause) { |
1303 if (clause is js.Case) { | 1306 if (clause is js.Case) { |
1304 return new js.Case( | 1307 return new js.Case( |
1305 clause.expression, translateInBlock(clause.body)); | 1308 clause.expression, translateToStatement(clause.body)); |
1306 } else if (clause is js.Default) { | 1309 } else if (clause is js.Default) { |
1307 return new js.Default(translateInBlock(clause.body)); | 1310 return new js.Default(translateToStatement(clause.body)); |
1308 } | 1311 } |
1309 }).toList(); | 1312 }).toList(); |
1310 addStatement(new js.Switch(key, cases)); | 1313 addStatement(new js.Switch(key, cases)); |
1311 }, store: false); | 1314 }, store: false); |
1312 insideUntranslatedBreakable = oldInsideUntranslated; | 1315 insideUntranslatedBreakable = oldInsideUntranslated; |
1313 return; | 1316 return; |
1314 } | 1317 } |
1315 int before = newLabel("switch"); | 1318 int before = newLabel("switch"); |
1316 int after = newLabel("after switch"); | 1319 int after = newLabel("after switch"); |
1317 breakLabels[node] = after; | 1320 breakLabels[node] = after; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1419 if (finallyLabel != null) { | 1422 if (finallyLabel != null) { |
1420 result.add(finallyLabel); | 1423 result.add(finallyLabel); |
1421 } | 1424 } |
1422 } | 1425 } |
1423 return result.reversed.toList(); | 1426 return result.reversed.toList(); |
1424 } | 1427 } |
1425 | 1428 |
1426 /// See the comments of [rewriteFunction] for more explanation. | 1429 /// See the comments of [rewriteFunction] for more explanation. |
1427 void visitTry(js.Try node) { | 1430 void visitTry(js.Try node) { |
1428 if (!shouldTransform(node)) { | 1431 if (!shouldTransform(node)) { |
1429 js.Block body = translateInBlock(node.body); | 1432 js.Block body = translateToStatement(node.body); |
sigurdm
2016/04/26 05:15:04
This would also become a `js.Statement`
| |
1430 js.Catch catchPart = (node.catchPart == null) | 1433 js.Catch catchPart = (node.catchPart == null) |
1431 ? null | 1434 ? null |
1432 : new js.Catch(node.catchPart.declaration, | 1435 : new js.Catch(node.catchPart.declaration, |
1433 translateInBlock(node.catchPart.body)); | 1436 translateToStatement(node.catchPart.body)); |
1434 js.Block finallyPart = (node.finallyPart == null) | 1437 js.Block finallyPart = (node.finallyPart == null) |
1435 ? null | 1438 ? null |
1436 : translateInBlock(node.finallyPart); | 1439 : translateToStatement(node.finallyPart); |
1437 addStatement(new js.Try(body, catchPart, finallyPart)); | 1440 addStatement(new js.Try(body, catchPart, finallyPart)); |
1438 return; | 1441 return; |
1439 } | 1442 } |
1440 | 1443 |
1441 hasTryBlocks = true; | 1444 hasTryBlocks = true; |
1442 int uncaughtLabel = newLabel("uncaught"); | 1445 int uncaughtLabel = newLabel("uncaught"); |
1443 int handlerLabel = | 1446 int handlerLabel = |
1444 (node.catchPart == null) ? uncaughtLabel : newLabel("catch"); | 1447 (node.catchPart == null) ? uncaughtLabel : newLabel("catch"); |
1445 | 1448 |
1446 int finallyLabel = newLabel("finally"); | 1449 int finallyLabel = newLabel("finally"); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1569 if (renaming == null) return node; | 1572 if (renaming == null) return node; |
1570 return new js.VariableUse(renaming.b); | 1573 return new js.VariableUse(renaming.b); |
1571 } | 1574 } |
1572 | 1575 |
1573 @override | 1576 @override |
1574 void visitWhile(js.While node) { | 1577 void visitWhile(js.While node) { |
1575 if (!shouldTransform(node)) { | 1578 if (!shouldTransform(node)) { |
1576 bool oldInsideUntranslated = insideUntranslatedBreakable; | 1579 bool oldInsideUntranslated = insideUntranslatedBreakable; |
1577 insideUntranslatedBreakable = true; | 1580 insideUntranslatedBreakable = true; |
1578 withExpression(node.condition, (js.Expression condition) { | 1581 withExpression(node.condition, (js.Expression condition) { |
1579 addStatement(new js.While(condition, translateInBlock(node.body))); | 1582 addStatement(new js.While(condition, translateToStatement(node.body))); |
1580 }, store: false); | 1583 }, store: false); |
1581 insideUntranslatedBreakable = oldInsideUntranslated; | 1584 insideUntranslatedBreakable = oldInsideUntranslated; |
1582 return; | 1585 return; |
1583 } | 1586 } |
1584 int continueLabel = newLabel("while condition"); | 1587 int continueLabel = newLabel("while condition"); |
1585 continueLabels[node] = continueLabel; | 1588 continueLabels[node] = continueLabel; |
1586 beginLabel(continueLabel); | 1589 beginLabel(continueLabel); |
1587 | 1590 |
1588 int afterLabel = newLabel("after while"); | 1591 int afterLabel = newLabel("after while"); |
1589 breakLabels[node] = afterLabel; | 1592 breakLabels[node] = afterLabel; |
(...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2577 return condition || body; | 2580 return condition || body; |
2578 } | 2581 } |
2579 | 2582 |
2580 @override | 2583 @override |
2581 bool visitDartYield(js.DartYield node) { | 2584 bool visitDartYield(js.DartYield node) { |
2582 hasYield = true; | 2585 hasYield = true; |
2583 visit(node.expression); | 2586 visit(node.expression); |
2584 return true; | 2587 return true; |
2585 } | 2588 } |
2586 } | 2589 } |
OLD | NEW |