| 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 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 /// | 110 /// |
| 111 /// It is a parameter to the [body] function, so that [awaitStatement] can | 111 /// It is a parameter to the [body] function, so that [awaitStatement] can |
| 112 /// call [body] with the result of an awaited Future. | 112 /// call [body] with the result of an awaited Future. |
| 113 js.VariableUse get result => new js.VariableUse(resultName); | 113 js.VariableUse get result => new js.VariableUse(resultName); |
| 114 String resultName; | 114 String resultName; |
| 115 | 115 |
| 116 /// A parameter to the [bodyName] function. Indicating if we are in success | 116 /// A parameter to the [bodyName] function. Indicating if we are in success |
| 117 /// or error case. | 117 /// or error case. |
| 118 String errorCodeName; | 118 String errorCodeName; |
| 119 | 119 |
| 120 final String suggestedBodyName; |
| 120 /// The inner function that is scheduled to do each await/yield, | 121 /// The inner function that is scheduled to do each await/yield, |
| 121 /// and called to do a new iteration for sync*. | 122 /// and called to do a new iteration for sync*. |
| 122 js.VariableUse get body => new js.VariableUse(bodyName); | 123 js.VariableUse get body => new js.VariableUse(bodyName); |
| 123 String bodyName; | 124 String bodyName; |
| 124 | 125 |
| 125 /// Used to simulate a goto. | 126 /// Used to simulate a goto. |
| 126 /// | 127 /// |
| 127 /// To "goto" a label, the label is assigned to this variable, and break out | 128 /// To "goto" a label, the label is assigned to this variable, and break out |
| 128 /// of the switch to take another iteration in the while loop. See [addGoto] | 129 /// of the switch to take another iteration in the while loop. See [addGoto] |
| 129 js.VariableUse get goto => new js.VariableUse(gotoName); | 130 js.VariableUse get goto => new js.VariableUse(gotoName); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 // The highest temporary variable index ever in use in this function. | 173 // The highest temporary variable index ever in use in this function. |
| 173 int tempVarHighWaterMark = 0; | 174 int tempVarHighWaterMark = 0; |
| 174 Map<int, js.Expression> tempVarNames = new Map<int, js.Expression>(); | 175 Map<int, js.Expression> tempVarNames = new Map<int, js.Expression>(); |
| 175 | 176 |
| 176 bool get isAsync => false; | 177 bool get isAsync => false; |
| 177 bool get isSyncStar => false; | 178 bool get isSyncStar => false; |
| 178 bool get isAsyncStar => false; | 179 bool get isAsyncStar => false; |
| 179 | 180 |
| 180 AsyncRewriterBase(this.diagnosticListener, | 181 AsyncRewriterBase(this.diagnosticListener, |
| 181 spannable, | 182 spannable, |
| 182 this.safeVariableName) | 183 this.safeVariableName, |
| 184 this.suggestedBodyName) |
| 183 : _spannable = spannable; | 185 : _spannable = spannable; |
| 184 | 186 |
| 185 /// Initialize names used by the subClass. | 187 /// Initialize names used by the subClass. |
| 186 void initializeNames(); | 188 void initializeNames(); |
| 187 | 189 |
| 188 /// Main entry point. | 190 /// Main entry point. |
| 189 /// Rewrites a sync*/async/async* function to an equivalent normal function. | 191 /// Rewrites a sync*/async/async* function to an equivalent normal function. |
| 190 /// | 192 /// |
| 191 /// [spannable] can be passed to have a location for error messages. | 193 /// [spannable] can be passed to have a location for error messages. |
| 192 js.Fun rewrite(js.Fun node, [Spannable spannable]) { | 194 js.Fun rewrite(js.Fun node, [Spannable spannable]) { |
| 193 _spannable = spannable; | 195 _spannable = spannable; |
| 194 | 196 |
| 195 analysis = new PreTranslationAnalysis(unsupported); | 197 analysis = new PreTranslationAnalysis(unsupported); |
| 196 analysis.analyze(node); | 198 analysis.analyze(node); |
| 197 | 199 |
| 198 // To avoid name collisions with existing names, the fresh names are | 200 // To avoid name collisions with existing names, the fresh names are |
| 199 // generated after the analysis. | 201 // generated after the analysis. |
| 200 resultName = freshName("result"); | 202 resultName = freshName("result"); |
| 201 errorCodeName = freshName("errorCode"); | 203 errorCodeName = freshName("errorCode"); |
| 202 bodyName = freshName("body"); | 204 bodyName = freshName(suggestedBodyName); |
| 203 gotoName = freshName("goto"); | 205 gotoName = freshName("goto"); |
| 204 handlerName = freshName("handler"); | 206 handlerName = freshName("handler"); |
| 205 nextName = freshName("next"); | 207 nextName = freshName("next"); |
| 206 returnValueName = freshName("returnValue"); | 208 returnValueName = freshName("returnValue"); |
| 207 currentErrorName = freshName("currentError"); | 209 currentErrorName = freshName("currentError"); |
| 208 outerLabelName = freshName("outer"); | 210 outerLabelName = freshName("outer"); |
| 209 selfName = freshName("self"); | 211 selfName = freshName("self"); |
| 210 // Initialize names specific to the subclass. | 212 // Initialize names specific to the subclass. |
| 211 initializeNames(); | 213 initializeNames(); |
| 212 | 214 |
| (...skipping 1454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1667 /// Contructor used to initialize the [completer] variable. | 1669 /// Contructor used to initialize the [completer] variable. |
| 1668 /// | 1670 /// |
| 1669 /// Specific to async methods. | 1671 /// Specific to async methods. |
| 1670 final js.Expression newCompleter; | 1672 final js.Expression newCompleter; |
| 1671 | 1673 |
| 1672 | 1674 |
| 1673 AsyncRewriter(DiagnosticListener diagnosticListener, | 1675 AsyncRewriter(DiagnosticListener diagnosticListener, |
| 1674 spannable, | 1676 spannable, |
| 1675 {this.asyncHelper, | 1677 {this.asyncHelper, |
| 1676 this.newCompleter, | 1678 this.newCompleter, |
| 1677 safeVariableName}) | 1679 String safeVariableName(String proposedName), |
| 1680 String bodyName}) |
| 1678 : super(diagnosticListener, | 1681 : super(diagnosticListener, |
| 1679 spannable, | 1682 spannable, |
| 1680 safeVariableName); | 1683 safeVariableName, |
| 1684 bodyName); |
| 1681 | 1685 |
| 1682 @override | 1686 @override |
| 1683 void addYield(js.DartYield node, js.Expression expression) { | 1687 void addYield(js.DartYield node, js.Expression expression) { |
| 1684 diagnosticListener.internalError(spannable, | 1688 diagnosticListener.internalError(spannable, |
| 1685 "Yield in non-generating async function"); | 1689 "Yield in non-generating async function"); |
| 1686 } | 1690 } |
| 1687 | 1691 |
| 1688 void addErrorExit() { | 1692 void addErrorExit() { |
| 1689 beginLabel(rethrowLabel); | 1693 beginLabel(rethrowLabel); |
| 1690 addStatement(js.js.statement( | 1694 addStatement(js.js.statement( |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1797 | 1801 |
| 1798 /// Used by sync* functions to throw exeptions. | 1802 /// Used by sync* functions to throw exeptions. |
| 1799 final js.Expression uncaughtErrorExpression; | 1803 final js.Expression uncaughtErrorExpression; |
| 1800 | 1804 |
| 1801 SyncStarRewriter(DiagnosticListener diagnosticListener, | 1805 SyncStarRewriter(DiagnosticListener diagnosticListener, |
| 1802 spannable, | 1806 spannable, |
| 1803 {this.endOfIteration, | 1807 {this.endOfIteration, |
| 1804 this.newIterable, | 1808 this.newIterable, |
| 1805 this.yieldStarExpression, | 1809 this.yieldStarExpression, |
| 1806 this.uncaughtErrorExpression, | 1810 this.uncaughtErrorExpression, |
| 1807 safeVariableName}) | 1811 String safeVariableName(String proposedName), |
| 1812 String bodyName}) |
| 1808 : super(diagnosticListener, | 1813 : super(diagnosticListener, |
| 1809 spannable, | 1814 spannable, |
| 1810 safeVariableName); | 1815 safeVariableName, |
| 1816 bodyName); |
| 1811 | 1817 |
| 1812 /// Translates a yield/yield* in an sync*. | 1818 /// Translates a yield/yield* in an sync*. |
| 1813 /// | 1819 /// |
| 1814 /// `yield` in a sync* function just returns [value]. | 1820 /// `yield` in a sync* function just returns [value]. |
| 1815 /// `yield*` wraps [value] in a [yieldStarExpression] and returns it. | 1821 /// `yield*` wraps [value] in a [yieldStarExpression] and returns it. |
| 1816 @override | 1822 @override |
| 1817 void addYield(js.DartYield node, js.Expression expression) { | 1823 void addYield(js.DartYield node, js.Expression expression) { |
| 1818 if (node.hasStar) { | 1824 if (node.hasStar) { |
| 1819 addStatement( | 1825 addStatement( |
| 1820 new js.Return(new js.Call(yieldStarExpression, [expression]))); | 1826 new js.Return(new js.Call(yieldStarExpression, [expression]))); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1965 /// Called with the stream to yield from. | 1971 /// Called with the stream to yield from. |
| 1966 final js.Expression yieldStarExpression; | 1972 final js.Expression yieldStarExpression; |
| 1967 | 1973 |
| 1968 AsyncStarRewriter(DiagnosticListener diagnosticListener, | 1974 AsyncStarRewriter(DiagnosticListener diagnosticListener, |
| 1969 spannable, | 1975 spannable, |
| 1970 {this.asyncStarHelper, | 1976 {this.asyncStarHelper, |
| 1971 this.streamOfController, | 1977 this.streamOfController, |
| 1972 this.newController, | 1978 this.newController, |
| 1973 this.yieldExpression, | 1979 this.yieldExpression, |
| 1974 this.yieldStarExpression, | 1980 this.yieldStarExpression, |
| 1975 String safeVariableName(String original)}) | 1981 String safeVariableName(String proposedName), |
| 1982 String bodyName}) |
| 1976 : super(diagnosticListener, | 1983 : super(diagnosticListener, |
| 1977 spannable, | 1984 spannable, |
| 1978 safeVariableName); | 1985 safeVariableName, |
| 1986 bodyName); |
| 1979 | 1987 |
| 1980 | 1988 |
| 1981 /// Translates a yield/yield* in an async* function. | 1989 /// Translates a yield/yield* in an async* function. |
| 1982 /// | 1990 /// |
| 1983 /// yield/yield* in an async* function is translated much like the `await` is | 1991 /// yield/yield* in an async* function is translated much like the `await` is |
| 1984 /// translated in [visitAwait], only the object is wrapped in a | 1992 /// translated in [visitAwait], only the object is wrapped in a |
| 1985 /// [yieldExpression]/[yieldStarExpression] to let [asyncStarHelper] | 1993 /// [yieldExpression]/[yieldStarExpression] to let [asyncStarHelper] |
| 1986 /// distinguish them. | 1994 /// distinguish them. |
| 1987 /// Also [nextWhenCanceled] is set up to contain the finally blocks that | 1995 /// Also [nextWhenCanceled] is set up to contain the finally blocks that |
| 1988 /// must be run in case the stream was canceled. | 1996 /// must be run in case the stream was canceled. |
| (...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2534 return condition || body; | 2542 return condition || body; |
| 2535 } | 2543 } |
| 2536 | 2544 |
| 2537 @override | 2545 @override |
| 2538 bool visitDartYield(js.DartYield node) { | 2546 bool visitDartYield(js.DartYield node) { |
| 2539 hasYield = true; | 2547 hasYield = true; |
| 2540 visit(node.expression); | 2548 visit(node.expression); |
| 2541 return true; | 2549 return true; |
| 2542 } | 2550 } |
| 2543 } | 2551 } |
| OLD | NEW |