Skip to content

Commit 124305d

Browse files
committed
Emit parens around type-asserted binary operators
Fixes #9766
1 parent cccf70b commit 124305d

File tree

5 files changed

+76
-1
lines changed

5 files changed

+76
-1
lines changed

src/compiler/emitter.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2553,7 +2553,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
25532553
operand = (<TypeAssertion | NonNullExpression>operand).expression;
25542554
}
25552555

2556-
// We have an expression of the form: (<Type>SubExpr)
2556+
// We have an expression of the form: (<Type>SubExpr) or (SubExpr as Type)
25572557
// Emitting this as (SubExpr) is really not desirable. We would like to emit the subexpr as is.
25582558
// Omitting the parentheses, however, could cause change in the semantics of the generated
25592559
// code if the casted expression has a lower precedence than the rest of the expression, e.g.:
@@ -2567,6 +2567,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
25672567
operand.kind !== SyntaxKind.DeleteExpression &&
25682568
operand.kind !== SyntaxKind.PostfixUnaryExpression &&
25692569
operand.kind !== SyntaxKind.NewExpression &&
2570+
!(operand.kind === SyntaxKind.BinaryExpression && node.expression.kind === SyntaxKind.AsExpression) &&
25702571
!(operand.kind === SyntaxKind.CallExpression && node.parent.kind === SyntaxKind.NewExpression) &&
25712572
!(operand.kind === SyntaxKind.FunctionExpression && node.parent.kind === SyntaxKind.CallExpression) &&
25722573
!(operand.kind === SyntaxKind.NumericLiteral && node.parent.kind === SyntaxKind.PropertyAccessExpression)) {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//// [asOpEmitParens.ts]
2+
declare var x;
3+
// Must emit as (x + 1) * 3
4+
(x + 1 as number) * 3;
5+
6+
// Should still emit as x.y
7+
(x as any).y;
8+
9+
// Emit as new (x())
10+
new (x() as any);
11+
12+
13+
//// [asOpEmitParens.js]
14+
// Must emit as (x + 1) * 3
15+
(x + 1) * 3;
16+
// Should still emit as x.y
17+
x.y;
18+
// Emit as new (x())
19+
new (x());
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
=== tests/cases/conformance/expressions/asOperator/asOpEmitParens.ts ===
2+
declare var x;
3+
>x : Symbol(x, Decl(asOpEmitParens.ts, 0, 11))
4+
5+
// Must emit as (x + 1) * 3
6+
(x + 1 as number) * 3;
7+
>x : Symbol(x, Decl(asOpEmitParens.ts, 0, 11))
8+
9+
// Should still emit as x.y
10+
(x as any).y;
11+
>x : Symbol(x, Decl(asOpEmitParens.ts, 0, 11))
12+
13+
// Emit as new (x())
14+
new (x() as any);
15+
>x : Symbol(x, Decl(asOpEmitParens.ts, 0, 11))
16+
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
=== tests/cases/conformance/expressions/asOperator/asOpEmitParens.ts ===
2+
declare var x;
3+
>x : any
4+
5+
// Must emit as (x + 1) * 3
6+
(x + 1 as number) * 3;
7+
>(x + 1 as number) * 3 : number
8+
>(x + 1 as number) : number
9+
>x + 1 as number : number
10+
>x + 1 : any
11+
>x : any
12+
>1 : number
13+
>3 : number
14+
15+
// Should still emit as x.y
16+
(x as any).y;
17+
>(x as any).y : any
18+
>(x as any) : any
19+
>x as any : any
20+
>x : any
21+
>y : any
22+
23+
// Emit as new (x())
24+
new (x() as any);
25+
>new (x() as any) : any
26+
>(x() as any) : any
27+
>x() as any : any
28+
>x() : any
29+
>x : any
30+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
declare var x;
2+
// Must emit as (x + 1) * 3
3+
(x + 1 as number) * 3;
4+
5+
// Should still emit as x.y
6+
(x as any).y;
7+
8+
// Emit as new (x())
9+
new (x() as any);

0 commit comments

Comments
 (0)