Index: pkg/compiler/lib/src/js/rewrite_async.dart |
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart |
index 970cc1cd65b8e431089d1d216b8aaeae54dfd506..2a9d8bff3080d0e70493a338fd830305793f5e34 100644 |
--- a/pkg/compiler/lib/src/js/rewrite_async.dart |
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart |
@@ -7,14 +7,12 @@ library rewrite_async; |
import "dart:math" show max; |
import 'dart:collection'; |
-import 'package:js_runtime/shared/async_await_error_codes.dart' |
- as error_codes; |
+import 'package:js_runtime/shared/async_await_error_codes.dart' as error_codes; |
import "js.dart" as js; |
import '../common.dart'; |
-import '../util/util.dart' show |
- Pair; |
+import '../util/util.dart' show Pair; |
/// Rewrites a [js.Fun] with async/sync*/async* functions and await and yield |
/// (with dart-like semantics) to an equivalent function without these. |
@@ -28,7 +26,6 @@ import '../util/util.dart' show |
/// Look at [rewriteFunction], [visitDartYield] and [visitAwait] for more |
/// explanation. |
abstract class AsyncRewriterBase extends js.NodeVisitor { |
- |
// Local variables are hoisted to the top of the function, so they are |
// collected here. |
List<js.VariableDeclaration> localVariables = |
@@ -176,10 +173,8 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
bool get isSyncStar => false; |
bool get isAsyncStar => false; |
- AsyncRewriterBase(this.reporter, |
- this._spannable, |
- this.safeVariableName, |
- this.bodyName); |
+ AsyncRewriterBase( |
+ this.reporter, this._spannable, this.safeVariableName, this.bodyName); |
/// Initialize names used by the subClass. |
void initializeNames(); |
@@ -212,8 +207,8 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
} |
js.Expression get currentErrorHandler { |
- return js.number(handlerLabels[jumpTargets.lastWhere( |
- (node) => handlerLabels[node] != null)]); |
+ return js.number(handlerLabels[ |
+ jumpTargets.lastWhere((node) => handlerLabels[node] != null)]); |
} |
int allocateTempVar() { |
@@ -349,8 +344,7 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
} |
void unreachable(js.Node node) { |
- reporter.internalError( |
- spannable, "Internal error, trying to visit $node"); |
+ reporter.internalError(spannable, "Internal error, trying to visit $node"); |
} |
visitStatement(js.Statement node) { |
@@ -373,7 +367,6 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
return node.accept(this); |
} |
- |
/// Calls [fn] with the value of evaluating [node1] and [node2]. |
/// |
/// Both nodes are evaluated in order. |
@@ -429,8 +422,8 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
/// evaluation order we can write: |
/// temp = <receiver>; |
/// temp.m(); |
- withCallTargetExpression(js.Expression node, |
- fn(js.Expression result), {bool store}) { |
+ withCallTargetExpression(js.Expression node, fn(js.Expression result), |
+ {bool store}) { |
int oldTempVarIndex = currentTempVarIndex; |
js.Expression visited = visitExpression(node); |
js.Expression selector; |
@@ -455,7 +448,6 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
return result; |
} |
- |
/// Calls [fn] with the value of evaluating [node1] and [node2]. |
/// |
/// If `shouldTransform(node2)` the first expression is stored in a temporary |
@@ -525,9 +517,10 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
} |
/// Returns the rewritten function. |
- js.Fun finishFunction(List<js.Parameter> parameters, |
- js.Statement rewrittenBody, |
- js.VariableDeclarationList variableDeclarations); |
+ js.Fun finishFunction( |
+ List<js.Parameter> parameters, |
+ js.Statement rewrittenBody, |
+ js.VariableDeclarationList variableDeclarations); |
Iterable<js.VariableInitialization> variableInitializations(); |
@@ -684,8 +677,7 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
List<js.SwitchClause> clauses = labelledParts.keys.map((label) { |
return new js.Case(js.number(label), new js.Block(labelledParts[label])); |
}).toList(); |
- js.Statement rewrittenBody = |
- new js.Switch(goto, clauses); |
+ js.Statement rewrittenBody = new js.Switch(goto, clauses); |
if (hasJumpThoughOuterLabel) { |
rewrittenBody = new js.LabeledStatement(outerLabelName, rewrittenBody); |
} |
@@ -695,20 +687,18 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
variables.add(_makeVariableInitializer(goto, js.number(0))); |
variables.addAll(variableInitializations()); |
- variables.add( |
- _makeVariableInitializer(handler, js.number(rethrowLabel))); |
+ variables.add(_makeVariableInitializer(handler, js.number(rethrowLabel))); |
variables.add(_makeVariableInitializer(currentError, null)); |
if (analysis.hasFinally || (isAsyncStar && analysis.hasYield)) { |
- variables.add(_makeVariableInitializer(next, |
- new js.ArrayInitializer(<js.Expression>[]))); |
+ variables.add(_makeVariableInitializer( |
+ next, new js.ArrayInitializer(<js.Expression>[]))); |
} |
if (analysis.hasThis && !isSyncStar) { |
// Sync* functions must remember `this` on the level of the outer |
// function. |
variables.add(_makeVariableInitializer(self, js.js('this'))); |
} |
- variables.addAll(localVariables.map( |
- (js.VariableDeclaration declaration) { |
+ variables.addAll(localVariables.map((js.VariableDeclaration declaration) { |
return new js.VariableInitialization(declaration, null); |
})); |
variables.addAll(new Iterable.generate(tempVarHighWaterMark, |
@@ -725,8 +715,8 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
// The translation does not handle nested functions that are generators |
// or asynchronous. These functions should only be ones that are |
// introduced by JS foreign code from our own libraries. |
- reporter.internalError(spannable, |
- 'Nested function is a generator or asynchronous.'); |
+ reporter.internalError( |
+ spannable, 'Nested function is a generator or asynchronous.'); |
} |
return node; |
} |
@@ -761,18 +751,16 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
// A non-compound [js.Assignment] has `op==null`. So it works out to |
// use [js.Assignment.compound] for all cases. |
// Visit the [js.VariableUse] to ensure renaming is done correctly. |
- return new js.Assignment.compound(visitExpression(leftHandSide), |
- node.op, |
- value); |
+ return new js.Assignment.compound( |
+ visitExpression(leftHandSide), node.op, value); |
}, store: false); |
} else if (leftHandSide is js.PropertyAccess) { |
- return withExpressions([ |
- leftHandSide.receiver, |
- leftHandSide.selector, |
- node.value |
- ], (evaluated) { |
+ return withExpressions( |
+ [leftHandSide.receiver, leftHandSide.selector, node.value], |
+ (evaluated) { |
return new js.Assignment.compound( |
- new js.PropertyAccess(evaluated[0], evaluated[1]), node.op, |
+ new js.PropertyAccess(evaluated[0], evaluated[1]), |
+ node.op, |
evaluated[2]); |
}); |
} else { |
@@ -887,9 +875,11 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
@override |
js.Expression visitConditional(js.Conditional node) { |
if (!shouldTransform(node.then) && !shouldTransform(node.otherwise)) { |
- return js.js('# ? # : #', [visitExpression(node.condition), |
- visitExpression(node.then), |
- visitExpression(node.otherwise)]); |
+ return js.js('# ? # : #', [ |
+ visitExpression(node.condition), |
+ visitExpression(node.then), |
+ visitExpression(node.otherwise) |
+ ]); |
} |
int thenLabel = newLabel("then"); |
int joinLabel = newLabel("join"); |
@@ -977,8 +967,7 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
bool oldInsideUntranslatedBreakable = insideUntranslatedBreakable; |
insideUntranslatedBreakable = true; |
addStatement(js.js.statement('do {#} while (#)', |
- [translateInBlock(node.body), |
- visitExpression(node.condition)])); |
+ [translateInBlock(node.body), visitExpression(node.condition)])); |
insideUntranslatedBreakable = oldInsideUntranslatedBreakable; |
return; |
} |
@@ -998,8 +987,8 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
beginLabel(continueLabel); |
withExpression(node.condition, (js.Expression condition) { |
- addStatement(js.js.statement('if (#) #', |
- [condition, gotoAndBreak(startLabel)])); |
+ addStatement( |
+ js.js.statement('if (#) #', [condition, gotoAndBreak(startLabel)])); |
}, store: false); |
beginLabel(afterLabel); |
} |
@@ -1009,7 +998,6 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
addStatement(node); |
} |
- |
@override |
void visitExpressionStatement(js.ExpressionStatement node) { |
visitExpressionIgnoreResult(node.expression); |
@@ -1022,13 +1010,10 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
insideUntranslatedBreakable = true; |
// Note that node.init, node.condition, node.update all can be null, but |
// withExpressions handles that. |
- withExpressions([ |
- node.init, |
- node.condition, |
- node.update |
- ], (List<js.Expression> transformed) { |
+ withExpressions([node.init, node.condition, node.update], |
+ (List<js.Expression> transformed) { |
addStatement(new js.For(transformed[0], transformed[1], transformed[2], |
- translateInBlock(node.body))); |
+ translateInBlock(node.body))); |
}); |
insideUntranslatedBreakable = oldInsideUntranslated; |
return; |
@@ -1100,18 +1085,14 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
} |
int thenLabel = newLabel("then"); |
int joinLabel = newLabel("join"); |
- int elseLabel = (node.otherwise is js.EmptyStatement) |
- ? joinLabel |
- : newLabel("else"); |
+ int elseLabel = |
+ (node.otherwise is js.EmptyStatement) ? joinLabel : newLabel("else"); |
withExpression(node.condition, (js.Expression condition) { |
- addExpressionStatement( |
- new js.Assignment( |
- goto, |
- new js.Conditional( |
- condition, |
- js.number(thenLabel), |
- js.number(elseLabel)))); |
+ addExpressionStatement(new js.Assignment( |
+ goto, |
+ new js.Conditional( |
+ condition, js.number(thenLabel), js.number(elseLabel)))); |
}, store: false); |
addBreak(); |
beginLabel(thenLabel); |
@@ -1295,7 +1276,7 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
void visitReturn(js.Return node) { |
js.Node target = analysis.targets[node]; |
if (node.value != null) { |
- if(isSyncStar || isAsyncStar) { |
+ if (isSyncStar || isAsyncStar) { |
// Even though `return expr;` is not allowed in the dart sync* and |
// async* code, the backend sometimes generates code like this, but |
// only when it is known that the 'expr' throws, and the return is just |
@@ -1377,15 +1358,14 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
for (js.SwitchClause clause in node.cases) { |
if (clause is js.Case) { |
labels[i] = newLabel("case"); |
- clauses.add(new js.Case(visitExpression(clause.expression), |
- gotoAndBreak(labels[i]))); |
+ clauses.add(new js.Case( |
+ visitExpression(clause.expression), gotoAndBreak(labels[i]))); |
} else if (clause is js.Default) { |
labels[i] = newLabel("default"); |
clauses.add(new js.Default(gotoAndBreak(labels[i]))); |
hasDefault = true; |
} else { |
- reporter.internalError( |
- spannable, "Unknown clause type $clause"); |
+ reporter.internalError(spannable, "Unknown clause type $clause"); |
} |
i++; |
} |
@@ -1421,10 +1401,9 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
} |
setErrorHandler([int errorHandler]) { |
- js.Expression label = (errorHandler == null) |
- ? currentErrorHandler |
- : js.number(errorHandler); |
- addStatement(js.js.statement('# = #;',[handler, label])); |
+ js.Expression label = |
+ (errorHandler == null) ? currentErrorHandler : js.number(errorHandler); |
+ addStatement(js.js.statement('# = #;', [handler, label])); |
} |
List<int> _finalliesUpToAndEnclosingHandler() { |
@@ -1461,9 +1440,8 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
hasTryBlocks = true; |
int uncaughtLabel = newLabel("uncaught"); |
- int handlerLabel = (node.catchPart == null) |
- ? uncaughtLabel |
- : newLabel("catch"); |
+ int handlerLabel = |
+ (node.catchPart == null) ? uncaughtLabel : newLabel("catch"); |
int finallyLabel = newLabel("finally"); |
int afterFinallyLabel = newLabel("after finally"); |
@@ -1514,9 +1492,8 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
if (node.finallyPart != null) { |
// The error has been caught, so after the finally, continue after the |
// try. |
- addStatement( |
- js.js.statement("#.push(#);", |
- [next, js.number(afterFinallyLabel)])); |
+ addStatement(js.js |
+ .statement("#.push(#);", [next, js.number(afterFinallyLabel)])); |
addGoto(finallyLabel); |
} else { |
addGoto(afterFinallyLabel); |
@@ -1535,9 +1512,10 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
if (enclosingFinallies.isNotEmpty) { |
// [enclosingFinallies] can be empty if there is no surrounding finally |
// blocks. Then [nextLabel] will be [rethrowLabel]. |
- addStatement( |
- js.js.statement("# = #;", [next, new js.ArrayInitializer( |
- enclosingFinallies.map(js.number).toList())])); |
+ addStatement(js.js.statement("# = #;", [ |
+ next, |
+ new js.ArrayInitializer(enclosingFinallies.map(js.number).toList()) |
+ ])); |
} |
if (node.finallyPart == null) { |
// The finally-block belonging to [node] will be visited because of |
@@ -1586,7 +1564,8 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
@override |
js.Expression visitVariableUse(js.VariableUse node) { |
Pair<String, String> renaming = variableRenamings.lastWhere( |
- (Pair renaming) => renaming.a == node.name, orElse: () => null); |
+ (Pair renaming) => renaming.a == node.name, |
+ orElse: () => null); |
if (renaming == null) return node; |
return new js.VariableUse(renaming.b); |
} |
@@ -1639,8 +1618,8 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
} |
} |
-js.VariableInitialization |
- _makeVariableInitializer(dynamic variable, js.Expression initValue) { |
+js.VariableInitialization _makeVariableInitializer( |
+ dynamic variable, js.Expression initValue) { |
js.VariableDeclaration declaration; |
if (variable is js.VariableUse) { |
declaration = new js.VariableDeclaration(variable.name); |
@@ -1654,7 +1633,6 @@ js.VariableInitialization |
} |
class AsyncRewriter extends AsyncRewriterBase { |
- |
bool get isAsync => true; |
/// The Completer that will finish an async function. |
@@ -1691,32 +1669,28 @@ class AsyncRewriter extends AsyncRewriterBase { |
final js.Expression wrapBody; |
- AsyncRewriter(DiagnosticReporter reporter, |
- Spannable spannable, |
- {this.asyncHelper, |
- this.newCompleter, |
- this.wrapBody, |
- String safeVariableName(String proposedName), |
- js.Name bodyName}) |
- : super(reporter, |
- spannable, |
- safeVariableName, |
- bodyName); |
+ AsyncRewriter(DiagnosticReporter reporter, Spannable spannable, |
+ {this.asyncHelper, |
+ this.newCompleter, |
+ this.wrapBody, |
+ String safeVariableName(String proposedName), |
+ js.Name bodyName}) |
+ : super(reporter, spannable, safeVariableName, bodyName); |
@override |
void addYield(js.DartYield node, js.Expression expression) { |
- reporter.internalError(spannable, |
- "Yield in non-generating async function"); |
+ reporter.internalError(spannable, "Yield in non-generating async function"); |
} |
void addErrorExit() { |
beginLabel(rethrowLabel); |
addStatement(js.js.statement( |
"return #thenHelper(#currentError, #errorCode, #completer);", { |
- "thenHelper": asyncHelper, |
- "errorCode": js.number(error_codes.ERROR), |
- "currentError": currentError, |
- "completer": completer})); |
+ "thenHelper": asyncHelper, |
+ "errorCode": js.number(error_codes.ERROR), |
+ "currentError": currentError, |
+ "completer": completer |
+ })); |
} |
/// Returning from an async method calls [asyncStarHelper] with the result. |
@@ -1730,21 +1704,22 @@ class AsyncRewriter extends AsyncRewriterBase { |
} |
addStatement(js.js.statement( |
"return #runtimeHelper(#returnValue, #successCode, " |
- "#completer, null);", { |
- "runtimeHelper": asyncHelper, |
- "successCode": js.number(error_codes.SUCCESS), |
- "returnValue": analysis.hasExplicitReturns |
- ? returnValue |
- : new js.LiteralNull(), |
- "completer": completer})); |
+ "#completer, null);", |
+ { |
+ "runtimeHelper": asyncHelper, |
+ "successCode": js.number(error_codes.SUCCESS), |
+ "returnValue": |
+ analysis.hasExplicitReturns ? returnValue : new js.LiteralNull(), |
+ "completer": completer |
+ })); |
} |
@override |
Iterable<js.VariableInitialization> variableInitializations() { |
List<js.VariableInitialization> variables = |
new List<js.VariableInitialization>(); |
- variables.add(_makeVariableInitializer(completer, |
- new js.New(newCompleter, []))); |
+ variables |
+ .add(_makeVariableInitializer(completer, new js.New(newCompleter, []))); |
if (analysis.hasExplicitReturns) { |
variables.add(_makeVariableInitializer(returnValue, null)); |
} |
@@ -1758,22 +1733,27 @@ class AsyncRewriter extends AsyncRewriterBase { |
@override |
js.Statement awaitStatement(js.Expression value) { |
- return js.js.statement(""" |
+ return js.js.statement( |
+ """ |
return #asyncHelper(#value, |
#bodyName, |
#completer); |
- """, { |
- "asyncHelper": asyncHelper, |
- "value": value, |
- "bodyName": bodyName, |
- "completer": completer}); |
+ """, |
+ { |
+ "asyncHelper": asyncHelper, |
+ "value": value, |
+ "bodyName": bodyName, |
+ "completer": completer |
+ }); |
} |
@override |
- js.Fun finishFunction(List<js.Parameter> parameters, |
- js.Statement rewrittenBody, |
- js.VariableDeclarationList variableDeclarations) { |
- return js.js(""" |
+ js.Fun finishFunction( |
+ List<js.Parameter> parameters, |
+ js.Statement rewrittenBody, |
+ js.VariableDeclarationList variableDeclarations) { |
+ return js.js( |
+ """ |
function (#parameters) { |
#variableDeclarations; |
var #bodyName = #wrapBody(function (#errorCode, #result) { |
@@ -1784,7 +1764,8 @@ class AsyncRewriter extends AsyncRewriterBase { |
#rewrittenBody; |
}); |
return #asyncHelper(null, #bodyName, #completer, null); |
- }""", { |
+ }""", |
+ { |
"parameters": parameters, |
"variableDeclarations": variableDeclarations, |
"ERROR": js.number(error_codes.ERROR), |
@@ -1803,7 +1784,6 @@ class AsyncRewriter extends AsyncRewriterBase { |
} |
class SyncStarRewriter extends AsyncRewriterBase { |
- |
bool get isSyncStar => true; |
/// Contructor creating the Iterable for a sync* method. Called with |
@@ -1823,18 +1803,14 @@ class SyncStarRewriter extends AsyncRewriterBase { |
/// Used by sync* functions to throw exeptions. |
final js.Expression uncaughtErrorExpression; |
- SyncStarRewriter(DiagnosticReporter diagnosticListener, |
- spannable, |
- {this.endOfIteration, |
- this.newIterable, |
- this.yieldStarExpression, |
- this.uncaughtErrorExpression, |
- String safeVariableName(String proposedName), |
- js.Name bodyName}) |
- : super(diagnosticListener, |
- spannable, |
- safeVariableName, |
- bodyName); |
+ SyncStarRewriter(DiagnosticReporter diagnosticListener, spannable, |
+ {this.endOfIteration, |
+ this.newIterable, |
+ this.yieldStarExpression, |
+ this.uncaughtErrorExpression, |
+ String safeVariableName(String proposedName), |
+ js.Name bodyName}) |
+ : super(diagnosticListener, spannable, safeVariableName, bodyName); |
/// Translates a yield/yield* in an sync*. |
/// |
@@ -1851,9 +1827,10 @@ class SyncStarRewriter extends AsyncRewriterBase { |
} |
@override |
- js.Fun finishFunction(List<js.Parameter> parameters, |
- js.Statement rewrittenBody, |
- js.VariableDeclarationList variableDeclarations) { |
+ js.Fun finishFunction( |
+ List<js.Parameter> parameters, |
+ js.Statement rewrittenBody, |
+ js.VariableDeclarationList variableDeclarations) { |
// Each iterator invocation on the iterable should work on its own copy of |
// the parameters. |
// TODO(sigurdm): We only need to do this copying for parameters that are |
@@ -1865,13 +1842,13 @@ class SyncStarRewriter extends AsyncRewriterBase { |
String name = parameter.name; |
String renamedName = freshName(name); |
renamedParameters.add(new js.Parameter(renamedName)); |
- declarations.add( |
- new js.VariableInitialization(new js.VariableDeclaration(name), |
- new js.VariableUse(renamedName))); |
+ declarations.add(new js.VariableInitialization( |
+ new js.VariableDeclaration(name), new js.VariableUse(renamedName))); |
} |
js.VariableDeclarationList copyParameters = |
new js.VariableDeclarationList(declarations); |
- return js.js(""" |
+ return js.js( |
+ """ |
function (#renamedParameters) { |
if (#needsThis) |
var #self = this; |
@@ -1889,29 +1866,30 @@ class SyncStarRewriter extends AsyncRewriterBase { |
}; |
}); |
} |
- """, { |
- "renamedParameters": renamedParameters, |
- "needsThis": analysis.hasThis, |
- "helperBody": rewrittenBody, |
- "hasParameters": parameters.isNotEmpty, |
- "copyParameters": copyParameters, |
- "varDecl": variableDeclarations, |
- "errorCode": errorCodeName, |
- "newIterable": newIterable, |
- "body": bodyName, |
- "self": selfName, |
- "result": resultName, |
- "goto": goto, |
- "handler": handler, |
- "currentError": currentErrorName, |
- "ERROR": js.number(error_codes.ERROR), |
- }); |
+ """, |
+ { |
+ "renamedParameters": renamedParameters, |
+ "needsThis": analysis.hasThis, |
+ "helperBody": rewrittenBody, |
+ "hasParameters": parameters.isNotEmpty, |
+ "copyParameters": copyParameters, |
+ "varDecl": variableDeclarations, |
+ "errorCode": errorCodeName, |
+ "newIterable": newIterable, |
+ "body": bodyName, |
+ "self": selfName, |
+ "result": resultName, |
+ "goto": goto, |
+ "handler": handler, |
+ "currentError": currentErrorName, |
+ "ERROR": js.number(error_codes.ERROR), |
+ }); |
} |
void addErrorExit() { |
beginLabel(rethrowLabel); |
- addStatement(js.js.statement('return #(#);', |
- [uncaughtErrorExpression, currentError])); |
+ addStatement(js.js |
+ .statement('return #(#);', [uncaughtErrorExpression, currentError])); |
} |
/// Returning from a sync* function returns an [endOfIteration] marker. |
@@ -1933,8 +1911,8 @@ class SyncStarRewriter extends AsyncRewriterBase { |
@override |
js.Statement awaitStatement(js.Expression value) { |
- throw reporter.internalError(spannable, |
- "Sync* functions cannot contain await statements."); |
+ throw reporter.internalError( |
+ spannable, "Sync* functions cannot contain await statements."); |
} |
@override |
@@ -1942,7 +1920,6 @@ class SyncStarRewriter extends AsyncRewriterBase { |
} |
class AsyncStarRewriter extends AsyncRewriterBase { |
- |
bool get isAsyncStar => true; |
/// The stack of labels of finally blocks to assign to [next] if the |
@@ -1950,6 +1927,7 @@ class AsyncStarRewriter extends AsyncRewriterBase { |
js.VariableUse get nextWhenCanceled { |
return new js.VariableUse(nextWhenCanceledName); |
} |
+ |
String nextWhenCanceledName; |
/// The StreamController that controls an async* function. |
@@ -1994,21 +1972,16 @@ class AsyncStarRewriter extends AsyncRewriterBase { |
final js.Expression wrapBody; |
- AsyncStarRewriter(DiagnosticReporter reporter, |
- Spannable spannable, |
- {this.asyncStarHelper, |
- this.streamOfController, |
- this.newController, |
- this.yieldExpression, |
- this.yieldStarExpression, |
- this.wrapBody, |
- String safeVariableName(String proposedName), |
- js.Name bodyName}) |
- : super(reporter, |
- spannable, |
- safeVariableName, |
- bodyName); |
- |
+ AsyncStarRewriter(DiagnosticReporter reporter, Spannable spannable, |
+ {this.asyncStarHelper, |
+ this.streamOfController, |
+ this.newController, |
+ this.yieldExpression, |
+ this.yieldStarExpression, |
+ this.wrapBody, |
+ String safeVariableName(String proposedName), |
+ js.Name bodyName}) |
+ : super(reporter, spannable, safeVariableName, bodyName); |
/// Translates a yield/yield* in an async* function. |
/// |
@@ -2027,25 +2000,31 @@ class AsyncStarRewriter extends AsyncRewriterBase { |
enclosingFinallyLabels.addAll(jumpTargets |
.where((js.Node node) => finallyLabels[node] != null) |
.map((js.Block node) => finallyLabels[node])); |
- addStatement(js.js.statement("# = #;", |
- [nextWhenCanceled, new js.ArrayInitializer( |
- enclosingFinallyLabels.map(js.number).toList())])); |
- addStatement(js.js.statement(""" |
+ addStatement(js.js.statement("# = #;", [ |
+ nextWhenCanceled, |
+ new js.ArrayInitializer(enclosingFinallyLabels.map(js.number).toList()) |
+ ])); |
+ addStatement(js.js.statement( |
+ """ |
return #asyncStarHelper(#yieldExpression(#expression), #bodyName, |
- #controller);""", { |
- "asyncStarHelper": asyncStarHelper, |
- "yieldExpression": node.hasStar ? yieldStarExpression : yieldExpression, |
- "expression": expression, |
- "bodyName": bodyName, |
- "controller": controllerName, |
- })); |
+ #controller);""", |
+ { |
+ "asyncStarHelper": asyncStarHelper, |
+ "yieldExpression": |
+ node.hasStar ? yieldStarExpression : yieldExpression, |
+ "expression": expression, |
+ "bodyName": bodyName, |
+ "controller": controllerName, |
+ })); |
} |
@override |
- js.Fun finishFunction(List<js.Parameter> parameters, |
- js.Statement rewrittenBody, |
- js.VariableDeclarationList variableDeclarations) { |
- return js.js(""" |
+ js.Fun finishFunction( |
+ List<js.Parameter> parameters, |
+ js.Statement rewrittenBody, |
+ js.VariableDeclarationList variableDeclarations) { |
+ return js.js( |
+ """ |
function (#parameters) { |
var #bodyName = #wrapBody(function (#errorCode, #result) { |
if (#hasYield) { |
@@ -2068,7 +2047,8 @@ class AsyncStarRewriter extends AsyncRewriterBase { |
}); |
#variableDeclarations; |
return #streamOfController(#controller); |
- }""", { |
+ }""", |
+ { |
"parameters": parameters, |
"variableDeclarations": variableDeclarations, |
"STREAM_WAS_CANCELED": js.number(error_codes.STREAM_WAS_CANCELED), |
@@ -2094,10 +2074,11 @@ class AsyncStarRewriter extends AsyncRewriterBase { |
beginLabel(rethrowLabel); |
addStatement(js.js.statement( |
"return #asyncHelper(#currentError, #errorCode, #controller);", { |
- "asyncHelper": asyncStarHelper, |
- "errorCode": js.number(error_codes.ERROR), |
- "currentError": currentError, |
- "controller": controllerName})); |
+ "asyncHelper": asyncStarHelper, |
+ "errorCode": js.number(error_codes.ERROR), |
+ "currentError": currentError, |
+ "controller": controllerName |
+ })); |
} |
/// Returning from an async* function calls the [streamHelper] with an |
@@ -2106,20 +2087,20 @@ class AsyncStarRewriter extends AsyncRewriterBase { |
void addSuccesExit() { |
beginLabel(exitLabel); |
- addStatement(js.js.statement( |
- "return #streamHelper(null, #successCode, #controller);", { |
+ addStatement(js.js |
+ .statement("return #streamHelper(null, #successCode, #controller);", { |
"streamHelper": asyncStarHelper, |
"successCode": js.number(error_codes.SUCCESS), |
- "controller": controllerName})); |
+ "controller": controllerName |
+ })); |
} |
@override |
Iterable<js.VariableInitialization> variableInitializations() { |
List<js.VariableInitialization> variables = |
new List<js.VariableInitialization>(); |
- variables.add(_makeVariableInitializer(controller, |
- js.js('#(#)', |
- [newController, bodyName]))); |
+ variables.add(_makeVariableInitializer( |
+ controller, js.js('#(#)', [newController, bodyName]))); |
if (analysis.hasYield) { |
variables.add(_makeVariableInitializer(nextWhenCanceled, null)); |
} |
@@ -2134,15 +2115,18 @@ class AsyncStarRewriter extends AsyncRewriterBase { |
@override |
js.Statement awaitStatement(js.Expression value) { |
- return js.js.statement(""" |
+ return js.js.statement( |
+ """ |
return #asyncHelper(#value, |
#bodyName, |
#controller); |
- """, { |
- "asyncHelper": asyncStarHelper, |
- "value": value, |
- "bodyName": bodyName, |
- "controller": controllerName}); |
+ """, |
+ { |
+ "asyncHelper": asyncStarHelper, |
+ "value": value, |
+ "bodyName": bodyName, |
+ "controller": controllerName |
+ }); |
} |
} |
@@ -2244,8 +2228,8 @@ class PreTranslationAnalysis extends js.NodeVisitor<bool> { |
@override |
bool visitBreak(js.Break node) { |
if (node.targetLabel != null) { |
- targets[node] = labelledStatements.lastWhere( |
- (js.LabeledStatement statement) { |
+ targets[node] = |
+ labelledStatements.lastWhere((js.LabeledStatement statement) { |
return statement.label == node.targetLabel; |
}); |
} else { |