Skip to content

Commit

Permalink
Error if assignment after block (#41115)
Browse files Browse the repository at this point in the history
* Error if assignment after block

* Update src/compiler/diagnosticMessages.json

Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com>

* Fix diags

* Error after block

Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com>
Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
  • Loading branch information
3 people committed Mar 31, 2021
1 parent 76a2ae3 commit 62f3ccd
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 10 deletions.
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Expand Up @@ -3308,6 +3308,10 @@
"category": "Error",
"code": 2808
},
"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.": {

This comment has been minimized.

Copy link
@jogo-

jogo- Apr 2, 2022

Typo/stutter: the the -> the

"category": "Error",
"code": 2809
},

"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
Expand Down
11 changes: 8 additions & 3 deletions src/compiler/parser.ts
Expand Up @@ -2109,8 +2109,7 @@ namespace ts {

while (!isListTerminator(kind)) {
if (isListElement(kind, /*inErrorRecovery*/ false)) {
const element = parseListElement(kind, parseElement);
list.push(element);
list.push(parseListElement(kind, parseElement));

continue;
}
Expand Down Expand Up @@ -5602,7 +5601,13 @@ namespace ts {
const multiLine = scanner.hasPrecedingLineBreak();
const statements = parseList(ParsingContext.BlockStatements, parseStatement);
parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBracePosition);
return finishNode(factory.createBlock(statements, multiLine), pos);
const result = finishNode(factory.createBlock(statements, multiLine), pos);
if (token() === SyntaxKind.EqualsToken) {
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);
nextToken();
}

return result;
}
else {
const statements = createMissingList<Statement>();
Expand Down
15 changes: 9 additions & 6 deletions tests/baselines/reference/assignmentLHSIsValue.errors.txt
Expand Up @@ -13,14 +13,15 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(2
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.
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.
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.
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(35,9): error TS1128: Declaration or statement expected.
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.
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.
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.
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(42,36): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(44,19): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(46,27): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(50,20): error TS1128: Declaration or statement expected.
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(51,11): error TS1005: ';' expected.
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.
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.
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(51,13): error TS1005: ';' expected.
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.
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.
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(58,2): error TS2631: Cannot assign to 'M' because it is a namespace.
Expand All @@ -38,7 +39,7 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(6
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.


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

Expand Down Expand Up @@ -105,7 +106,7 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(7
// object literals
{ a: 0} = value;
~
!!! error TS1128: Declaration or statement expected.
!!! 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.

// array literals
['', ''] = value;
Expand All @@ -132,9 +133,11 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(7
// function expression
function bar() { } = value;
~
!!! error TS1128: Declaration or statement expected.
!!! 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.
() => { } = value;
~
!!! 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.
~~~~~
!!! error TS1005: ';' expected.

// function calls
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/assignmentLHSIsValue.types
Expand Up @@ -146,7 +146,7 @@ function bar() { } = value;
>value : any

() => { } = value;
>() => { } : () => void
>() => { } = : () => void
>value : any

// function calls
Expand Down
27 changes: 27 additions & 0 deletions tests/baselines/reference/destructionAssignmentError.errors.txt
@@ -0,0 +1,27 @@
tests/cases/compiler/destructionAssignmentError.ts(6,3): error TS2695: Left side of comma operator is unused and has no side effects.
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.
tests/cases/compiler/destructionAssignmentError.ts(11,3): error TS2695: Left side of comma operator is unused and has no side effects.
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.


==== tests/cases/compiler/destructionAssignmentError.ts (4 errors) ====
declare function fn(): { a: 1, b: 2 }
let a: number;
let b: number;

({ a, b } = fn());
{ a, b } = fn();
~
!!! error TS2695: Left side of comma operator is unused and has no side effects.
~
!!! 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.

({ a, b } =
fn());

{ a, b }
~
!!! error TS2695: Left side of comma operator is unused and has no side effects.
= fn();
~
!!! 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 changes: 28 additions & 0 deletions tests/baselines/reference/destructionAssignmentError.js
@@ -0,0 +1,28 @@
//// [destructionAssignmentError.ts]
declare function fn(): { a: 1, b: 2 }
let a: number;
let b: number;

({ a, b } = fn());
{ a, b } = fn();

({ a, b } =
fn());

{ a, b }
= fn();

//// [destructionAssignmentError.js]
var _a, _b;
var a;
var b;
(_a = fn(), a = _a.a, b = _a.b);
{
a, b;
}
fn();
(_b = fn(), a = _b.a, b = _b.b);
{
a, b;
}
fn();
36 changes: 36 additions & 0 deletions tests/baselines/reference/destructionAssignmentError.symbols
@@ -0,0 +1,36 @@
=== tests/cases/compiler/destructionAssignmentError.ts ===
declare function fn(): { a: 1, b: 2 }
>fn : Symbol(fn, Decl(destructionAssignmentError.ts, 0, 0))
>a : Symbol(a, Decl(destructionAssignmentError.ts, 0, 24))
>b : Symbol(b, Decl(destructionAssignmentError.ts, 0, 30))

let a: number;
>a : Symbol(a, Decl(destructionAssignmentError.ts, 1, 3))

let b: number;
>b : Symbol(b, Decl(destructionAssignmentError.ts, 2, 3))

({ a, b } = fn());
>a : Symbol(a, Decl(destructionAssignmentError.ts, 4, 2))
>b : Symbol(b, Decl(destructionAssignmentError.ts, 4, 5))
>fn : Symbol(fn, Decl(destructionAssignmentError.ts, 0, 0))

{ a, b } = fn();
>a : Symbol(a, Decl(destructionAssignmentError.ts, 1, 3))
>b : Symbol(b, Decl(destructionAssignmentError.ts, 2, 3))
>fn : Symbol(fn, Decl(destructionAssignmentError.ts, 0, 0))

({ a, b } =
>a : Symbol(a, Decl(destructionAssignmentError.ts, 7, 2))
>b : Symbol(b, Decl(destructionAssignmentError.ts, 7, 5))

fn());
>fn : Symbol(fn, Decl(destructionAssignmentError.ts, 0, 0))

{ a, b }
>a : Symbol(a, Decl(destructionAssignmentError.ts, 1, 3))
>b : Symbol(b, Decl(destructionAssignmentError.ts, 2, 3))

= fn();
>fn : Symbol(fn, Decl(destructionAssignmentError.ts, 0, 0))

48 changes: 48 additions & 0 deletions tests/baselines/reference/destructionAssignmentError.types
@@ -0,0 +1,48 @@
=== tests/cases/compiler/destructionAssignmentError.ts ===
declare function fn(): { a: 1, b: 2 }
>fn : () => { a: 1; b: 2;}
>a : 1
>b : 2

let a: number;
>a : number

let b: number;
>b : number

({ a, b } = fn());
>({ a, b } = fn()) : { a: 1; b: 2; }
>{ a, b } = fn() : { a: 1; b: 2; }
>{ a, b } : { a: number; b: number; }
>a : number
>b : number
>fn() : { a: 1; b: 2; }
>fn : () => { a: 1; b: 2; }

{ a, b } = fn();
>a, b : number
>a : number
>b : number
>fn() : { a: 1; b: 2; }
>fn : () => { a: 1; b: 2; }

({ a, b } =
>({ a, b } =fn()) : { a: 1; b: 2; }
>{ a, b } =fn() : { a: 1; b: 2; }
>{ a, b } : { a: number; b: number; }
>a : number
>b : number

fn());
>fn() : { a: 1; b: 2; }
>fn : () => { a: 1; b: 2; }

{ a, b }
>a, b : number
>a : number
>b : number

= fn();
>fn() : { a: 1; b: 2; }
>fn : () => { a: 1; b: 2; }

12 changes: 12 additions & 0 deletions tests/cases/compiler/destructionAssignmentError.ts
@@ -0,0 +1,12 @@
declare function fn(): { a: 1, b: 2 }
let a: number;
let b: number;

({ a, b } = fn());
{ a, b } = fn();

({ a, b } =
fn());

{ a, b }
= fn();

0 comments on commit 62f3ccd

Please sign in to comment.