dart2js: Distinguish precedence levels for left-hand side and call.

This fixes an issue where `new (f())()` was emitted as `new f()()`.

This in turn fixes some JS interop issues in the CPS backend.

CLOSES #25708

BUG=
R=sigmund@google.com

Review URL: https://codereview.chromium.org/1681863003 .
This commit is contained in:
Asger Feldthaus 2016-02-09 17:15:00 +01:00
parent 20d31ea8c3
commit ba582b48b3
4 changed files with 10 additions and 15 deletions

View file

@ -904,7 +904,7 @@ class NamedFunction extends Expression {
}
NamedFunction _clone() => new NamedFunction(name, function);
int get precedenceLevel => CALL;
int get precedenceLevel => LEFT_HAND_SIDE;
}
class Fun extends Expression {
@ -923,7 +923,7 @@ class Fun extends Expression {
Fun _clone() => new Fun(params, body, asyncModifier: asyncModifier);
int get precedenceLevel => CALL;
int get precedenceLevel => LEFT_HAND_SIDE;
}
class AsyncModifier {
@ -969,7 +969,7 @@ class PropertyAccess extends Expression {
PropertyAccess _clone() => new PropertyAccess(receiver, selector);
int get precedenceLevel => CALL;
int get precedenceLevel => LEFT_HAND_SIDE;
}
/// A [DeferredToken] is a placeholder for some [Expression] that is not known

View file

@ -17,9 +17,6 @@ const SHIFT = RELATIONAL + 1;
const ADDITIVE = SHIFT + 1;
const MULTIPLICATIVE = ADDITIVE + 1;
const UNARY = MULTIPLICATIVE + 1;
const LEFT_HAND_SIDE = UNARY + 1;
// We merge new, call and member expressions.
// This means that we have to emit parenthesis for 'new's. For example `new X;`
// should be printed as `new X();`. This simplifies the requirements.
const CALL = LEFT_HAND_SIDE;
const PRIMARY = CALL + 1;
const CALL = UNARY + 1;
const LEFT_HAND_SIDE = CALL + 1;
const PRIMARY = LEFT_HAND_SIDE + 1;

View file

@ -678,7 +678,7 @@ class Printer implements NodeVisitor {
@override
visitAssignment(Assignment assignment) {
visitNestedExpression(assignment.leftHandSide, LEFT_HAND_SIDE,
visitNestedExpression(assignment.leftHandSide, CALL,
newInForInit: inForInit,
newAtStatementBegin: atStatementBegin);
if (assignment.value != null) {
@ -719,7 +719,7 @@ class Printer implements NodeVisitor {
@override
visitNew(New node) {
out("new ");
visitNestedExpression(node.target, CALL,
visitNestedExpression(node.target, LEFT_HAND_SIDE,
newInForInit: inForInit, newAtStatementBegin: false);
out("(");
visitCommaSeparated(node.arguments, ASSIGNMENT,
@ -729,7 +729,7 @@ class Printer implements NodeVisitor {
@override
visitCall(Call call) {
visitNestedExpression(call.target, LEFT_HAND_SIDE,
visitNestedExpression(call.target, CALL,
newInForInit: inForInit,
newAtStatementBegin: atStatementBegin);
out("(");
@ -872,7 +872,7 @@ class Printer implements NodeVisitor {
@override
void visitPostfix(Postfix postfix) {
visitNestedExpression(postfix.argument, LEFT_HAND_SIDE,
visitNestedExpression(postfix.argument, CALL,
newInForInit: inForInit,
newAtStatementBegin: atStatementBegin);
out(postfix.op);

View file

@ -452,6 +452,4 @@ js_typed_interop_test: RuntimeError # Need package:js support #24978
mirrors_js_typed_interop_test: RuntimeError # Need package:js support #24978
# These are raw dart:js tests that fail due to bugs in the CPS IR:
js_test/JsObject_methods: RuntimeError # Bad code for new #(). Issue #25708
js_test/new_JsObject: RuntimeError # Bad code for new #(). Issue #25708
js_test/Dart_functions: RuntimeError # Tree-shaking an escaping closure #25720