Merge pull request #9767 from RyanCavanaugh/fix9766

Emit parens around type-asserted binary operators
This commit is contained in:
Ryan Cavanaugh 2016-08-01 15:44:48 -07:00 committed by GitHub
commit 2d20dbf25e
7 changed files with 76 additions and 35 deletions

View File

@ -2578,7 +2578,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
operand = (<TypeAssertion | NonNullExpression>operand).expression;
}
// We have an expression of the form: (<Type>SubExpr)
// We have an expression of the form: (<Type>SubExpr) or (SubExpr as Type)
// 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.:
@ -2592,6 +2592,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
operand.kind !== SyntaxKind.DeleteExpression &&
operand.kind !== SyntaxKind.PostfixUnaryExpression &&
operand.kind !== SyntaxKind.NewExpression &&
!(operand.kind === SyntaxKind.BinaryExpression && node.expression.kind === SyntaxKind.AsExpression) &&
!(operand.kind === SyntaxKind.CallExpression && node.parent.kind === SyntaxKind.NewExpression) &&
!(operand.kind === SyntaxKind.FunctionExpression && node.parent.kind === SyntaxKind.CallExpression) &&
!(operand.kind === SyntaxKind.NumericLiteral && node.parent.kind === SyntaxKind.PropertyAccessExpression)) {

View File

@ -0,0 +1,19 @@
//// [asOpEmitParens.ts]
declare var x;
// Must emit as (x + 1) * 3
(x + 1 as number) * 3;
// Should still emit as x.y
(x as any).y;
// Emit as new (x())
new (x() as any);
//// [asOpEmitParens.js]
// Must emit as (x + 1) * 3
(x + 1) * 3;
// Should still emit as x.y
x.y;
// Emit as new (x())
new (x());

View File

@ -0,0 +1,16 @@
=== tests/cases/conformance/expressions/asOperator/asOpEmitParens.ts ===
declare var x;
>x : Symbol(x, Decl(asOpEmitParens.ts, 0, 11))
// Must emit as (x + 1) * 3
(x + 1 as number) * 3;
>x : Symbol(x, Decl(asOpEmitParens.ts, 0, 11))
// Should still emit as x.y
(x as any).y;
>x : Symbol(x, Decl(asOpEmitParens.ts, 0, 11))
// Emit as new (x())
new (x() as any);
>x : Symbol(x, Decl(asOpEmitParens.ts, 0, 11))

View File

@ -0,0 +1,30 @@
=== tests/cases/conformance/expressions/asOperator/asOpEmitParens.ts ===
declare var x;
>x : any
// Must emit as (x + 1) * 3
(x + 1 as number) * 3;
>(x + 1 as number) * 3 : number
>(x + 1 as number) : number
>x + 1 as number : number
>x + 1 : any
>x : any
>1 : number
>3 : number
// Should still emit as x.y
(x as any).y;
>(x as any).y : any
>(x as any) : any
>x as any : any
>x : any
>y : any
// Emit as new (x())
new (x() as any);
>new (x() as any) : any
>(x() as any) : any
>x() as any : any
>x() : any
>x : any

View File

@ -1,20 +0,0 @@
tests/cases/compiler/b.d.ts(2,20): error TS2305: Module '"tests/cases/compiler/a".ns' has no exported member 'IFoo'.
==== tests/cases/compiler/a.d.ts (0 errors) ====
export = ns;
export as namespace ns;
declare namespace ns {
export var x: number;
export interface IFoo { }
}
==== tests/cases/compiler/b.d.ts (1 errors) ====
declare namespace ns.something {
export var p: ns.IFoo;
~~~~
!!! error TS2305: Module '"tests/cases/compiler/a".ns' has no exported member 'IFoo'.
}

View File

@ -1,14 +0,0 @@
// @filename: a.d.ts
export = ns;
export as namespace ns;
declare namespace ns {
export var x: number;
export interface IFoo { }
}
// @filename: b.d.ts
declare namespace ns.something {
export var p: ns.IFoo;
}

View File

@ -0,0 +1,9 @@
declare var x;
// Must emit as (x + 1) * 3
(x + 1 as number) * 3;
// Should still emit as x.y
(x as any).y;
// Emit as new (x())
new (x() as any);