| 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 c2863c5d895c9e32fc00dcc6819e9818b200cf4d..2e78d2816346d5eb775ecfd307e9be8c61abe1fd 100644
|
| --- a/pkg/compiler/lib/src/js/rewrite_async.dart
|
| +++ b/pkg/compiler/lib/src/js/rewrite_async.dart
|
| @@ -399,11 +399,14 @@ abstract class AsyncRewriterBase extends js.NodeVisitor {
|
| // Note that RegExes, js.ArrayInitializer and js.ObjectInitializer are not
|
| // [js.Literal]s.
|
| if (result is js.Literal) return result;
|
| +
|
| js.Expression tempVar = useTempVar(allocateTempVar());
|
| addStatement(js.js.statement('# = #;', [tempVar, result]));
|
| return tempVar;
|
| }
|
|
|
| + // TODO(sigurdm): This is obsolete - all calls use store: false. Replace with
|
| + // visitExpression(node);
|
| withExpression(js.Expression node, fn(js.Expression result), {bool store}) {
|
| int oldTempVarIndex = currentTempVarIndex;
|
| js.Expression visited = visitExpression(node);
|
| @@ -415,6 +418,46 @@ abstract class AsyncRewriterBase extends js.NodeVisitor {
|
| return result;
|
| }
|
|
|
| + /// Calls [fn] with the result of evaluating [node]. Taking special care of
|
| + /// property accesses.
|
| + ///
|
| + /// If [store] is true the result of evaluating [node] is stored in a
|
| + /// temporary.
|
| + ///
|
| + /// We cannot rewrite `<receiver>.m()` to:
|
| + /// temp = <receiver>.m;
|
| + /// temp();
|
| + /// Because this leaves `this` unbound in the call. But because of dart
|
| + /// evaluation order we can write:
|
| + /// temp = <receiver>;
|
| + /// temp.m();
|
| + withCallTargetExpression(js.Expression node,
|
| + fn(js.Expression result), {bool store}) {
|
| + int oldTempVarIndex = currentTempVarIndex;
|
| + js.Expression visited = visitExpression(node);
|
| + js.Expression selector;
|
| + js.Expression storedIfNeeded;
|
| + if (store) {
|
| + if (visited is js.PropertyAccess) {
|
| + js.PropertyAccess propertyAccess = visited;
|
| + selector = propertyAccess.selector;
|
| + visited = propertyAccess.receiver;
|
| + }
|
| + storedIfNeeded = _storeIfNecessary(visited);
|
| + } else {
|
| + storedIfNeeded = visited;
|
| + }
|
| + js.Expression result;
|
| + if (selector == null) {
|
| + result = fn(storedIfNeeded);
|
| + } else {
|
| + result = fn(new js.PropertyAccess(storedIfNeeded, selector));
|
| + }
|
| + currentTempVarIndex = oldTempVarIndex;
|
| + return result;
|
| + }
|
| +
|
| +
|
| /// Calls [fn] with the value of evaluating [node1] and [node2].
|
| ///
|
| /// If `shouldTransform(node2)` the first expression is stored in a temporary
|
| @@ -805,7 +848,7 @@ abstract class AsyncRewriterBase extends js.NodeVisitor {
|
| @override
|
| js.Expression visitCall(js.Call node) {
|
| bool storeTarget = node.arguments.any(shouldTransform);
|
| - return withExpression(node.target, (target) {
|
| + return withCallTargetExpression(node.target, (target) {
|
| return withExpressions(node.arguments, (List<js.Expression> arguments) {
|
| return new js.Call(target, arguments);
|
| });
|
| @@ -920,7 +963,8 @@ abstract class AsyncRewriterBase extends js.NodeVisitor {
|
| bool oldInsideUntranslatedBreakable = insideUntranslatedBreakable;
|
| insideUntranslatedBreakable = true;
|
| withExpression(node.condition, (js.Expression condition) {
|
| - addStatement(js.js.statement('do {#} while (#)', [node.body, condition]));
|
| + addStatement(js.js.statement('do {#} while (#)',
|
| + [node.body, condition]));
|
| }, store: false);
|
| insideUntranslatedBreakable = oldInsideUntranslatedBreakable;
|
| return;
|
| @@ -1148,7 +1192,7 @@ abstract class AsyncRewriterBase extends js.NodeVisitor {
|
| @override
|
| js.Expression visitNew(js.New node) {
|
| bool storeTarget = node.arguments.any(shouldTransform);
|
| - return withExpression(node.target, (target) {
|
| + return withCallTargetExpression(node.target, (target) {
|
| return withExpressions(node.arguments, (List<js.Expression> arguments) {
|
| return new js.New(target, arguments);
|
| });
|
| @@ -1777,7 +1821,8 @@ class SyncStarRewriter extends AsyncRewriterBase {
|
| 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 mutated.
|
| + // TODO(sigurdm): We only need to do this copying for parameters that are
|
| + // mutated.
|
| List<js.VariableInitialization> declarations =
|
| new List<js.VariableInitialization>();
|
| List<js.Parameter> renamedParameters = new List<js.Parameter>();
|
|
|