Fix renaming of exception variables on left-hand-sides.

Also fix compound assignments.

BUG=
R=floitsch@google.com

Review URL: https://codereview.chromium.org//1012783002

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@44558 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
sigurdm@google.com 2015-03-18 14:04:41 +00:00
parent 745b6809e9
commit 25e11e6b29
4 changed files with 116 additions and 5 deletions

View file

@ -749,7 +749,12 @@ abstract class AsyncRewriterBase extends js.NodeVisitor {
js.Expression leftHandSide = node.leftHandSide;
if (leftHandSide is js.VariableUse) {
return withExpression(node.value, (js.Expression value) {
return new js.Assignment(leftHandSide, value);
// 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);
}, store: false);
} else if (leftHandSide is js.PropertyAccess) {
return withExpressions([
@ -1211,7 +1216,7 @@ abstract class AsyncRewriterBase extends js.NodeVisitor {
if (node.op == "++" || node.op == "--") {
js.Expression argument = node.argument;
if (argument is js.VariableUse) {
return new js.Postfix(node.op, argument);
return new js.Postfix(node.op, visitExpression(argument));
} else if (argument is js.PropertyAccess) {
return withExpression2(argument.receiver, argument.selector,
(receiver, selector) {
@ -1233,7 +1238,7 @@ abstract class AsyncRewriterBase extends js.NodeVisitor {
if (node.op == "++" || node.op == "--") {
js.Expression argument = node.argument;
if (argument is js.VariableUse) {
return new js.Prefix(node.op, argument);
return new js.Prefix(node.op, visitExpression(argument));
} else if (argument is js.PropertyAccess) {
return withExpression2(argument.receiver, argument.selector,
(receiver, selector) {
@ -1528,7 +1533,7 @@ abstract class AsyncRewriterBase extends js.NodeVisitor {
@override
js.Expression visitVariableDeclarationList(js.VariableDeclarationList node) {
List<js.Assignment> initializations = new List<js.Assignment>();
List<js.Expression> initializations = new List<js.Expression>();
// Declaration of local variables is hoisted outside the helper but the
// initialization is done here.

View file

@ -611,6 +611,7 @@ class Assignment extends Expression {
Assignment(leftHandSide, value)
: this.compound(leftHandSide, null, value);
// If `this.op == null` this will be a non-compound assignment.
Assignment.compound(this.leftHandSide, this.op, this.value);
int get precedenceLevel => ASSIGNMENT;

View file

@ -597,7 +597,7 @@ function(g) {
return thenHelper(foo2(), __body, __completer);
case 11:
// returning from await.
i = __result;
i += __result;
// goto for condition
__goto = 3;
break;
@ -1059,4 +1059,83 @@ function(l) {
}
return thenHelper(null, __body, __completer, null);
}""");
testTransform("""
function(m) async {
var exception = 1;
try {
await 42;
throw 42;
} catch (exception) {
exception = await 10;
exception += await 10;
exception++;
exception--;
++exception;
--exception;
exception += 10;
}
print(exception);
}""", """
function(m) {
var __goto = 0, __completer = new Completer(), __handler = 1, __currentError, __next = [], exception, __exception;
function __body(__errorCode, __result) {
if (__errorCode === 1) {
__currentError = __result;
__goto = __handler;
}
while (true)
switch (__goto) {
case 0:
// Function start
exception = 1;
__handler = 3;
__goto = 6;
return thenHelper(42, __body, __completer);
case 6:
// returning from await.
throw 42;
__handler = 1;
// goto after finally
__goto = 5;
break;
case 3:
// catch
__handler = 2;
__exception = __currentError;
__goto = 7;
return thenHelper(10, __body, __completer);
case 7:
// returning from await.
__exception = __result;
__goto = 8;
return thenHelper(10, __body, __completer);
case 8:
// returning from await.
__exception += __result;
__exception++;
__exception--;
++__exception;
--__exception;
__exception += 10;
// goto after finally
__goto = 5;
break;
case 2:
// uncaught
// goto rethrow
__goto = 1;
break;
case 5:
// after finally
print(exception);
// implicit return
return thenHelper(null, 0, __completer, null);
case 1:
// rethrow
return thenHelper(__currentError, 1, __completer);
}
}
return thenHelper(null, __body, __completer, null);
}""");
}

View file

@ -0,0 +1,26 @@
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
import "package:async_helper/async_helper.dart";
foo() async {
throw 42;
}
test() async {
var exception;
try {
await foo();
} catch (e) {
print(await(e));
await (exception = await e);
}
Expect.equals(42, exception);
}
main() {
asyncStart();
test().then((_) => asyncEnd());
}