From ba582b48b359bd193ecf643515176f827a9452e7 Mon Sep 17 00:00:00 2001 From: Asger Feldthaus Date: Tue, 9 Feb 2016 17:15:00 +0100 Subject: [PATCH] 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 . --- pkg/js_ast/lib/src/nodes.dart | 6 +++--- pkg/js_ast/lib/src/precedence.dart | 9 +++------ pkg/js_ast/lib/src/printer.dart | 8 ++++---- tests/html/html.status | 2 -- 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/pkg/js_ast/lib/src/nodes.dart b/pkg/js_ast/lib/src/nodes.dart index 27511cafcdd..94371a0e688 100644 --- a/pkg/js_ast/lib/src/nodes.dart +++ b/pkg/js_ast/lib/src/nodes.dart @@ -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 diff --git a/pkg/js_ast/lib/src/precedence.dart b/pkg/js_ast/lib/src/precedence.dart index 6d66f1fca5a..222f4a80f07 100644 --- a/pkg/js_ast/lib/src/precedence.dart +++ b/pkg/js_ast/lib/src/precedence.dart @@ -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; diff --git a/pkg/js_ast/lib/src/printer.dart b/pkg/js_ast/lib/src/printer.dart index edd4189d3af..564a467afb0 100644 --- a/pkg/js_ast/lib/src/printer.dart +++ b/pkg/js_ast/lib/src/printer.dart @@ -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); diff --git a/tests/html/html.status b/tests/html/html.status index a0120a8a1ab..8a8dae64157 100644 --- a/tests/html/html.status +++ b/tests/html/html.status @@ -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