Skip to content

Commit c141447

Browse files
committed
Only issue matching token errors on non-dupe locations
Intead of unconditionally retrieving the last error and attaching a related span, `parseErrorAt` and friends now return the last error and return `false` when there is none. Also make one more place use parseExpectedMatchingBrackets that I missed last time.
1 parent 5b7838e commit c141447

File tree

40 files changed

+44
-333
lines changed

40 files changed

+44
-333
lines changed

src/compiler/parser.ts

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,24 +1335,30 @@ namespace ts {
13351335
return inContext(NodeFlags.AwaitContext);
13361336
}
13371337

1338-
function parseErrorAtCurrentToken(message: DiagnosticMessage, arg0?: any): void {
1339-
parseErrorAt(scanner.getTokenPos(), scanner.getTextPos(), message, arg0);
1338+
function parseErrorAtCurrentToken(message: DiagnosticMessage, arg0?: any): DiagnosticWithDetachedLocation | false {
1339+
return parseErrorAt(scanner.getTokenPos(), scanner.getTextPos(), message, arg0);
13401340
}
13411341

1342-
function parseErrorAtPosition(start: number, length: number, message: DiagnosticMessage, arg0?: any): void {
1342+
function parseErrorAtPosition(start: number, length: number, message: DiagnosticMessage, arg0?: any): DiagnosticWithDetachedLocation | false {
13431343
// Don't report another error if it would just be at the same position as the last error.
13441344
const lastError = lastOrUndefined(parseDiagnostics);
1345+
let result: DiagnosticWithDetachedLocation | false;
13451346
if (!lastError || start !== lastError.start) {
1346-
parseDiagnostics.push(createDetachedDiagnostic(fileName, start, length, message, arg0));
1347+
result = createDetachedDiagnostic(fileName, start, length, message, arg0)
1348+
parseDiagnostics.push(result);
1349+
}
1350+
else {
1351+
result = false;
13471352
}
13481353

13491354
// Mark that we've encountered an error. We'll set an appropriate bit on the next
13501355
// node we finish so that it can't be reused incrementally.
13511356
parseErrorBeforeNextFinishedNode = true;
1357+
return result
13521358
}
13531359

1354-
function parseErrorAt(start: number, end: number, message: DiagnosticMessage, arg0?: any): void {
1355-
parseErrorAtPosition(start, end - start, message, arg0);
1360+
function parseErrorAt(start: number, end: number, message: DiagnosticMessage, arg0?: any): DiagnosticWithDetachedLocation | false {
1361+
return parseErrorAtPosition(start, end - start, message, arg0);
13561362
}
13571363

13581364
function parseErrorAtRange(range: TextRange, message: DiagnosticMessage, arg0?: any): void {
@@ -1533,6 +1539,24 @@ namespace ts {
15331539
return false;
15341540
}
15351541

1542+
/** Like parseExpected, but returns true=succeed, diagnostic=fail, false=fail+failed to log error */
1543+
function parseTokenForError(kind: SyntaxKind, diagnosticMessage?: DiagnosticMessage, shouldAdvance = true): DiagnosticWithDetachedLocation | boolean {
1544+
if (token() === kind) {
1545+
if (shouldAdvance) {
1546+
nextToken();
1547+
}
1548+
return true;
1549+
}
1550+
1551+
// Report specific message if provided with one. Otherwise, report generic fallback message.
1552+
if (diagnosticMessage) {
1553+
return parseErrorAtCurrentToken(diagnosticMessage);
1554+
}
1555+
else {
1556+
return parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(kind));
1557+
}
1558+
}
1559+
15361560
function parseExpectedJSDoc(kind: JSDocSyntaxKind) {
15371561
if (token() === kind) {
15381562
nextTokenJSDoc();
@@ -1543,17 +1567,16 @@ namespace ts {
15431567
}
15441568

15451569
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-
}
1570+
const lastError = parseTokenForError(closeKind);
1571+
if (typeof lastError === 'boolean')
1572+
return lastError
1573+
else {
1574+
addRelatedInfo(
1575+
lastError,
1576+
createDetachedDiagnostic(fileName, openPosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, tokenToString(openKind), tokenToString(closeKind))
1577+
);
15541578
return false;
15551579
}
1556-
return true;
15571580
}
15581581

15591582
function parseOptional(t: SyntaxKind): boolean {
@@ -5513,15 +5536,7 @@ namespace ts {
55135536
parseExpected(SyntaxKind.OpenBraceToken);
55145537
const multiLine = scanner.hasPrecedingLineBreak();
55155538
const properties = parseDelimitedList(ParsingContext.ObjectLiteralMembers, parseObjectLiteralElement, /*considerSemicolonAsDelimiter*/ true);
5516-
if (!parseExpected(SyntaxKind.CloseBraceToken)) {
5517-
const lastError = lastOrUndefined(parseDiagnostics);
5518-
if (lastError && lastError.code === Diagnostics._0_expected.code) {
5519-
addRelatedInfo(
5520-
lastError,
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))
5522-
);
5523-
}
5524-
}
5539+
parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBracePosition);
55255540
return finishNode(factory.createObjectLiteralExpression(properties, multiLine), pos);
55265541
}
55275542

@@ -7984,13 +7999,9 @@ namespace ts {
79847999
hasChildren = true;
79858000
if (child.kind === SyntaxKind.JSDocTypeTag) {
79868001
if (childTypeTag) {
7987-
parseErrorAtCurrentToken(Diagnostics.A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags);
7988-
const lastError = lastOrUndefined(parseDiagnostics);
8002+
const lastError = parseErrorAtCurrentToken(Diagnostics.A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags);
79898003
if (lastError) {
7990-
addRelatedInfo(
7991-
lastError,
7992-
createDetachedDiagnostic(fileName, 0, 0, Diagnostics.The_tag_was_first_specified_here)
7993-
);
8004+
addRelatedInfo(lastError, createDetachedDiagnostic(fileName, 0, 0, Diagnostics.The_tag_was_first_specified_here));
79948005
}
79958006
break;
79968007
}

tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,6 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(261,1): error TS
505505
!!! error TS1135: Argument expression expected.
506506
~
507507
!!! error TS1005: '(' expected.
508-
!!! related TS1007 tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts:257:33: The parser expected to find a ')' to match the '(' token here.
509508
~~~~~~
510509
!!! error TS2693: 'string' only refers to a type, but is being used as a value here.
511510
~~~

tests/baselines/reference/destructuringParameterDeclaration2.errors.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ 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.
4342
a0([1, 2, [["world"]], "string"]); // Error
4443
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4544
!!! error TS2345: Argument of type '[number, number, string[][], string]' is not assignable to parameter of type '[number, number, string[][]]'.

tests/baselines/reference/errorRecoveryWithDotFollowedByNamespaceKeyword.errors.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,4 @@ tests/cases/compiler/errorRecoveryWithDotFollowedByNamespaceKeyword.ts(9,2): err
1616
}
1717

1818
!!! error TS1005: '}' expected.
19-
!!! related TS1007 tests/cases/compiler/errorRecoveryWithDotFollowedByNamespaceKeyword.ts:3:19: The parser expected to find a '}' to match the '{' token here.
20-
!!! related TS1007 tests/cases/compiler/errorRecoveryWithDotFollowedByNamespaceKeyword.ts:2:20: The parser expected to find a '}' to match the '{' token here.
19+
!!! related TS1007 tests/cases/compiler/errorRecoveryWithDotFollowedByNamespaceKeyword.ts:3:19: The parser expected to find a '}' to match the '{' token here.

tests/baselines/reference/nestedClassDeclaration.errors.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ tests/cases/conformance/classes/nestedClassDeclaration.ts(17,1): error TS1128: D
3232
!!! error TS2304: Cannot find name 'C4'.
3333
~
3434
!!! error TS1005: ',' expected.
35-
!!! related TS1007 tests/cases/conformance/classes/nestedClassDeclaration.ts:14:9: The parser expected to find a '}' to match the '{' token here.
3635
}
3736
}
3837
~

tests/baselines/reference/objectLiteralWithSemicolons4.errors.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,4 @@ tests/cases/compiler/objectLiteralWithSemicolons4.ts(3,1): error TS1005: ',' exp
99
!!! error TS18004: No value exists in scope for the shorthand property 'a'. Either declare one or provide an initializer.
1010
;
1111
~
12-
!!! error TS1005: ',' expected.
13-
!!! related TS1007 tests/cases/compiler/objectLiteralWithSemicolons4.ts:1:9: The parser expected to find a '}' to match the '{' token here.
12+
!!! error TS1005: ',' expected.

tests/baselines/reference/objectSpreadNegativeParse.errors.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ tests/cases/conformance/types/spread/objectSpreadNegativeParse.ts(4,20): error T
2828
!!! error TS2304: Cannot find name 'matchMedia'.
2929
~
3030
!!! error TS1005: ',' expected.
31-
!!! related TS1007 tests/cases/conformance/types/spread/objectSpreadNegativeParse.ts:3:10: The parser expected to find a '}' to match the '{' token here.
3231
~
3332
!!! error TS1128: Declaration or statement expected.
3433
let o10 = { ...get x() { return 12; }};

tests/baselines/reference/parseErrorIncorrectReturnToken.errors.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ tests/cases/compiler/parseErrorIncorrectReturnToken.ts(12,1): error TS1128: Decl
2525
m(n: number) => string {
2626
~~
2727
!!! error TS1005: '{' expected.
28-
!!! related TS1007 tests/cases/compiler/parseErrorIncorrectReturnToken.ts:8:9: The parser expected to find a '}' to match the '{' token here.
2928
~~~~~~
3029
!!! error TS2693: 'string' only refers to a type, but is being used as a value here.
3130
~

tests/baselines/reference/parserErrorRecoveryArrayLiteralExpression3.errors.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ 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.
1211
~~~~~~~~~
1312
!!! error TS2695: Left side of comma operator is unused and has no side effects.
1413
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

tests/baselines/reference/parserFuzz1.errors.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,4 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserFuzz1.ts(2,15): e
2020
~~~~~~
2121
!!! error TS1005: ';' expected.
2222

23-
!!! error TS1005: '{' expected.
24-
!!! related TS1007 tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserFuzz1.ts:1:9: The parser expected to find a '}' to match the '{' token here.
23+
!!! error TS1005: '{' expected.

tests/baselines/reference/reservedWords2.errors.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ tests/cases/compiler/reservedWords2.ts(12,17): error TS1138: Parameter declarati
105105
!!! error TS1005: ';' expected.
106106
~
107107
!!! error TS1005: '(' expected.
108-
!!! related TS1007 tests/cases/compiler/reservedWords2.ts:9:18: The parser expected to find a ')' to match the '(' token here.
109108
~
110109
!!! error TS1128: Declaration or statement expected.
111110
enum void {}

tests/baselines/reference/tsbuild/noEmitOnError/initial-build/syntax-errors-with-incremental.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,6 @@ Output::
4747
4 ;
4848
  ~
4949

50-
src/src/main.ts:2:11
51-
2 const a = {
52-
   ~
53-
The parser expected to find a '}' to match the '{' token here.
54-
5550

5651
Found 1 error.
5752

@@ -81,11 +76,6 @@ Output::
8176
4 ;
8277
  ~
8378

84-
src/src/main.ts:2:11
85-
2 const a = {
86-
   ~
87-
The parser expected to find a '}' to match the '{' token here.
88-
8979

9080
Found 1 error.
9181

tests/baselines/reference/tsbuild/noEmitOnError/initial-build/syntax-errors.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,6 @@ Output::
4747
4 ;
4848
  ~
4949

50-
src/src/main.ts:2:11
51-
2 const a = {
52-
   ~
53-
The parser expected to find a '}' to match the '{' token here.
54-
5550

5651
Found 1 error.
5752

@@ -81,11 +76,6 @@ Output::
8176
4 ;
8277
  ~
8378

84-
src/src/main.ts:2:11
85-
2 const a = {
86-
   ~
87-
The parser expected to find a '}' to match the '{' token here.
88-
8979

9080
Found 1 error.
9181

tests/baselines/reference/tsbuild/watchMode/noEmitOnError/does-not-emit-any-files-on-error-with-incremental.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,6 @@ Output::
5656
4 ;
5757
  ~
5858

59-
src/main.ts:2:11
60-
2 const a = {
61-
   ~
62-
The parser expected to find a '}' to match the '{' token here.
63-
6459
[12:00:35 AM] Found 1 error. Watching for file changes.
6560

6661

@@ -113,11 +108,6 @@ Output::
113108
4 ;
114109
  ~
115110

116-
src/main.ts:2:11
117-
2 const a = {
118-
   ~
119-
The parser expected to find a '}' to match the '{' token here.
120-
121111
[12:00:42 AM] Found 1 error. Watching for file changes.
122112

123113

tests/baselines/reference/tsbuild/watchMode/noEmitOnError/does-not-emit-any-files-on-error.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,6 @@ Output::
5656
4 ;
5757
  ~
5858

59-
src/main.ts:2:11
60-
2 const a = {
61-
   ~
62-
The parser expected to find a '}' to match the '{' token here.
63-
6459
[12:00:35 AM] Found 1 error. Watching for file changes.
6560

6661

@@ -113,11 +108,6 @@ Output::
113108
4 ;
114109
  ~
115110

116-
src/main.ts:2:11
117-
2 const a = {
118-
   ~
119-
The parser expected to find a '}' to match the '{' token here.
120-
121111
[12:00:42 AM] Found 1 error. Watching for file changes.
122112

123113

tests/baselines/reference/tsc/incremental/initial-build/with-noEmitOnError-syntax-errors.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,6 @@ Output::
4747
4 ;
4848
  ~
4949

50-
src/src/main.ts:2:11
51-
2 const a = {
52-
   ~
53-
The parser expected to find a '}' to match the '{' token here.
54-
5550

5651
Found 1 error.
5752

@@ -166,11 +161,6 @@ Output::
166161
4 ;
167162
  ~
168163

169-
src/src/main.ts:2:11
170-
2 const a = {
171-
   ~
172-
The parser expected to find a '}' to match the '{' token here.
173-
174164

175165
Found 1 error.
176166

tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError-with-incremental.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,6 @@ Output::
4343
4 ;
4444
  ~
4545

46-
src/main.ts:2:11
47-
2 const a = {
48-
   ~
49-
The parser expected to find a '}' to match the '{' token here.
50-
5146
[12:00:37 AM] Found 1 error. Watching for file changes.
5247

5348

@@ -186,11 +181,6 @@ Output::
186181
4 ;
187182
  ~
188183

189-
src/main.ts:2:11
190-
2 const a = {
191-
   ~
192-
The parser expected to find a '}' to match the '{' token here.
193-
194184
[12:00:44 AM] Found 1 error. Watching for file changes.
195185

196186

tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,6 @@ Output::
4343
4 ;
4444
  ~
4545

46-
src/main.ts:2:11
47-
2 const a = {
48-
   ~
49-
The parser expected to find a '}' to match the '{' token here.
50-
5146
[12:00:32 AM] Found 1 error. Watching for file changes.
5247

5348

@@ -104,11 +99,6 @@ Output::
10499
4 ;
105100
  ~
106101

107-
src/main.ts:2:11
108-
2 const a = {
109-
   ~
110-
The parser expected to find a '}' to match the '{' token here.
111-
112102
[12:00:37 AM] Found 1 error. Watching for file changes.
113103

114104

tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependenciesAndD/with-noEmitOnError-with-incremental.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,6 @@ Output::
4343
4 ;
4444
  ~
4545

46-
src/main.ts:2:11
47-
2 const a = {
48-
   ~
49-
The parser expected to find a '}' to match the '{' token here.
50-
5146
[12:00:37 AM] Found 1 error. Watching for file changes.
5247

5348

@@ -187,11 +182,6 @@ Output::
187182
4 ;
188183
  ~
189184

190-
src/main.ts:2:11
191-
2 const a = {
192-
   ~
193-
The parser expected to find a '}' to match the '{' token here.
194-
195185
[12:00:44 AM] Found 1 error. Watching for file changes.
196186

197187

0 commit comments

Comments
 (0)