CR feedback.

This commit is contained in:
Cyrus Najmabadi 2015-03-07 02:08:36 -08:00
parent 0c5654164f
commit bdcdd84dda
7 changed files with 151 additions and 25 deletions

View File

@ -3179,35 +3179,38 @@ module ts {
}
function emitParenExpression(node: ParenthesizedExpression) {
if (node.expression.kind === SyntaxKind.TypeAssertionExpression) {
var operand = (<TypeAssertion>node.expression).expression;
if (!node.parent || node.parent.kind !== SyntaxKind.ArrowFunction) {
if (node.expression.kind === SyntaxKind.TypeAssertionExpression) {
var operand = (<TypeAssertion>node.expression).expression;
// Make sure we consider all nested cast expressions, e.g.:
// (<any><number><any>-A).x;
while (operand.kind == SyntaxKind.TypeAssertionExpression) {
operand = (<TypeAssertion>operand).expression;
}
// Make sure we consider all nested cast expressions, e.g.:
// (<any><number><any>-A).x;
while (operand.kind == SyntaxKind.TypeAssertionExpression) {
operand = (<TypeAssertion>operand).expression;
}
// We have an expression of the form: (<Type>SubExpr)
// Emitting this as (SubExpr) is really not desirable. We would like to emit the subexpr as is.
// Omitting the parentheses, however, could cause change in the semantics of the generated
// code if the casted expression has a lower precedence than the rest of the expression, e.g.:
// (<any>new A).foo should be emitted as (new A).foo and not new A.foo
// (<any>typeof A).toString() should be emitted as (typeof A).toString() and not typeof A.toString()
// new (<any>A()) should be emitted as new (A()) and not new A()
// (<any>function foo() { })() should be emitted as an IIF (function foo(){})() and not declaration function foo(){} ()
if (operand.kind !== SyntaxKind.PrefixUnaryExpression &&
operand.kind !== SyntaxKind.VoidExpression &&
operand.kind !== SyntaxKind.TypeOfExpression &&
operand.kind !== SyntaxKind.DeleteExpression &&
operand.kind !== SyntaxKind.PostfixUnaryExpression &&
operand.kind !== SyntaxKind.NewExpression &&
!(operand.kind === SyntaxKind.CallExpression && node.parent.kind === SyntaxKind.NewExpression) &&
!(operand.kind === SyntaxKind.FunctionExpression && node.parent.kind === SyntaxKind.CallExpression)) {
emit(operand);
return;
// We have an expression of the form: (<Type>SubExpr)
// Emitting this as (SubExpr) is really not desirable. We would like to emit the subexpr as is.
// Omitting the parentheses, however, could cause change in the semantics of the generated
// code if the casted expression has a lower precedence than the rest of the expression, e.g.:
// (<any>new A).foo should be emitted as (new A).foo and not new A.foo
// (<any>typeof A).toString() should be emitted as (typeof A).toString() and not typeof A.toString()
// new (<any>A()) should be emitted as new (A()) and not new A()
// (<any>function foo() { })() should be emitted as an IIF (function foo(){})() and not declaration function foo(){} ()
if (operand.kind !== SyntaxKind.PrefixUnaryExpression &&
operand.kind !== SyntaxKind.VoidExpression &&
operand.kind !== SyntaxKind.TypeOfExpression &&
operand.kind !== SyntaxKind.DeleteExpression &&
operand.kind !== SyntaxKind.PostfixUnaryExpression &&
operand.kind !== SyntaxKind.NewExpression &&
!(operand.kind === SyntaxKind.CallExpression && node.parent.kind === SyntaxKind.NewExpression) &&
!(operand.kind === SyntaxKind.FunctionExpression && node.parent.kind === SyntaxKind.CallExpression)) {
emit(operand);
return;
}
}
}
write("(");
emit(node.expression);
write(")");

View File

@ -0,0 +1,14 @@
//// [arrowFunctionWithObjectLiteralBody5.ts]
var a = () => <Error>{ name: "foo", message: "bar" };
var b = () => (<Error>{ name: "foo", message: "bar" });
var c = () => ({ name: "foo", message: "bar" });
var d = () => ((<Error>({ name: "foo", message: "bar" })));
//// [arrowFunctionWithObjectLiteralBody5.js]
var a = function () { return { name: "foo", message: "bar" }; };
var b = function () { return ({ name: "foo", message: "bar" }); };
var c = function () { return ({ name: "foo", message: "bar" }); };
var d = function () { return (({ name: "foo", message: "bar" })); };

View File

@ -0,0 +1,40 @@
=== tests/cases/compiler/arrowFunctionWithObjectLiteralBody5.ts ===
var a = () => <Error>{ name: "foo", message: "bar" };
>a : () => Error
>() => <Error>{ name: "foo", message: "bar" } : () => Error
><Error>{ name: "foo", message: "bar" } : Error
>Error : Error
>{ name: "foo", message: "bar" } : { name: string; message: string; }
>name : string
>message : string
var b = () => (<Error>{ name: "foo", message: "bar" });
>b : () => Error
>() => (<Error>{ name: "foo", message: "bar" }) : () => Error
>(<Error>{ name: "foo", message: "bar" }) : Error
><Error>{ name: "foo", message: "bar" } : Error
>Error : Error
>{ name: "foo", message: "bar" } : { name: string; message: string; }
>name : string
>message : string
var c = () => ({ name: "foo", message: "bar" });
>c : () => { name: string; message: string; }
>() => ({ name: "foo", message: "bar" }) : () => { name: string; message: string; }
>({ name: "foo", message: "bar" }) : { name: string; message: string; }
>{ name: "foo", message: "bar" } : { name: string; message: string; }
>name : string
>message : string
var d = () => ((<Error>({ name: "foo", message: "bar" })));
>d : () => Error
>() => ((<Error>({ name: "foo", message: "bar" }))) : () => Error
>((<Error>({ name: "foo", message: "bar" }))) : Error
>(<Error>({ name: "foo", message: "bar" })) : Error
><Error>({ name: "foo", message: "bar" }) : Error
>Error : Error
>({ name: "foo", message: "bar" }) : { name: string; message: string; }
>{ name: "foo", message: "bar" } : { name: string; message: string; }
>name : string
>message : string

View File

@ -0,0 +1,14 @@
//// [arrowFunctionWithObjectLiteralBody6.ts]
var a = () => <Error>{ name: "foo", message: "bar" };
var b = () => (<Error>{ name: "foo", message: "bar" });
var c = () => ({ name: "foo", message: "bar" });
var d = () => ((<Error>({ name: "foo", message: "bar" })));
//// [arrowFunctionWithObjectLiteralBody6.js]
var a = () => ({ name: "foo", message: "bar" });
var b = () => ({ name: "foo", message: "bar" });
var c = () => ({ name: "foo", message: "bar" });
var d = () => (({ name: "foo", message: "bar" }));

View File

@ -0,0 +1,40 @@
=== tests/cases/compiler/arrowFunctionWithObjectLiteralBody6.ts ===
var a = () => <Error>{ name: "foo", message: "bar" };
>a : () => Error
>() => <Error>{ name: "foo", message: "bar" } : () => Error
><Error>{ name: "foo", message: "bar" } : Error
>Error : Error
>{ name: "foo", message: "bar" } : { name: string; message: string; }
>name : string
>message : string
var b = () => (<Error>{ name: "foo", message: "bar" });
>b : () => Error
>() => (<Error>{ name: "foo", message: "bar" }) : () => Error
>(<Error>{ name: "foo", message: "bar" }) : Error
><Error>{ name: "foo", message: "bar" } : Error
>Error : Error
>{ name: "foo", message: "bar" } : { name: string; message: string; }
>name : string
>message : string
var c = () => ({ name: "foo", message: "bar" });
>c : () => { name: string; message: string; }
>() => ({ name: "foo", message: "bar" }) : () => { name: string; message: string; }
>({ name: "foo", message: "bar" }) : { name: string; message: string; }
>{ name: "foo", message: "bar" } : { name: string; message: string; }
>name : string
>message : string
var d = () => ((<Error>({ name: "foo", message: "bar" })));
>d : () => Error
>() => ((<Error>({ name: "foo", message: "bar" }))) : () => Error
>((<Error>({ name: "foo", message: "bar" }))) : Error
>(<Error>({ name: "foo", message: "bar" })) : Error
><Error>({ name: "foo", message: "bar" }) : Error
>Error : Error
>({ name: "foo", message: "bar" }) : { name: string; message: string; }
>{ name: "foo", message: "bar" } : { name: string; message: string; }
>name : string
>message : string

View File

@ -0,0 +1,7 @@
var a = () => <Error>{ name: "foo", message: "bar" };
var b = () => (<Error>{ name: "foo", message: "bar" });
var c = () => ({ name: "foo", message: "bar" });
var d = () => ((<Error>({ name: "foo", message: "bar" })));

View File

@ -0,0 +1,8 @@
// @target: es6
var a = () => <Error>{ name: "foo", message: "bar" };
var b = () => (<Error>{ name: "foo", message: "bar" });
var c = () => ({ name: "foo", message: "bar" });
var d = () => ((<Error>({ name: "foo", message: "bar" })));