From 4ccf088734ad929f347a29ad0962830116ca575f Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Wed, 3 Jun 2015 17:22:11 -0700 Subject: [PATCH 1/4] Don't try to strip parentheses when emitting synthesized parenthesized expressions --- src/compiler/emitter.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 028a65ddfa1..5a0db87d409 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1644,6 +1644,13 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } function parenthesizeForAccess(expr: Expression): LeftHandSideExpression { + // When diagnosing whether the expression needs parentheses, the decision should be based + // on the innermost expression in a chain of nested type assertions. + let innerExpression = expr; + while (innerExpression.kind === SyntaxKind.TypeAssertionExpression) { + innerExpression = (innerExpression).expression; + } + // isLeftHandSideExpression is almost the correct criterion for when it is not necessary // to parenthesize the expression before a dot. The known exceptions are: // @@ -1652,7 +1659,10 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { // NumberLiteral // 1.x -> not the same as (1).x // - if (isLeftHandSideExpression(expr) && expr.kind !== SyntaxKind.NewExpression && expr.kind !== SyntaxKind.NumericLiteral) { + if (isLeftHandSideExpression(innerExpression) && + innerExpression.kind !== SyntaxKind.NewExpression && + innerExpression.kind !== SyntaxKind.NumericLiteral) { + return expr; } let node = createSynthesizedNode(SyntaxKind.ParenthesizedExpression); @@ -1906,7 +1916,10 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } function emitParenExpression(node: ParenthesizedExpression) { - if (!node.parent || node.parent.kind !== SyntaxKind.ArrowFunction) { + // If the node is synthesized, it means the emitter put the parentheses there, + // not the user. If we didn't want them, the emitter would not have put them + // there. + if (!nodeIsSynthesized(node) && node.parent.kind !== SyntaxKind.ArrowFunction) { if (node.expression.kind === SyntaxKind.TypeAssertionExpression) { let operand = (node.expression).expression; From 7a74d9f8d021f50201765d2170af8d249af90320 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Wed, 3 Jun 2015 17:22:38 -0700 Subject: [PATCH 2/4] Add tests for parenthesized type assertions --- .../es6/destructuring/destructuringTypeAssertionsES5_1.ts | 2 ++ .../es6/destructuring/destructuringTypeAssertionsES5_2.ts | 2 ++ .../es6/destructuring/destructuringTypeAssertionsES5_3.ts | 2 ++ .../es6/destructuring/destructuringTypeAssertionsES5_4.ts | 2 ++ .../es6/destructuring/destructuringTypeAssertionsES5_5.ts | 2 ++ .../es6/destructuring/destructuringTypeAssertionsES5_6.ts | 2 ++ .../es6/destructuring/destructuringTypeAssertionsES5_7.ts | 2 ++ 7 files changed, 14 insertions(+) create mode 100644 tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_1.ts create mode 100644 tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_2.ts create mode 100644 tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_3.ts create mode 100644 tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_4.ts create mode 100644 tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_5.ts create mode 100644 tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_6.ts create mode 100644 tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_7.ts diff --git a/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_1.ts b/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_1.ts new file mode 100644 index 00000000000..7be8ce1dc12 --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_1.ts @@ -0,0 +1,2 @@ +//@target: ES5 +var { x } = foo(); \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_2.ts b/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_2.ts new file mode 100644 index 00000000000..7c4e084796a --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_2.ts @@ -0,0 +1,2 @@ +//@target: ES5 +var { x } = (foo()); \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_3.ts b/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_3.ts new file mode 100644 index 00000000000..30386fe9f86 --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_3.ts @@ -0,0 +1,2 @@ +//@target: ES5 +var { x } = (foo()); \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_4.ts b/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_4.ts new file mode 100644 index 00000000000..84f251c205b --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_4.ts @@ -0,0 +1,2 @@ +//@target: ES5 +var { x } = foo(); \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_5.ts b/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_5.ts new file mode 100644 index 00000000000..927a53883d3 --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_5.ts @@ -0,0 +1,2 @@ +//@target: ES5 +var { x } = 0; \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_6.ts b/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_6.ts new file mode 100644 index 00000000000..2097a8ec760 --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_6.ts @@ -0,0 +1,2 @@ +//@target: ES5 +var { x } = new Foo; \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_7.ts b/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_7.ts new file mode 100644 index 00000000000..d11381dc088 --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_7.ts @@ -0,0 +1,2 @@ +//@target: ES5 +var { x } = new Foo; \ No newline at end of file From 26cf97430e6f2cec2141155f61edfafe8ed49b42 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Wed, 3 Jun 2015 17:22:51 -0700 Subject: [PATCH 3/4] Accept baselines for parenthesized type assertions --- .../reference/destructuringTypeAssertionsES5_1.errors.txt | 7 +++++++ .../reference/destructuringTypeAssertionsES5_1.js | 5 +++++ .../reference/destructuringTypeAssertionsES5_2.errors.txt | 7 +++++++ .../reference/destructuringTypeAssertionsES5_2.js | 5 +++++ .../reference/destructuringTypeAssertionsES5_3.errors.txt | 7 +++++++ .../reference/destructuringTypeAssertionsES5_3.js | 5 +++++ .../reference/destructuringTypeAssertionsES5_4.errors.txt | 7 +++++++ .../reference/destructuringTypeAssertionsES5_4.js | 5 +++++ .../reference/destructuringTypeAssertionsES5_5.js | 5 +++++ .../reference/destructuringTypeAssertionsES5_5.symbols | 4 ++++ .../reference/destructuringTypeAssertionsES5_5.types | 6 ++++++ .../reference/destructuringTypeAssertionsES5_6.errors.txt | 7 +++++++ .../reference/destructuringTypeAssertionsES5_6.js | 5 +++++ .../reference/destructuringTypeAssertionsES5_7.errors.txt | 7 +++++++ .../reference/destructuringTypeAssertionsES5_7.js | 5 +++++ 15 files changed, 87 insertions(+) create mode 100644 tests/baselines/reference/destructuringTypeAssertionsES5_1.errors.txt create mode 100644 tests/baselines/reference/destructuringTypeAssertionsES5_1.js create mode 100644 tests/baselines/reference/destructuringTypeAssertionsES5_2.errors.txt create mode 100644 tests/baselines/reference/destructuringTypeAssertionsES5_2.js create mode 100644 tests/baselines/reference/destructuringTypeAssertionsES5_3.errors.txt create mode 100644 tests/baselines/reference/destructuringTypeAssertionsES5_3.js create mode 100644 tests/baselines/reference/destructuringTypeAssertionsES5_4.errors.txt create mode 100644 tests/baselines/reference/destructuringTypeAssertionsES5_4.js create mode 100644 tests/baselines/reference/destructuringTypeAssertionsES5_5.js create mode 100644 tests/baselines/reference/destructuringTypeAssertionsES5_5.symbols create mode 100644 tests/baselines/reference/destructuringTypeAssertionsES5_5.types create mode 100644 tests/baselines/reference/destructuringTypeAssertionsES5_6.errors.txt create mode 100644 tests/baselines/reference/destructuringTypeAssertionsES5_6.js create mode 100644 tests/baselines/reference/destructuringTypeAssertionsES5_7.errors.txt create mode 100644 tests/baselines/reference/destructuringTypeAssertionsES5_7.js diff --git a/tests/baselines/reference/destructuringTypeAssertionsES5_1.errors.txt b/tests/baselines/reference/destructuringTypeAssertionsES5_1.errors.txt new file mode 100644 index 00000000000..187c1d33f3d --- /dev/null +++ b/tests/baselines/reference/destructuringTypeAssertionsES5_1.errors.txt @@ -0,0 +1,7 @@ +tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_1.ts(1,18): error TS2304: Cannot find name 'foo'. + + +==== tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_1.ts (1 errors) ==== + var { x } = foo(); + ~~~ +!!! error TS2304: Cannot find name 'foo'. \ No newline at end of file diff --git a/tests/baselines/reference/destructuringTypeAssertionsES5_1.js b/tests/baselines/reference/destructuringTypeAssertionsES5_1.js new file mode 100644 index 00000000000..296cad051b1 --- /dev/null +++ b/tests/baselines/reference/destructuringTypeAssertionsES5_1.js @@ -0,0 +1,5 @@ +//// [destructuringTypeAssertionsES5_1.ts] +var { x } = foo(); + +//// [destructuringTypeAssertionsES5_1.js] +var x = foo().x; diff --git a/tests/baselines/reference/destructuringTypeAssertionsES5_2.errors.txt b/tests/baselines/reference/destructuringTypeAssertionsES5_2.errors.txt new file mode 100644 index 00000000000..2036653820b --- /dev/null +++ b/tests/baselines/reference/destructuringTypeAssertionsES5_2.errors.txt @@ -0,0 +1,7 @@ +tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_2.ts(1,19): error TS2304: Cannot find name 'foo'. + + +==== tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_2.ts (1 errors) ==== + var { x } = (foo()); + ~~~ +!!! error TS2304: Cannot find name 'foo'. \ No newline at end of file diff --git a/tests/baselines/reference/destructuringTypeAssertionsES5_2.js b/tests/baselines/reference/destructuringTypeAssertionsES5_2.js new file mode 100644 index 00000000000..1725b7042ec --- /dev/null +++ b/tests/baselines/reference/destructuringTypeAssertionsES5_2.js @@ -0,0 +1,5 @@ +//// [destructuringTypeAssertionsES5_2.ts] +var { x } = (foo()); + +//// [destructuringTypeAssertionsES5_2.js] +var x = foo().x; diff --git a/tests/baselines/reference/destructuringTypeAssertionsES5_3.errors.txt b/tests/baselines/reference/destructuringTypeAssertionsES5_3.errors.txt new file mode 100644 index 00000000000..a3aef8b91ea --- /dev/null +++ b/tests/baselines/reference/destructuringTypeAssertionsES5_3.errors.txt @@ -0,0 +1,7 @@ +tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_3.ts(1,19): error TS2304: Cannot find name 'foo'. + + +==== tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_3.ts (1 errors) ==== + var { x } = (foo()); + ~~~ +!!! error TS2304: Cannot find name 'foo'. \ No newline at end of file diff --git a/tests/baselines/reference/destructuringTypeAssertionsES5_3.js b/tests/baselines/reference/destructuringTypeAssertionsES5_3.js new file mode 100644 index 00000000000..1c8b8b1e5d8 --- /dev/null +++ b/tests/baselines/reference/destructuringTypeAssertionsES5_3.js @@ -0,0 +1,5 @@ +//// [destructuringTypeAssertionsES5_3.ts] +var { x } = (foo()); + +//// [destructuringTypeAssertionsES5_3.js] +var x = (foo()).x; diff --git a/tests/baselines/reference/destructuringTypeAssertionsES5_4.errors.txt b/tests/baselines/reference/destructuringTypeAssertionsES5_4.errors.txt new file mode 100644 index 00000000000..a27afe42f3c --- /dev/null +++ b/tests/baselines/reference/destructuringTypeAssertionsES5_4.errors.txt @@ -0,0 +1,7 @@ +tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_4.ts(1,23): error TS2304: Cannot find name 'foo'. + + +==== tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_4.ts (1 errors) ==== + var { x } = foo(); + ~~~ +!!! error TS2304: Cannot find name 'foo'. \ No newline at end of file diff --git a/tests/baselines/reference/destructuringTypeAssertionsES5_4.js b/tests/baselines/reference/destructuringTypeAssertionsES5_4.js new file mode 100644 index 00000000000..66a3e89c9b0 --- /dev/null +++ b/tests/baselines/reference/destructuringTypeAssertionsES5_4.js @@ -0,0 +1,5 @@ +//// [destructuringTypeAssertionsES5_4.ts] +var { x } = foo(); + +//// [destructuringTypeAssertionsES5_4.js] +var x = foo().x; diff --git a/tests/baselines/reference/destructuringTypeAssertionsES5_5.js b/tests/baselines/reference/destructuringTypeAssertionsES5_5.js new file mode 100644 index 00000000000..a51ac02af77 --- /dev/null +++ b/tests/baselines/reference/destructuringTypeAssertionsES5_5.js @@ -0,0 +1,5 @@ +//// [destructuringTypeAssertionsES5_5.ts] +var { x } = 0; + +//// [destructuringTypeAssertionsES5_5.js] +var x = (0).x; diff --git a/tests/baselines/reference/destructuringTypeAssertionsES5_5.symbols b/tests/baselines/reference/destructuringTypeAssertionsES5_5.symbols new file mode 100644 index 00000000000..d8e335f3e73 --- /dev/null +++ b/tests/baselines/reference/destructuringTypeAssertionsES5_5.symbols @@ -0,0 +1,4 @@ +=== tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_5.ts === +var { x } = 0; +>x : Symbol(x, Decl(destructuringTypeAssertionsES5_5.ts, 0, 5)) + diff --git a/tests/baselines/reference/destructuringTypeAssertionsES5_5.types b/tests/baselines/reference/destructuringTypeAssertionsES5_5.types new file mode 100644 index 00000000000..a7111cc4361 --- /dev/null +++ b/tests/baselines/reference/destructuringTypeAssertionsES5_5.types @@ -0,0 +1,6 @@ +=== tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_5.ts === +var { x } = 0; +>x : any +>0 : any +>0 : number + diff --git a/tests/baselines/reference/destructuringTypeAssertionsES5_6.errors.txt b/tests/baselines/reference/destructuringTypeAssertionsES5_6.errors.txt new file mode 100644 index 00000000000..9a27c4f47ab --- /dev/null +++ b/tests/baselines/reference/destructuringTypeAssertionsES5_6.errors.txt @@ -0,0 +1,7 @@ +tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_6.ts(1,22): error TS2304: Cannot find name 'Foo'. + + +==== tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_6.ts (1 errors) ==== + var { x } = new Foo; + ~~~ +!!! error TS2304: Cannot find name 'Foo'. \ No newline at end of file diff --git a/tests/baselines/reference/destructuringTypeAssertionsES5_6.js b/tests/baselines/reference/destructuringTypeAssertionsES5_6.js new file mode 100644 index 00000000000..01fd78f44e9 --- /dev/null +++ b/tests/baselines/reference/destructuringTypeAssertionsES5_6.js @@ -0,0 +1,5 @@ +//// [destructuringTypeAssertionsES5_6.ts] +var { x } = new Foo; + +//// [destructuringTypeAssertionsES5_6.js] +var x = (new Foo).x; diff --git a/tests/baselines/reference/destructuringTypeAssertionsES5_7.errors.txt b/tests/baselines/reference/destructuringTypeAssertionsES5_7.errors.txt new file mode 100644 index 00000000000..984f6a1dbb4 --- /dev/null +++ b/tests/baselines/reference/destructuringTypeAssertionsES5_7.errors.txt @@ -0,0 +1,7 @@ +tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_7.ts(1,27): error TS2304: Cannot find name 'Foo'. + + +==== tests/cases/conformance/es6/destructuring/destructuringTypeAssertionsES5_7.ts (1 errors) ==== + var { x } = new Foo; + ~~~ +!!! error TS2304: Cannot find name 'Foo'. \ No newline at end of file diff --git a/tests/baselines/reference/destructuringTypeAssertionsES5_7.js b/tests/baselines/reference/destructuringTypeAssertionsES5_7.js new file mode 100644 index 00000000000..78492eefc28 --- /dev/null +++ b/tests/baselines/reference/destructuringTypeAssertionsES5_7.js @@ -0,0 +1,5 @@ +//// [destructuringTypeAssertionsES5_7.ts] +var { x } = new Foo; + +//// [destructuringTypeAssertionsES5_7.js] +var x = (new Foo).x; From e940fdc534f0c8de8794274a84264efe67299c57 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Wed, 3 Jun 2015 17:34:56 -0700 Subject: [PATCH 4/4] Don't use innerExpression in parenthesizeForAccess --- src/compiler/emitter.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 5a0db87d409..bf0aef74455 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1646,9 +1646,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { function parenthesizeForAccess(expr: Expression): LeftHandSideExpression { // When diagnosing whether the expression needs parentheses, the decision should be based // on the innermost expression in a chain of nested type assertions. - let innerExpression = expr; - while (innerExpression.kind === SyntaxKind.TypeAssertionExpression) { - innerExpression = (innerExpression).expression; + while (expr.kind === SyntaxKind.TypeAssertionExpression) { + expr = (expr).expression; } // isLeftHandSideExpression is almost the correct criterion for when it is not necessary @@ -1659,9 +1658,9 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { // NumberLiteral // 1.x -> not the same as (1).x // - if (isLeftHandSideExpression(innerExpression) && - innerExpression.kind !== SyntaxKind.NewExpression && - innerExpression.kind !== SyntaxKind.NumericLiteral) { + if (isLeftHandSideExpression(expr) && + expr.kind !== SyntaxKind.NewExpression && + expr.kind !== SyntaxKind.NumericLiteral) { return expr; }