| 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 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 /// The order is important, therefore the type is explicitly LinkedHashMap. | 353 /// The order is important, therefore the type is explicitly LinkedHashMap. |
| 354 LinkedHashMap<int, List<js.Statement>> labelledParts = | 354 LinkedHashMap<int, List<js.Statement>> labelledParts = |
| 355 new LinkedHashMap<int, List<js.Statement>>(); | 355 new LinkedHashMap<int, List<js.Statement>>(); |
| 356 | 356 |
| 357 /// Description of each label for readability of the non-minified output. | 357 /// Description of each label for readability of the non-minified output. |
| 358 Map<int, String> labelComments = new Map<int, String>(); | 358 Map<int, String> labelComments = new Map<int, String>(); |
| 359 | 359 |
| 360 /// True if the function has any try blocks containing await. | 360 /// True if the function has any try blocks containing await. |
| 361 bool hasTryBlocks = false; | 361 bool hasTryBlocks = false; |
| 362 | 362 |
| 363 /// True if any return, break or continue passes through a finally. | |
| 364 bool hasJumpThroughFinally = false; | |
| 365 | |
| 366 /// True if the traversion currently is inside a loop or switch for which | 363 /// True if the traversion currently is inside a loop or switch for which |
| 367 /// [shouldTransform] is false. | 364 /// [shouldTransform] is false. |
| 368 bool insideUntranslatedBreakable = false; | 365 bool insideUntranslatedBreakable = false; |
| 369 | 366 |
| 370 /// True if a label is used to break to an outer switch-statement. | 367 /// True if a label is used to break to an outer switch-statement. |
| 371 bool hasJumpThoughOuterLabel = false; | 368 bool hasJumpThoughOuterLabel = false; |
| 372 | 369 |
| 373 /// True if there is a catch-handler protected by a finally with no enclosing | 370 /// True if there is a catch-handler protected by a finally with no enclosing |
| 374 /// catch-handlers. | 371 /// catch-handlers. |
| 375 bool needsRethrow = false; | 372 bool needsRethrow = false; |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 838 | 835 |
| 839 inits.add(makeInit(gotoName, js.number(0))); | 836 inits.add(makeInit(gotoName, js.number(0))); |
| 840 if (isAsync) { | 837 if (isAsync) { |
| 841 inits.add(makeInit(completerName, new js.New(newCompleter, []))); | 838 inits.add(makeInit(completerName, new js.New(newCompleter, []))); |
| 842 } else if (isAsyncStar) { | 839 } else if (isAsyncStar) { |
| 843 inits.add(makeInit(controllerName, | 840 inits.add(makeInit(controllerName, |
| 844 new js.Call(newController, [new js.VariableUse(bodyName)]))); | 841 new js.Call(newController, [new js.VariableUse(bodyName)]))); |
| 845 } | 842 } |
| 846 inits.add(makeInit(handlerName, js.number(rethrowLabel))); | 843 inits.add(makeInit(handlerName, js.number(rethrowLabel))); |
| 847 inits.add(makeInit(currentErrorName, null)); | 844 inits.add(makeInit(currentErrorName, null)); |
| 848 if (hasJumpThroughFinally || analysis.hasYield) { | 845 if (analysis.hasFinally || (isAsyncStar && analysis.hasYield)) { |
| 849 inits.add(makeInit(nextName, null)); | 846 inits.add(makeInit(nextName, null)); |
| 850 } | 847 } |
| 851 if (isAsyncStar && analysis.hasYield) { | 848 if (isAsyncStar && analysis.hasYield) { |
| 852 inits.add(makeInit(nextWhenCanceledName, null)); | 849 inits.add(makeInit(nextWhenCanceledName, null)); |
| 853 } | 850 } |
| 854 if (analysis.hasExplicitReturns && isAsync) { | 851 if (analysis.hasExplicitReturns && isAsync) { |
| 855 inits.add(makeInit(returnValueName, null)); | 852 inits.add(makeInit(returnValueName, null)); |
| 856 } | 853 } |
| 857 if (analysis.hasThis && !isSyncStar) { | 854 if (analysis.hasThis && !isSyncStar) { |
| 858 // Sync* functions must remember `this` on the level of the outer | 855 // Sync* functions must remember `this` on the level of the outer |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1169 jumpStack.add(targetLabel); | 1166 jumpStack.add(targetLabel); |
| 1170 break; | 1167 break; |
| 1171 } | 1168 } |
| 1172 // Ignore other nodes. | 1169 // Ignore other nodes. |
| 1173 } | 1170 } |
| 1174 jumpStack = jumpStack.reversed.toList(); | 1171 jumpStack = jumpStack.reversed.toList(); |
| 1175 // As the program jumps directly to the top of the stack, it is taken off | 1172 // As the program jumps directly to the top of the stack, it is taken off |
| 1176 // now. | 1173 // now. |
| 1177 int firstTarget = jumpStack.removeLast(); | 1174 int firstTarget = jumpStack.removeLast(); |
| 1178 if (jumpStack.isNotEmpty) { | 1175 if (jumpStack.isNotEmpty) { |
| 1179 hasJumpThroughFinally = true; | |
| 1180 js.Expression jsJumpStack = new js.ArrayInitializer( | 1176 js.Expression jsJumpStack = new js.ArrayInitializer( |
| 1181 jumpStack.map((int label) => js.number(label)).toList()); | 1177 jumpStack.map((int label) => js.number(label)).toList()); |
| 1182 addStatement(js.js.statement("# = #", [nextName, jsJumpStack])); | 1178 addStatement(js.js.statement("# = #", [nextName, jsJumpStack])); |
| 1183 } | 1179 } |
| 1184 addGoto(firstTarget); | 1180 addGoto(firstTarget); |
| 1185 } | 1181 } |
| 1186 | 1182 |
| 1187 @override | 1183 @override |
| 1188 void visitDefault(js.Default node) => unreachable(node); | 1184 void visitDefault(js.Default node) => unreachable(node); |
| 1189 | 1185 |
| (...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1898 List<js.LabeledStatement> labelledStatements = | 1894 List<js.LabeledStatement> labelledStatements = |
| 1899 new List<js.LabeledStatement>(); | 1895 new List<js.LabeledStatement>(); |
| 1900 Set<String> usedNames = new Set<String>(); | 1896 Set<String> usedNames = new Set<String>(); |
| 1901 | 1897 |
| 1902 bool hasExplicitReturns = false; | 1898 bool hasExplicitReturns = false; |
| 1903 | 1899 |
| 1904 bool hasThis = false; | 1900 bool hasThis = false; |
| 1905 | 1901 |
| 1906 bool hasYield = false; | 1902 bool hasYield = false; |
| 1907 | 1903 |
| 1904 bool hasFinally = false; |
| 1905 |
| 1908 // The function currently being analyzed. | 1906 // The function currently being analyzed. |
| 1909 js.Fun currentFunction; | 1907 js.Fun currentFunction; |
| 1910 | 1908 |
| 1911 // For error messages. | 1909 // For error messages. |
| 1912 final Function unsupported; | 1910 final Function unsupported; |
| 1913 | 1911 |
| 1914 PreTranslationAnalysis(void this.unsupported(js.Node node)); | 1912 PreTranslationAnalysis(void this.unsupported(js.Node node)); |
| 1915 | 1913 |
| 1916 bool visit(js.Node node) { | 1914 bool visit(js.Node node) { |
| 1917 bool containsAwait = node.accept(this); | 1915 bool containsAwait = node.accept(this); |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2253 bool visitThrow(js.Throw node) { | 2251 bool visitThrow(js.Throw node) { |
| 2254 return visit(node.expression); | 2252 return visit(node.expression); |
| 2255 } | 2253 } |
| 2256 | 2254 |
| 2257 @override | 2255 @override |
| 2258 bool visitTry(js.Try node) { | 2256 bool visitTry(js.Try node) { |
| 2259 bool body = visit(node.body); | 2257 bool body = visit(node.body); |
| 2260 bool catchPart = (node.catchPart == null) ? false : visit(node.catchPart); | 2258 bool catchPart = (node.catchPart == null) ? false : visit(node.catchPart); |
| 2261 bool finallyPart = | 2259 bool finallyPart = |
| 2262 (node.finallyPart == null) ? false : visit(node.finallyPart); | 2260 (node.finallyPart == null) ? false : visit(node.finallyPart); |
| 2261 if (finallyPart != null) hasFinally = true; |
| 2263 return body || catchPart || finallyPart; | 2262 return body || catchPart || finallyPart; |
| 2264 } | 2263 } |
| 2265 | 2264 |
| 2266 @override | 2265 @override |
| 2267 bool visitVariableDeclaration(js.VariableDeclaration node) { | 2266 bool visitVariableDeclaration(js.VariableDeclaration node) { |
| 2268 usedNames.add(node.name); | 2267 usedNames.add(node.name); |
| 2269 return false; | 2268 return false; |
| 2270 } | 2269 } |
| 2271 | 2270 |
| 2272 @override | 2271 @override |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2298 return condition || body; | 2297 return condition || body; |
| 2299 } | 2298 } |
| 2300 | 2299 |
| 2301 @override | 2300 @override |
| 2302 bool visitDartYield(js.DartYield node) { | 2301 bool visitDartYield(js.DartYield node) { |
| 2303 hasYield = true; | 2302 hasYield = true; |
| 2304 visit(node.expression); | 2303 visit(node.expression); |
| 2305 return true; | 2304 return true; |
| 2306 } | 2305 } |
| 2307 } | 2306 } |
| OLD | NEW |