Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: pkg/compiler/lib/src/js/rewrite_async.dart

Issue 1198293002: dart2js: Use an abstract Name class for names in the generated JavaScript ast. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fix tests Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 /// 108 ///
109 /// It is a parameter to the [body] function, so that [awaitStatement] can 109 /// It is a parameter to the [body] function, so that [awaitStatement] can
110 /// call [body] with the result of an awaited Future. 110 /// call [body] with the result of an awaited Future.
111 js.VariableUse get result => new js.VariableUse(resultName); 111 js.VariableUse get result => new js.VariableUse(resultName);
112 String resultName; 112 String resultName;
113 113
114 /// A parameter to the [bodyName] function. Indicating if we are in success 114 /// A parameter to the [bodyName] function. Indicating if we are in success
115 /// or error case. 115 /// or error case.
116 String errorCodeName; 116 String errorCodeName;
117 117
118 final String suggestedBodyName;
119 /// The inner function that is scheduled to do each await/yield, 118 /// The inner function that is scheduled to do each await/yield,
120 /// and called to do a new iteration for sync*. 119 /// and called to do a new iteration for sync*.
121 js.VariableUse get body => new js.VariableUse(bodyName); 120 js.Name bodyName;
122 String bodyName;
123 121
124 /// Used to simulate a goto. 122 /// Used to simulate a goto.
125 /// 123 ///
126 /// To "goto" a label, the label is assigned to this variable, and break out 124 /// To "goto" a label, the label is assigned to this variable, and break out
127 /// of the switch to take another iteration in the while loop. See [addGoto] 125 /// of the switch to take another iteration in the while loop. See [addGoto]
128 js.VariableUse get goto => new js.VariableUse(gotoName); 126 js.VariableUse get goto => new js.VariableUse(gotoName);
129 String gotoName; 127 String gotoName;
130 128
131 /// Variable containing the label of the current error handler. 129 /// Variable containing the label of the current error handler.
132 js.VariableUse get handler => new js.VariableUse(handlerName); 130 js.VariableUse get handler => new js.VariableUse(handlerName);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 int tempVarHighWaterMark = 0; 170 int tempVarHighWaterMark = 0;
173 Map<int, js.Expression> tempVarNames = new Map<int, js.Expression>(); 171 Map<int, js.Expression> tempVarNames = new Map<int, js.Expression>();
174 172
175 bool get isAsync => false; 173 bool get isAsync => false;
176 bool get isSyncStar => false; 174 bool get isSyncStar => false;
177 bool get isAsyncStar => false; 175 bool get isAsyncStar => false;
178 176
179 AsyncRewriterBase(this.diagnosticListener, 177 AsyncRewriterBase(this.diagnosticListener,
180 spannable, 178 spannable,
181 this.safeVariableName, 179 this.safeVariableName,
182 this.suggestedBodyName) 180 this.bodyName)
183 : _spannable = spannable; 181 : _spannable = spannable;
184 182
185 /// Initialize names used by the subClass. 183 /// Initialize names used by the subClass.
186 void initializeNames(); 184 void initializeNames();
187 185
188 /// Main entry point. 186 /// Main entry point.
189 /// Rewrites a sync*/async/async* function to an equivalent normal function. 187 /// Rewrites a sync*/async/async* function to an equivalent normal function.
190 /// 188 ///
191 /// [spannable] can be passed to have a location for error messages. 189 /// [spannable] can be passed to have a location for error messages.
192 js.Fun rewrite(js.Fun node, [Spannable spannable]) { 190 js.Fun rewrite(js.Fun node, [Spannable spannable]) {
193 _spannable = spannable; 191 _spannable = spannable;
194 192
195 analysis = new PreTranslationAnalysis(unsupported); 193 analysis = new PreTranslationAnalysis(unsupported);
196 analysis.analyze(node); 194 analysis.analyze(node);
197 195
198 // To avoid name collisions with existing names, the fresh names are 196 // To avoid name collisions with existing names, the fresh names are
199 // generated after the analysis. 197 // generated after the analysis.
200 resultName = freshName("result"); 198 resultName = freshName("result");
201 errorCodeName = freshName("errorCode"); 199 errorCodeName = freshName("errorCode");
202 bodyName = freshName(suggestedBodyName);
203 gotoName = freshName("goto"); 200 gotoName = freshName("goto");
204 handlerName = freshName("handler"); 201 handlerName = freshName("handler");
205 nextName = freshName("next"); 202 nextName = freshName("next");
206 returnValueName = freshName("returnValue"); 203 returnValueName = freshName("returnValue");
207 currentErrorName = freshName("currentError"); 204 currentErrorName = freshName("currentError");
208 outerLabelName = freshName("outer"); 205 outerLabelName = freshName("outer");
209 selfName = freshName("self"); 206 selfName = freshName("self");
210 // Initialize names specific to the subclass. 207 // Initialize names specific to the subclass.
211 initializeNames(); 208 initializeNames();
212 209
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 @override 1174 @override
1178 visitLiteralStatement(js.LiteralStatement node) => unsupported(node); 1175 visitLiteralStatement(js.LiteralStatement node) => unsupported(node);
1179 1176
1180 @override 1177 @override
1181 js.Expression visitLiteralString(js.LiteralString node) => node; 1178 js.Expression visitLiteralString(js.LiteralString node) => node;
1182 1179
1183 @override 1180 @override
1184 js.Expression visitStringConcatenation(js.StringConcatenation node) => node; 1181 js.Expression visitStringConcatenation(js.StringConcatenation node) => node;
1185 1182
1186 @override 1183 @override
1184 js.Name visitName(js.Name node) => node;
1185
1186 @override
1187 visitNamedFunction(js.NamedFunction node) { 1187 visitNamedFunction(js.NamedFunction node) {
1188 unsupported(node); 1188 unsupported(node);
1189 } 1189 }
1190 1190
1191 @override 1191 @override
1192 js.Expression visitDeferredExpression(js.DeferredExpression node) => node; 1192 js.Expression visitDeferredExpression(js.DeferredExpression node) => node;
1193 1193
1194 @override 1194 @override
1195 js.Expression visitDeferredNumber(js.DeferredNumber node) => node; 1195 js.Expression visitDeferredNumber(js.DeferredNumber node) => node;
1196 1196
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 /// 1680 ///
1681 /// Specific to async methods. 1681 /// Specific to async methods.
1682 final js.Expression newCompleter; 1682 final js.Expression newCompleter;
1683 1683
1684 1684
1685 AsyncRewriter(DiagnosticListener diagnosticListener, 1685 AsyncRewriter(DiagnosticListener diagnosticListener,
1686 spannable, 1686 spannable,
1687 {this.asyncHelper, 1687 {this.asyncHelper,
1688 this.newCompleter, 1688 this.newCompleter,
1689 String safeVariableName(String proposedName), 1689 String safeVariableName(String proposedName),
1690 String bodyName}) 1690 js.Name bodyName})
1691 : super(diagnosticListener, 1691 : super(diagnosticListener,
1692 spannable, 1692 spannable,
1693 safeVariableName, 1693 safeVariableName,
1694 bodyName); 1694 bodyName);
1695 1695
1696 @override 1696 @override
1697 void addYield(js.DartYield node, js.Expression expression) { 1697 void addYield(js.DartYield node, js.Expression expression) {
1698 diagnosticListener.internalError(spannable, 1698 diagnosticListener.internalError(spannable,
1699 "Yield in non-generating async function"); 1699 "Yield in non-generating async function");
1700 } 1700 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1743 1743
1744 @override 1744 @override
1745 void initializeNames() { 1745 void initializeNames() {
1746 completerName = freshName("completer"); 1746 completerName = freshName("completer");
1747 } 1747 }
1748 1748
1749 @override 1749 @override
1750 js.Statement awaitStatement(js.Expression value) { 1750 js.Statement awaitStatement(js.Expression value) {
1751 return js.js.statement(""" 1751 return js.js.statement("""
1752 return #asyncHelper(#value, 1752 return #asyncHelper(#value,
1753 #body, 1753 #bodyName,
1754 #completer); 1754 #completer);
1755 """, { 1755 """, {
1756 "asyncHelper": asyncHelper, 1756 "asyncHelper": asyncHelper,
1757 "value": value, 1757 "value": value,
1758 "body": body, 1758 "bodyName": bodyName,
1759 "completer": completer}); 1759 "completer": completer});
1760 } 1760 }
1761 1761
1762 @override 1762 @override
1763 js.Fun finishFunction(List<js.Parameter> parameters, 1763 js.Fun finishFunction(List<js.Parameter> parameters,
1764 js.Statement rewrittenBody, 1764 js.Statement rewrittenBody,
1765 js.VariableDeclarationList variableDeclarations) { 1765 js.VariableDeclarationList variableDeclarations) {
1766 return js.js(""" 1766 return js.js("""
1767 function (#parameters) { 1767 function (#parameters) {
1768 #variableDeclarations; 1768 #variableDeclarations;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1812 /// Used by sync* functions to throw exeptions. 1812 /// Used by sync* functions to throw exeptions.
1813 final js.Expression uncaughtErrorExpression; 1813 final js.Expression uncaughtErrorExpression;
1814 1814
1815 SyncStarRewriter(DiagnosticListener diagnosticListener, 1815 SyncStarRewriter(DiagnosticListener diagnosticListener,
1816 spannable, 1816 spannable,
1817 {this.endOfIteration, 1817 {this.endOfIteration,
1818 this.newIterable, 1818 this.newIterable,
1819 this.yieldStarExpression, 1819 this.yieldStarExpression,
1820 this.uncaughtErrorExpression, 1820 this.uncaughtErrorExpression,
1821 String safeVariableName(String proposedName), 1821 String safeVariableName(String proposedName),
1822 String bodyName}) 1822 js.Name bodyName})
1823 : super(diagnosticListener, 1823 : super(diagnosticListener,
1824 spannable, 1824 spannable,
1825 safeVariableName, 1825 safeVariableName,
1826 bodyName); 1826 bodyName);
1827 1827
1828 /// Translates a yield/yield* in an sync*. 1828 /// Translates a yield/yield* in an sync*.
1829 /// 1829 ///
1830 /// `yield` in a sync* function just returns [value]. 1830 /// `yield` in a sync* function just returns [value].
1831 /// `yield*` wraps [value] in a [yieldStarExpression] and returns it. 1831 /// `yield*` wraps [value] in a [yieldStarExpression] and returns it.
1832 @override 1832 @override
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1982 final js.Expression yieldStarExpression; 1982 final js.Expression yieldStarExpression;
1983 1983
1984 AsyncStarRewriter(DiagnosticListener diagnosticListener, 1984 AsyncStarRewriter(DiagnosticListener diagnosticListener,
1985 spannable, 1985 spannable,
1986 {this.asyncStarHelper, 1986 {this.asyncStarHelper,
1987 this.streamOfController, 1987 this.streamOfController,
1988 this.newController, 1988 this.newController,
1989 this.yieldExpression, 1989 this.yieldExpression,
1990 this.yieldStarExpression, 1990 this.yieldStarExpression,
1991 String safeVariableName(String proposedName), 1991 String safeVariableName(String proposedName),
1992 String bodyName}) 1992 js.Name bodyName})
1993 : super(diagnosticListener, 1993 : super(diagnosticListener,
1994 spannable, 1994 spannable,
1995 safeVariableName, 1995 safeVariableName,
1996 bodyName); 1996 bodyName);
1997 1997
1998 1998
1999 /// Translates a yield/yield* in an async* function. 1999 /// Translates a yield/yield* in an async* function.
2000 /// 2000 ///
2001 /// yield/yield* in an async* function is translated much like the `await` is 2001 /// yield/yield* in an async* function is translated much like the `await` is
2002 /// translated in [visitAwait], only the object is wrapped in a 2002 /// translated in [visitAwait], only the object is wrapped in a
2003 /// [yieldExpression]/[yieldStarExpression] to let [asyncStarHelper] 2003 /// [yieldExpression]/[yieldStarExpression] to let [asyncStarHelper]
2004 /// distinguish them. 2004 /// distinguish them.
2005 /// Also [nextWhenCanceled] is set up to contain the finally blocks that 2005 /// Also [nextWhenCanceled] is set up to contain the finally blocks that
2006 /// must be run in case the stream was canceled. 2006 /// must be run in case the stream was canceled.
2007 @override 2007 @override
2008 void addYield(js.DartYield node, js.Expression expression) { 2008 void addYield(js.DartYield node, js.Expression expression) {
2009 // Find all the finally blocks that should be performed if the stream is 2009 // Find all the finally blocks that should be performed if the stream is
2010 // canceled during the yield. 2010 // canceled during the yield.
2011 // At the bottom of the stack is the return label. 2011 // At the bottom of the stack is the return label.
2012 List<int> enclosingFinallyLabels = <int>[exitLabel]; 2012 List<int> enclosingFinallyLabels = <int>[exitLabel];
2013 enclosingFinallyLabels.addAll(jumpTargets 2013 enclosingFinallyLabels.addAll(jumpTargets
2014 .where((js.Node node) => finallyLabels[node] != null) 2014 .where((js.Node node) => finallyLabels[node] != null)
2015 .map((js.Block node) => finallyLabels[node])); 2015 .map((js.Block node) => finallyLabels[node]));
2016 addStatement(js.js.statement("# = #;", 2016 addStatement(js.js.statement("# = #;",
2017 [nextWhenCanceled, new js.ArrayInitializer( 2017 [nextWhenCanceled, new js.ArrayInitializer(
2018 enclosingFinallyLabels.map(js.number).toList())])); 2018 enclosingFinallyLabels.map(js.number).toList())]));
2019 addStatement(js.js.statement(""" 2019 addStatement(js.js.statement("""
2020 return #asyncStarHelper(#yieldExpression(#expression), #body, 2020 return #asyncStarHelper(#yieldExpression(#expression), #bodyName,
2021 #controller);""", { 2021 #controller);""", {
2022 "asyncStarHelper": asyncStarHelper, 2022 "asyncStarHelper": asyncStarHelper,
2023 "yieldExpression": node.hasStar ? yieldStarExpression : yieldExpression, 2023 "yieldExpression": node.hasStar ? yieldStarExpression : yieldExpression,
2024 "expression": expression, 2024 "expression": expression,
2025 "body": body, 2025 "bodyName": bodyName,
2026 "controller": controllerName, 2026 "controller": controllerName,
2027 })); 2027 }));
2028 } 2028 }
2029 2029
2030 @override 2030 @override
2031 js.Fun finishFunction(List<js.Parameter> parameters, 2031 js.Fun finishFunction(List<js.Parameter> parameters,
2032 js.Statement rewrittenBody, 2032 js.Statement rewrittenBody,
2033 js.VariableDeclarationList variableDeclarations) { 2033 js.VariableDeclarationList variableDeclarations) {
2034 return js.js(""" 2034 return js.js("""
2035 function (#parameters) { 2035 function (#parameters) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
2113 @override 2113 @override
2114 void initializeNames() { 2114 void initializeNames() {
2115 controllerName = freshName("controller"); 2115 controllerName = freshName("controller");
2116 nextWhenCanceledName = freshName("nextWhenCanceled"); 2116 nextWhenCanceledName = freshName("nextWhenCanceled");
2117 } 2117 }
2118 2118
2119 @override 2119 @override
2120 js.Statement awaitStatement(js.Expression value) { 2120 js.Statement awaitStatement(js.Expression value) {
2121 return js.js.statement(""" 2121 return js.js.statement("""
2122 return #asyncHelper(#value, 2122 return #asyncHelper(#value,
2123 #body, 2123 #bodyName,
2124 #controller); 2124 #controller);
2125 """, { 2125 """, {
2126 "asyncHelper": asyncStarHelper, 2126 "asyncHelper": asyncStarHelper,
2127 "value": value, 2127 "value": value,
2128 "body": body, 2128 "bodyName": bodyName,
2129 "controller": controllerName}); 2129 "controller": controllerName});
2130 } 2130 }
2131 } 2131 }
2132 2132
2133 /// Finds out 2133 /// Finds out
2134 /// 2134 ///
2135 /// - which expressions have yield or await nested in them. 2135 /// - which expressions have yield or await nested in them.
2136 /// - targets of jumps 2136 /// - targets of jumps
2137 /// - a set of used names. 2137 /// - a set of used names.
2138 /// - if any [This]-expressions are used. 2138 /// - if any [This]-expressions are used.
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
2438 bool visitLiteralString(js.LiteralString node) { 2438 bool visitLiteralString(js.LiteralString node) {
2439 return false; 2439 return false;
2440 } 2440 }
2441 2441
2442 @override 2442 @override
2443 bool visitStringConcatenation(js.StringConcatenation node) { 2443 bool visitStringConcatenation(js.StringConcatenation node) {
2444 return true; 2444 return true;
2445 } 2445 }
2446 2446
2447 @override 2447 @override
2448 bool visitName(js.Name node) {
2449 return true;
2450 }
2451
2452 @override
2448 bool visitNamedFunction(js.NamedFunction node) { 2453 bool visitNamedFunction(js.NamedFunction node) {
2449 return false; 2454 return false;
2450 } 2455 }
2451 2456
2452 @override 2457 @override
2453 bool visitNew(js.New node) { 2458 bool visitNew(js.New node) {
2454 return visitCall(node); 2459 return visitCall(node);
2455 } 2460 }
2456 2461
2457 @override 2462 @override
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
2572 return condition || body; 2577 return condition || body;
2573 } 2578 }
2574 2579
2575 @override 2580 @override
2576 bool visitDartYield(js.DartYield node) { 2581 bool visitDartYield(js.DartYield node) {
2577 hasYield = true; 2582 hasYield = true;
2578 visit(node.expression); 2583 visit(node.expression);
2579 return true; 2584 return true;
2580 } 2585 }
2581 } 2586 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698