Skip to content

Commit 555ef73

Browse files
keerthana1212kekanakamssandersn
authored
Adding Diagnostic message for missing ']' and ')' in Array literal and conditional statements (microsoft#40884)
* Adding Diagnostic message for missing ']' in Array literal * revert change on parseArrayBindingPattern * Adding diagnostic message for if, while, do and with statements * Extract parseExpectMatchingBrackets Co-authored-by: Keerthana Kanakaraju <[email protected]> Co-authored-by: Nathan Shively-Sanders <[email protected]>
1 parent 294a5a7 commit 555ef73

20 files changed

+245
-17
lines changed

src/compiler/diagnosticMessages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"category": "Error",
1616
"code": 1006
1717
},
18-
"The parser expected to find a '}' to match the '{' token here.": {
18+
"The parser expected to find a '{1}' to match the '{0}' token here.": {
1919
"category": "Error",
2020
"code": 1007
2121
},

src/compiler/parser.ts

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,6 +1542,20 @@ namespace ts {
15421542
return false;
15431543
}
15441544

1545+
function parseExpectedMatchingBrackets(openKind: SyntaxKind, closeKind: SyntaxKind, openPosition: number) {
1546+
if (!parseExpected(closeKind)) {
1547+
const lastError = lastOrUndefined(parseDiagnostics);
1548+
if (lastError && lastError.code === Diagnostics._0_expected.code) {
1549+
addRelatedInfo(
1550+
lastError,
1551+
createDetachedDiagnostic(fileName, openPosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, tokenToString(openKind), tokenToString(closeKind))
1552+
);
1553+
}
1554+
return false;
1555+
}
1556+
return true;
1557+
}
1558+
15451559
function parseOptional(t: SyntaxKind): boolean {
15461560
if (token() === t) {
15471561
nextToken();
@@ -5426,10 +5440,11 @@ namespace ts {
54265440

54275441
function parseArrayLiteralExpression(): ArrayLiteralExpression {
54285442
const pos = getNodePos();
5443+
const openBracketPosition = scanner.getTokenPos();
54295444
parseExpected(SyntaxKind.OpenBracketToken);
54305445
const multiLine = scanner.hasPrecedingLineBreak();
54315446
const elements = parseDelimitedList(ParsingContext.ArrayLiteralMembers, parseArgumentOrArrayLiteralElement);
5432-
parseExpected(SyntaxKind.CloseBracketToken);
5447+
parseExpectedMatchingBrackets(SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken, openBracketPosition);
54335448
return finishNode(factory.createArrayLiteralExpression(elements, multiLine), pos);
54345449
}
54355450

@@ -5503,7 +5518,7 @@ namespace ts {
55035518
if (lastError && lastError.code === Diagnostics._0_expected.code) {
55045519
addRelatedInfo(
55055520
lastError,
5506-
createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_to_match_the_token_here)
5521+
createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, tokenToString(SyntaxKind.OpenBraceToken), tokenToString(SyntaxKind.CloseBraceToken))
55075522
);
55085523
}
55095524
}
@@ -5591,15 +5606,7 @@ namespace ts {
55915606
if (parseExpected(SyntaxKind.OpenBraceToken, diagnosticMessage) || ignoreMissingOpenBrace) {
55925607
const multiLine = scanner.hasPrecedingLineBreak();
55935608
const statements = parseList(ParsingContext.BlockStatements, parseStatement);
5594-
if (!parseExpected(SyntaxKind.CloseBraceToken)) {
5595-
const lastError = lastOrUndefined(parseDiagnostics);
5596-
if (lastError && lastError.code === Diagnostics._0_expected.code) {
5597-
addRelatedInfo(
5598-
lastError,
5599-
createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_to_match_the_token_here)
5600-
);
5601-
}
5602-
}
5609+
parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBracePosition);
56035610
return finishNode(factory.createBlock(statements, multiLine), pos);
56045611
}
56055612
else {
@@ -5647,9 +5654,10 @@ namespace ts {
56475654
function parseIfStatement(): IfStatement {
56485655
const pos = getNodePos();
56495656
parseExpected(SyntaxKind.IfKeyword);
5657+
const openParenPosition = scanner.getTokenPos();
56505658
parseExpected(SyntaxKind.OpenParenToken);
56515659
const expression = allowInAnd(parseExpression);
5652-
parseExpected(SyntaxKind.CloseParenToken);
5660+
parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenPosition);
56535661
const thenStatement = parseStatement();
56545662
const elseStatement = parseOptional(SyntaxKind.ElseKeyword) ? parseStatement() : undefined;
56555663
return finishNode(factory.createIfStatement(expression, thenStatement, elseStatement), pos);
@@ -5660,9 +5668,10 @@ namespace ts {
56605668
parseExpected(SyntaxKind.DoKeyword);
56615669
const statement = parseStatement();
56625670
parseExpected(SyntaxKind.WhileKeyword);
5671+
const openParenPosition = scanner.getTokenPos();
56635672
parseExpected(SyntaxKind.OpenParenToken);
56645673
const expression = allowInAnd(parseExpression);
5665-
parseExpected(SyntaxKind.CloseParenToken);
5674+
parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenPosition);
56665675

56675676
// From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html
56685677
// 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in
@@ -5675,9 +5684,10 @@ namespace ts {
56755684
function parseWhileStatement(): WhileStatement {
56765685
const pos = getNodePos();
56775686
parseExpected(SyntaxKind.WhileKeyword);
5687+
const openParenPosition = scanner.getTokenPos();
56785688
parseExpected(SyntaxKind.OpenParenToken);
56795689
const expression = allowInAnd(parseExpression);
5680-
parseExpected(SyntaxKind.CloseParenToken);
5690+
parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenPosition);
56815691
const statement = parseStatement();
56825692
return finishNode(factory.createWhileStatement(expression, statement), pos);
56835693
}
@@ -5749,9 +5759,10 @@ namespace ts {
57495759
function parseWithStatement(): WithStatement {
57505760
const pos = getNodePos();
57515761
parseExpected(SyntaxKind.WithKeyword);
5762+
const openParenPosition = scanner.getTokenPos();
57525763
parseExpected(SyntaxKind.OpenParenToken);
57535764
const expression = allowInAnd(parseExpression);
5754-
parseExpected(SyntaxKind.CloseParenToken);
5765+
parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenPosition);
57555766
const statement = doInsideOfContext(NodeFlags.InWithStatement, parseStatement);
57565767
return finishNode(factory.createWithStatement(expression, statement), pos);
57575768
}

tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(261,1): error TS
121121
if (retValue != 0 ^= {
122122
~~
123123
!!! error TS1005: ')' expected.
124+
!!! related TS1007 tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts:22:20: The parser expected to find a ')' to match the '(' token here.
124125
~
125126

126127

@@ -504,6 +505,7 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(261,1): error TS
504505
!!! error TS1135: Argument expression expected.
505506
~
506507
!!! error TS1005: '(' expected.
508+
!!! related TS1007 tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts:257:33: The parser expected to find a ')' to match the '(' token here.
507509
~~~~~~
508510
!!! error TS2693: 'string' only refers to a type, but is being used as a value here.
509511
~~~

tests/baselines/reference/destructuringParameterDeclaration2.errors.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(
3939
!!! error TS2322: Type 'string' is not assignable to type 'number'.
4040
~
4141
!!! error TS1005: ',' expected.
42+
!!! related TS1007 tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts:7:4: The parser expected to find a ']' to match the '[' token here.
4243
a0([1, 2, [["world"]], "string"]); // Error
4344
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4445
!!! error TS2345: Argument of type '[number, number, string[][], string]' is not assignable to parameter of type '[number, number, string[][]]'.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
tests/cases/compiler/missingCloseBracketInArray.ts(1,48): error TS1005: ']' expected.
2+
3+
4+
==== tests/cases/compiler/missingCloseBracketInArray.ts (1 errors) ====
5+
var alphas:string[] = alphas = ["1","2","3","4"
6+
7+
!!! error TS1005: ']' expected.
8+
!!! related TS1007 tests/cases/compiler/missingCloseBracketInArray.ts:1:32: The parser expected to find a ']' to match the '[' token here.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
//// [missingCloseBracketInArray.ts]
2+
var alphas:string[] = alphas = ["1","2","3","4"
3+
4+
//// [missingCloseBracketInArray.js]
5+
var alphas = alphas = ["1", "2", "3", "4"];
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
=== tests/cases/compiler/missingCloseBracketInArray.ts ===
2+
var alphas:string[] = alphas = ["1","2","3","4"
3+
>alphas : Symbol(alphas, Decl(missingCloseBracketInArray.ts, 0, 3))
4+
>alphas : Symbol(alphas, Decl(missingCloseBracketInArray.ts, 0, 3))
5+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/compiler/missingCloseBracketInArray.ts ===
2+
var alphas:string[] = alphas = ["1","2","3","4"
3+
>alphas : string[]
4+
>alphas = ["1","2","3","4" : string[]
5+
>alphas : string[]
6+
>["1","2","3","4" : string[]
7+
>"1" : "1"
8+
>"2" : "2"
9+
>"3" : "3"
10+
>"4" : "4"
11+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
tests/cases/compiler/missingCloseParenStatements.ts(2,26): error TS1005: ')' expected.
2+
tests/cases/compiler/missingCloseParenStatements.ts(4,5): error TS1005: ')' expected.
3+
tests/cases/compiler/missingCloseParenStatements.ts(8,39): error TS1005: ')' expected.
4+
tests/cases/compiler/missingCloseParenStatements.ts(11,35): error TS1005: ')' expected.
5+
6+
7+
==== tests/cases/compiler/missingCloseParenStatements.ts (4 errors) ====
8+
var a1, a2, a3 = 0;
9+
if ( a1 && (a2 + a3 > 0) {
10+
~
11+
!!! error TS1005: ')' expected.
12+
!!! related TS1007 tests/cases/compiler/missingCloseParenStatements.ts:2:4: The parser expected to find a ')' to match the '(' token here.
13+
while( (a2 > 0) && a1
14+
{
15+
~
16+
!!! error TS1005: ')' expected.
17+
!!! related TS1007 tests/cases/compiler/missingCloseParenStatements.ts:3:10: The parser expected to find a ')' to match the '(' token here.
18+
do {
19+
var i = i + 1;
20+
a1 = a1 + i;
21+
with ((a2 + a3 > 0) && a1 {
22+
~
23+
!!! error TS1005: ')' expected.
24+
!!! related TS1007 tests/cases/compiler/missingCloseParenStatements.ts:8:18: The parser expected to find a ')' to match the '(' token here.
25+
console.log(x);
26+
}
27+
} while (i < 5 && (a1 > 5);
28+
~
29+
!!! error TS1005: ')' expected.
30+
!!! related TS1007 tests/cases/compiler/missingCloseParenStatements.ts:11:17: The parser expected to find a ')' to match the '(' token here.
31+
}
32+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//// [missingCloseParenStatements.ts]
2+
var a1, a2, a3 = 0;
3+
if ( a1 && (a2 + a3 > 0) {
4+
while( (a2 > 0) && a1
5+
{
6+
do {
7+
var i = i + 1;
8+
a1 = a1 + i;
9+
with ((a2 + a3 > 0) && a1 {
10+
console.log(x);
11+
}
12+
} while (i < 5 && (a1 > 5);
13+
}
14+
}
15+
16+
//// [missingCloseParenStatements.js]
17+
var a1, a2, a3 = 0;
18+
if (a1 && (a2 + a3 > 0)) {
19+
while ((a2 > 0) && a1) {
20+
do {
21+
var i = i + 1;
22+
a1 = a1 + i;
23+
with ((a2 + a3 > 0) && a1) {
24+
console.log(x);
25+
}
26+
} while (i < 5 && (a1 > 5));
27+
}
28+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
=== tests/cases/compiler/missingCloseParenStatements.ts ===
2+
var a1, a2, a3 = 0;
3+
>a1 : Symbol(a1, Decl(missingCloseParenStatements.ts, 0, 3))
4+
>a2 : Symbol(a2, Decl(missingCloseParenStatements.ts, 0, 7))
5+
>a3 : Symbol(a3, Decl(missingCloseParenStatements.ts, 0, 11))
6+
7+
if ( a1 && (a2 + a3 > 0) {
8+
>a1 : Symbol(a1, Decl(missingCloseParenStatements.ts, 0, 3))
9+
>a2 : Symbol(a2, Decl(missingCloseParenStatements.ts, 0, 7))
10+
>a3 : Symbol(a3, Decl(missingCloseParenStatements.ts, 0, 11))
11+
12+
while( (a2 > 0) && a1
13+
>a2 : Symbol(a2, Decl(missingCloseParenStatements.ts, 0, 7))
14+
>a1 : Symbol(a1, Decl(missingCloseParenStatements.ts, 0, 3))
15+
{
16+
do {
17+
var i = i + 1;
18+
>i : Symbol(i, Decl(missingCloseParenStatements.ts, 5, 15))
19+
>i : Symbol(i, Decl(missingCloseParenStatements.ts, 5, 15))
20+
21+
a1 = a1 + i;
22+
>a1 : Symbol(a1, Decl(missingCloseParenStatements.ts, 0, 3))
23+
>a1 : Symbol(a1, Decl(missingCloseParenStatements.ts, 0, 3))
24+
>i : Symbol(i, Decl(missingCloseParenStatements.ts, 5, 15))
25+
26+
with ((a2 + a3 > 0) && a1 {
27+
>a2 : Symbol(a2, Decl(missingCloseParenStatements.ts, 0, 7))
28+
>a3 : Symbol(a3, Decl(missingCloseParenStatements.ts, 0, 11))
29+
>a1 : Symbol(a1, Decl(missingCloseParenStatements.ts, 0, 3))
30+
31+
console.log(x);
32+
}
33+
} while (i < 5 && (a1 > 5);
34+
>i : Symbol(i, Decl(missingCloseParenStatements.ts, 5, 15))
35+
>a1 : Symbol(a1, Decl(missingCloseParenStatements.ts, 0, 3))
36+
}
37+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
=== tests/cases/compiler/missingCloseParenStatements.ts ===
2+
var a1, a2, a3 = 0;
3+
>a1 : any
4+
>a2 : any
5+
>a3 : number
6+
>0 : 0
7+
8+
if ( a1 && (a2 + a3 > 0) {
9+
>a1 && (a2 + a3 > 0) : boolean
10+
>a1 : any
11+
>(a2 + a3 > 0) : boolean
12+
>a2 + a3 > 0 : boolean
13+
>a2 + a3 : any
14+
>a2 : any
15+
>a3 : number
16+
>0 : 0
17+
18+
while( (a2 > 0) && a1
19+
>(a2 > 0) && a1 : any
20+
>(a2 > 0) : boolean
21+
>a2 > 0 : boolean
22+
>a2 : any
23+
>0 : 0
24+
>a1 : any
25+
{
26+
do {
27+
var i = i + 1;
28+
>i : any
29+
>i + 1 : any
30+
>i : any
31+
>1 : 1
32+
33+
a1 = a1 + i;
34+
>a1 = a1 + i : any
35+
>a1 : any
36+
>a1 + i : any
37+
>a1 : any
38+
>i : any
39+
40+
with ((a2 + a3 > 0) && a1 {
41+
>(a2 + a3 > 0) && a1 : any
42+
>(a2 + a3 > 0) : boolean
43+
>a2 + a3 > 0 : boolean
44+
>a2 + a3 : any
45+
>a2 : any
46+
>a3 : number
47+
>0 : 0
48+
>a1 : any
49+
50+
console.log(x);
51+
>console.log(x) : any
52+
>console.log : any
53+
>console : any
54+
>log : any
55+
>x : any
56+
}
57+
} while (i < 5 && (a1 > 5);
58+
>i < 5 && (a1 > 5) : boolean
59+
>i < 5 : boolean
60+
>i : any
61+
>5 : 5
62+
>(a1 > 5) : boolean
63+
>a1 > 5 : boolean
64+
>a1 : any
65+
>5 : 5
66+
}
67+
}

tests/baselines/reference/parserErrorRecoveryArrayLiteralExpression3.errors.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrayLiteralExpressions
88
var texCoords = [2, 2, 0.5000001192092895, 0.8749999 ; 403953552, 0.5000001192092895, 0.8749999403953552];
99
~
1010
!!! error TS1005: ',' expected.
11+
!!! related TS1007 tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrayLiteralExpressions/parserErrorRecoveryArrayLiteralExpression3.ts:1:17: The parser expected to find a ']' to match the '[' token here.
1112
~~~~~~~~~
1213
!!! error TS2695: Left side of comma operator is unused and has no side effects.
1314
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

tests/baselines/reference/parserErrorRecoveryIfStatement2.errors.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/IfStatements/parserErro
1111
}
1212
~
1313
!!! error TS1005: ')' expected.
14+
!!! related TS1007 tests/cases/conformance/parser/ecmascript5/ErrorRecovery/IfStatements/parserErrorRecoveryIfStatement2.ts:3:8: The parser expected to find a ')' to match the '(' token here.
1415
f2() {
1516
}
1617
f3() {

tests/baselines/reference/parserErrorRecoveryIfStatement3.errors.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/IfStatements/parserErro
1111
}
1212
~
1313
!!! error TS1005: ')' expected.
14+
!!! related TS1007 tests/cases/conformance/parser/ecmascript5/ErrorRecovery/IfStatements/parserErrorRecoveryIfStatement3.ts:3:8: The parser expected to find a ')' to match the '(' token here.
1415
f2() {
1516
}
1617
f3() {

tests/baselines/reference/reservedWords2.errors.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ tests/cases/compiler/reservedWords2.ts(12,17): error TS1138: Parameter declarati
4545
!!! error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.
4646
~
4747
!!! error TS1005: ')' expected.
48+
!!! related TS1007 tests/cases/compiler/reservedWords2.ts:1:14: The parser expected to find a ')' to match the '(' token here.
4849
import * as while from "foo"
4950

5051
!!! error TS2300: Duplicate identifier '(Missing)'.
@@ -58,6 +59,7 @@ tests/cases/compiler/reservedWords2.ts(12,17): error TS1138: Parameter declarati
5859
!!! error TS2304: Cannot find name 'from'.
5960
~~~~~
6061
!!! error TS1005: ')' expected.
62+
!!! related TS1007 tests/cases/compiler/reservedWords2.ts:2:20: The parser expected to find a ')' to match the '(' token here.
6163

6264
var typeof = 10;
6365
~~~~~~
@@ -103,6 +105,7 @@ tests/cases/compiler/reservedWords2.ts(12,17): error TS1138: Parameter declarati
103105
!!! error TS1005: ';' expected.
104106
~
105107
!!! error TS1005: '(' expected.
108+
!!! related TS1007 tests/cases/compiler/reservedWords2.ts:9:18: The parser expected to find a ')' to match the '(' token here.
106109
~
107110
!!! error TS1128: Declaration or statement expected.
108111
enum void {}

0 commit comments

Comments
 (0)