Skip to content

Commit 62f3ccd

Browse files
KingwlDanielRosenwassersandersn
authored
Error if assignment after block (microsoft#41115)
* Error if assignment after block * Update src/compiler/diagnosticMessages.json Co-authored-by: Daniel Rosenwasser <[email protected]> * Fix diags * Error after block Co-authored-by: Daniel Rosenwasser <[email protected]> Co-authored-by: Nathan Shively-Sanders <[email protected]>
1 parent 76a2ae3 commit 62f3ccd

9 files changed

+173
-10
lines changed

Diff for: src/compiler/diagnosticMessages.json

+4
Original file line numberDiff line numberDiff line change
@@ -3308,6 +3308,10 @@
33083308
"category": "Error",
33093309
"code": 2808
33103310
},
3311+
"Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses.": {
3312+
"category": "Error",
3313+
"code": 2809
3314+
},
33113315

33123316
"Import declaration '{0}' is using private name '{1}'.": {
33133317
"category": "Error",

Diff for: src/compiler/parser.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -2109,8 +2109,7 @@ namespace ts {
21092109

21102110
while (!isListTerminator(kind)) {
21112111
if (isListElement(kind, /*inErrorRecovery*/ false)) {
2112-
const element = parseListElement(kind, parseElement);
2113-
list.push(element);
2112+
list.push(parseListElement(kind, parseElement));
21142113

21152114
continue;
21162115
}
@@ -5602,7 +5601,13 @@ namespace ts {
56025601
const multiLine = scanner.hasPrecedingLineBreak();
56035602
const statements = parseList(ParsingContext.BlockStatements, parseStatement);
56045603
parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBracePosition);
5605-
return finishNode(factory.createBlock(statements, multiLine), pos);
5604+
const result = finishNode(factory.createBlock(statements, multiLine), pos);
5605+
if (token() === SyntaxKind.EqualsToken) {
5606+
parseErrorAtCurrentToken(Diagnostics.Declaration_or_statement_expected_This_follows_a_block_of_statements_so_if_you_intended_to_write_a_destructuring_assignment_you_might_need_to_wrap_the_the_whole_assignment_in_parentheses);
5607+
nextToken();
5608+
}
5609+
5610+
return result;
56065611
}
56075612
else {
56085613
const statements = createMissingList<Statement>();

Diff for: tests/baselines/reference/assignmentLHSIsValue.errors.txt

+9-6
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(2
1313
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(30,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
1414
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(31,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
1515
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(32,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
16-
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(35,9): error TS1128: Declaration or statement expected.
16+
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(35,9): error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses.
1717
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(38,2): error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
1818
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(38,6): error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
1919
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(42,36): error TS1034: 'super' must be followed by an argument list or member access.
2020
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(44,19): error TS1034: 'super' must be followed by an argument list or member access.
2121
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(46,27): error TS1034: 'super' must be followed by an argument list or member access.
22-
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(50,20): error TS1128: Declaration or statement expected.
23-
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(51,11): error TS1005: ';' expected.
22+
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(50,20): error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses.
23+
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(51,11): error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses.
24+
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(51,13): error TS1005: ';' expected.
2425
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(54,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
2526
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(57,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
2627
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(58,2): error TS2631: Cannot assign to 'M' because it is a namespace.
@@ -38,7 +39,7 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(6
3839
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(70,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
3940

4041

41-
==== tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts (38 errors) ====
42+
==== tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts (39 errors) ====
4243
// expected error for all the LHS of assignments
4344
var value: any;
4445

@@ -105,7 +106,7 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(7
105106
// object literals
106107
{ a: 0} = value;
107108
~
108-
!!! error TS1128: Declaration or statement expected.
109+
!!! error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses.
109110

110111
// array literals
111112
['', ''] = value;
@@ -132,9 +133,11 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(7
132133
// function expression
133134
function bar() { } = value;
134135
~
135-
!!! error TS1128: Declaration or statement expected.
136+
!!! error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses.
136137
() => { } = value;
137138
~
139+
!!! error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses.
140+
~~~~~
138141
!!! error TS1005: ';' expected.
139142

140143
// function calls

Diff for: tests/baselines/reference/assignmentLHSIsValue.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ function bar() { } = value;
146146
>value : any
147147

148148
() => { } = value;
149-
>() => { } : () => void
149+
>() => { } = : () => void
150150
>value : any
151151

152152
// function calls
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
tests/cases/compiler/destructionAssignmentError.ts(6,3): error TS2695: Left side of comma operator is unused and has no side effects.
2+
tests/cases/compiler/destructionAssignmentError.ts(6,10): error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses.
3+
tests/cases/compiler/destructionAssignmentError.ts(11,3): error TS2695: Left side of comma operator is unused and has no side effects.
4+
tests/cases/compiler/destructionAssignmentError.ts(12,1): error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses.
5+
6+
7+
==== tests/cases/compiler/destructionAssignmentError.ts (4 errors) ====
8+
declare function fn(): { a: 1, b: 2 }
9+
let a: number;
10+
let b: number;
11+
12+
({ a, b } = fn());
13+
{ a, b } = fn();
14+
~
15+
!!! error TS2695: Left side of comma operator is unused and has no side effects.
16+
~
17+
!!! error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses.
18+
19+
({ a, b } =
20+
fn());
21+
22+
{ a, b }
23+
~
24+
!!! error TS2695: Left side of comma operator is unused and has no side effects.
25+
= fn();
26+
~
27+
!!! error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses.
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//// [destructionAssignmentError.ts]
2+
declare function fn(): { a: 1, b: 2 }
3+
let a: number;
4+
let b: number;
5+
6+
({ a, b } = fn());
7+
{ a, b } = fn();
8+
9+
({ a, b } =
10+
fn());
11+
12+
{ a, b }
13+
= fn();
14+
15+
//// [destructionAssignmentError.js]
16+
var _a, _b;
17+
var a;
18+
var b;
19+
(_a = fn(), a = _a.a, b = _a.b);
20+
{
21+
a, b;
22+
}
23+
fn();
24+
(_b = fn(), a = _b.a, b = _b.b);
25+
{
26+
a, b;
27+
}
28+
fn();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
=== tests/cases/compiler/destructionAssignmentError.ts ===
2+
declare function fn(): { a: 1, b: 2 }
3+
>fn : Symbol(fn, Decl(destructionAssignmentError.ts, 0, 0))
4+
>a : Symbol(a, Decl(destructionAssignmentError.ts, 0, 24))
5+
>b : Symbol(b, Decl(destructionAssignmentError.ts, 0, 30))
6+
7+
let a: number;
8+
>a : Symbol(a, Decl(destructionAssignmentError.ts, 1, 3))
9+
10+
let b: number;
11+
>b : Symbol(b, Decl(destructionAssignmentError.ts, 2, 3))
12+
13+
({ a, b } = fn());
14+
>a : Symbol(a, Decl(destructionAssignmentError.ts, 4, 2))
15+
>b : Symbol(b, Decl(destructionAssignmentError.ts, 4, 5))
16+
>fn : Symbol(fn, Decl(destructionAssignmentError.ts, 0, 0))
17+
18+
{ a, b } = fn();
19+
>a : Symbol(a, Decl(destructionAssignmentError.ts, 1, 3))
20+
>b : Symbol(b, Decl(destructionAssignmentError.ts, 2, 3))
21+
>fn : Symbol(fn, Decl(destructionAssignmentError.ts, 0, 0))
22+
23+
({ a, b } =
24+
>a : Symbol(a, Decl(destructionAssignmentError.ts, 7, 2))
25+
>b : Symbol(b, Decl(destructionAssignmentError.ts, 7, 5))
26+
27+
fn());
28+
>fn : Symbol(fn, Decl(destructionAssignmentError.ts, 0, 0))
29+
30+
{ a, b }
31+
>a : Symbol(a, Decl(destructionAssignmentError.ts, 1, 3))
32+
>b : Symbol(b, Decl(destructionAssignmentError.ts, 2, 3))
33+
34+
= fn();
35+
>fn : Symbol(fn, Decl(destructionAssignmentError.ts, 0, 0))
36+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
=== tests/cases/compiler/destructionAssignmentError.ts ===
2+
declare function fn(): { a: 1, b: 2 }
3+
>fn : () => { a: 1; b: 2;}
4+
>a : 1
5+
>b : 2
6+
7+
let a: number;
8+
>a : number
9+
10+
let b: number;
11+
>b : number
12+
13+
({ a, b } = fn());
14+
>({ a, b } = fn()) : { a: 1; b: 2; }
15+
>{ a, b } = fn() : { a: 1; b: 2; }
16+
>{ a, b } : { a: number; b: number; }
17+
>a : number
18+
>b : number
19+
>fn() : { a: 1; b: 2; }
20+
>fn : () => { a: 1; b: 2; }
21+
22+
{ a, b } = fn();
23+
>a, b : number
24+
>a : number
25+
>b : number
26+
>fn() : { a: 1; b: 2; }
27+
>fn : () => { a: 1; b: 2; }
28+
29+
({ a, b } =
30+
>({ a, b } =fn()) : { a: 1; b: 2; }
31+
>{ a, b } =fn() : { a: 1; b: 2; }
32+
>{ a, b } : { a: number; b: number; }
33+
>a : number
34+
>b : number
35+
36+
fn());
37+
>fn() : { a: 1; b: 2; }
38+
>fn : () => { a: 1; b: 2; }
39+
40+
{ a, b }
41+
>a, b : number
42+
>a : number
43+
>b : number
44+
45+
= fn();
46+
>fn() : { a: 1; b: 2; }
47+
>fn : () => { a: 1; b: 2; }
48+

Diff for: tests/cases/compiler/destructionAssignmentError.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
declare function fn(): { a: 1, b: 2 }
2+
let a: number;
3+
let b: number;
4+
5+
({ a, b } = fn());
6+
{ a, b } = fn();
7+
8+
({ a, b } =
9+
fn());
10+
11+
{ a, b }
12+
= fn();

0 commit comments

Comments
 (0)