Skip to content

Commit

Permalink
Only issue matching token errors on non-dupe locations (#43460)
Browse files Browse the repository at this point in the history
* 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.

* Inline parseTokenForError, return undefined not false

* skip redundant undefined assignment

* address PR comments
  • Loading branch information
sandersn committed Mar 31, 2021
1 parent 5b7838e commit 76a2ae3
Show file tree
Hide file tree
Showing 40 changed files with 25 additions and 334 deletions.
53 changes: 22 additions & 31 deletions src/compiler/parser.ts
Expand Up @@ -1335,24 +1335,27 @@ namespace ts {
return inContext(NodeFlags.AwaitContext);
}

function parseErrorAtCurrentToken(message: DiagnosticMessage, arg0?: any): void {
parseErrorAt(scanner.getTokenPos(), scanner.getTextPos(), message, arg0);
function parseErrorAtCurrentToken(message: DiagnosticMessage, arg0?: any): DiagnosticWithDetachedLocation | undefined {
return parseErrorAt(scanner.getTokenPos(), scanner.getTextPos(), message, arg0);
}

function parseErrorAtPosition(start: number, length: number, message: DiagnosticMessage, arg0?: any): void {
function parseErrorAtPosition(start: number, length: number, message: DiagnosticMessage, arg0?: any): DiagnosticWithDetachedLocation | undefined {
// Don't report another error if it would just be at the same position as the last error.
const lastError = lastOrUndefined(parseDiagnostics);
let result: DiagnosticWithDetachedLocation | undefined;
if (!lastError || start !== lastError.start) {
parseDiagnostics.push(createDetachedDiagnostic(fileName, start, length, message, arg0));
result = createDetachedDiagnostic(fileName, start, length, message, arg0);
parseDiagnostics.push(result);
}

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

function parseErrorAt(start: number, end: number, message: DiagnosticMessage, arg0?: any): void {
parseErrorAtPosition(start, end - start, message, arg0);
function parseErrorAt(start: number, end: number, message: DiagnosticMessage, arg0?: any): DiagnosticWithDetachedLocation | undefined {
return parseErrorAtPosition(start, end - start, message, arg0);
}

function parseErrorAtRange(range: TextRange, message: DiagnosticMessage, arg0?: any): void {
Expand Down Expand Up @@ -1543,17 +1546,17 @@ namespace ts {
}

function parseExpectedMatchingBrackets(openKind: SyntaxKind, closeKind: SyntaxKind, openPosition: number) {
if (!parseExpected(closeKind)) {
const lastError = lastOrUndefined(parseDiagnostics);
if (lastError && lastError.code === Diagnostics._0_expected.code) {
addRelatedInfo(
lastError,
createDetachedDiagnostic(fileName, openPosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, tokenToString(openKind), tokenToString(closeKind))
);
}
return false;
if (token() === closeKind) {
nextToken();
return;
}
const lastError = parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(closeKind));
if (lastError) {
addRelatedInfo(
lastError,
createDetachedDiagnostic(fileName, openPosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, tokenToString(openKind), tokenToString(closeKind))
);
}
return true;
}

function parseOptional(t: SyntaxKind): boolean {
Expand Down Expand Up @@ -5513,15 +5516,7 @@ namespace ts {
parseExpected(SyntaxKind.OpenBraceToken);
const multiLine = scanner.hasPrecedingLineBreak();
const properties = parseDelimitedList(ParsingContext.ObjectLiteralMembers, parseObjectLiteralElement, /*considerSemicolonAsDelimiter*/ true);
if (!parseExpected(SyntaxKind.CloseBraceToken)) {
const lastError = lastOrUndefined(parseDiagnostics);
if (lastError && lastError.code === Diagnostics._0_expected.code) {
addRelatedInfo(
lastError,
createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, tokenToString(SyntaxKind.OpenBraceToken), tokenToString(SyntaxKind.CloseBraceToken))
);
}
}
parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBracePosition);
return finishNode(factory.createObjectLiteralExpression(properties, multiLine), pos);
}

Expand Down Expand Up @@ -7984,13 +7979,9 @@ namespace ts {
hasChildren = true;
if (child.kind === SyntaxKind.JSDocTypeTag) {
if (childTypeTag) {
parseErrorAtCurrentToken(Diagnostics.A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags);
const lastError = lastOrUndefined(parseDiagnostics);
const lastError = parseErrorAtCurrentToken(Diagnostics.A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags);
if (lastError) {
addRelatedInfo(
lastError,
createDetachedDiagnostic(fileName, 0, 0, Diagnostics.The_tag_was_first_specified_here)
);
addRelatedInfo(lastError, createDetachedDiagnostic(fileName, 0, 0, Diagnostics.The_tag_was_first_specified_here));
}
break;
}
Expand Down
Expand Up @@ -505,7 +505,6 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(261,1): error TS
!!! error TS1135: Argument expression expected.
~
!!! error TS1005: '(' expected.
!!! related TS1007 tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts:257:33: The parser expected to find a ')' to match the '(' token here.
~~~~~~
!!! error TS2693: 'string' only refers to a type, but is being used as a value here.
~~~
Expand Down
Expand Up @@ -39,7 +39,6 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(
!!! error TS2322: Type 'string' is not assignable to type 'number'.
~
!!! error TS1005: ',' expected.
!!! related TS1007 tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts:7:4: The parser expected to find a ']' to match the '[' token here.
a0([1, 2, [["world"]], "string"]); // Error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type '[number, number, string[][], string]' is not assignable to parameter of type '[number, number, string[][]]'.
Expand Down
Expand Up @@ -16,5 +16,4 @@ tests/cases/compiler/errorRecoveryWithDotFollowedByNamespaceKeyword.ts(9,2): err
}

!!! error TS1005: '}' expected.
!!! related TS1007 tests/cases/compiler/errorRecoveryWithDotFollowedByNamespaceKeyword.ts:3:19: The parser expected to find a '}' to match the '{' token here.
!!! related TS1007 tests/cases/compiler/errorRecoveryWithDotFollowedByNamespaceKeyword.ts:2:20: The parser expected to find a '}' to match the '{' token here.
!!! related TS1007 tests/cases/compiler/errorRecoveryWithDotFollowedByNamespaceKeyword.ts:3:19: The parser expected to find a '}' to match the '{' token here.
Expand Up @@ -32,7 +32,6 @@ tests/cases/conformance/classes/nestedClassDeclaration.ts(17,1): error TS1128: D
!!! error TS2304: Cannot find name 'C4'.
~
!!! error TS1005: ',' expected.
!!! related TS1007 tests/cases/conformance/classes/nestedClassDeclaration.ts:14:9: The parser expected to find a '}' to match the '{' token here.
}
}
~
Expand Down
Expand Up @@ -9,5 +9,4 @@ tests/cases/compiler/objectLiteralWithSemicolons4.ts(3,1): error TS1005: ',' exp
!!! error TS18004: No value exists in scope for the shorthand property 'a'. Either declare one or provide an initializer.
;
~
!!! error TS1005: ',' expected.
!!! related TS1007 tests/cases/compiler/objectLiteralWithSemicolons4.ts:1:9: The parser expected to find a '}' to match the '{' token here.
!!! error TS1005: ',' expected.
Expand Up @@ -28,7 +28,6 @@ tests/cases/conformance/types/spread/objectSpreadNegativeParse.ts(4,20): error T
!!! error TS2304: Cannot find name 'matchMedia'.
~
!!! error TS1005: ',' expected.
!!! related TS1007 tests/cases/conformance/types/spread/objectSpreadNegativeParse.ts:3:10: The parser expected to find a '}' to match the '{' token here.
~
!!! error TS1128: Declaration or statement expected.
let o10 = { ...get x() { return 12; }};
Expand Down
Expand Up @@ -25,7 +25,6 @@ tests/cases/compiler/parseErrorIncorrectReturnToken.ts(12,1): error TS1128: Decl
m(n: number) => string {
~~
!!! error TS1005: '{' expected.
!!! related TS1007 tests/cases/compiler/parseErrorIncorrectReturnToken.ts:8:9: The parser expected to find a '}' to match the '{' token here.
~~~~~~
!!! error TS2693: 'string' only refers to a type, but is being used as a value here.
~
Expand Down
Expand Up @@ -8,7 +8,6 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrayLiteralExpressions
var texCoords = [2, 2, 0.5000001192092895, 0.8749999 ; 403953552, 0.5000001192092895, 0.8749999403953552];
~
!!! error TS1005: ',' expected.
!!! related TS1007 tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrayLiteralExpressions/parserErrorRecoveryArrayLiteralExpression3.ts:1:17: The parser expected to find a ']' to match the '[' token here.
~~~~~~~~~
!!! error TS2695: Left side of comma operator is unused and has no side effects.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
3 changes: 1 addition & 2 deletions tests/baselines/reference/parserFuzz1.errors.txt
Expand Up @@ -20,5 +20,4 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserFuzz1.ts(2,15): e
~~~~~~
!!! error TS1005: ';' expected.

!!! error TS1005: '{' expected.
!!! related TS1007 tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserFuzz1.ts:1:9: The parser expected to find a '}' to match the '{' token here.
!!! error TS1005: '{' expected.
1 change: 0 additions & 1 deletion tests/baselines/reference/reservedWords2.errors.txt
Expand Up @@ -105,7 +105,6 @@ tests/cases/compiler/reservedWords2.ts(12,17): error TS1138: Parameter declarati
!!! error TS1005: ';' expected.
~
!!! error TS1005: '(' expected.
!!! related TS1007 tests/cases/compiler/reservedWords2.ts:9:18: The parser expected to find a ')' to match the '(' token here.
~
!!! error TS1128: Declaration or statement expected.
enum void {}
Expand Down
Expand Up @@ -47,11 +47,6 @@ Output::
4 ;
  ~
src/src/main.ts:2:11
2 const a = {
   ~
The parser expected to find a '}' to match the '{' token here.
Found 1 error.
Expand Down Expand Up @@ -81,11 +76,6 @@ Output::
4 ;
  ~
src/src/main.ts:2:11
2 const a = {
   ~
The parser expected to find a '}' to match the '{' token here.
Found 1 error.
Expand Down
Expand Up @@ -47,11 +47,6 @@ Output::
4 ;
  ~
src/src/main.ts:2:11
2 const a = {
   ~
The parser expected to find a '}' to match the '{' token here.
Found 1 error.
Expand Down Expand Up @@ -81,11 +76,6 @@ Output::
4 ;
  ~
src/src/main.ts:2:11
2 const a = {
   ~
The parser expected to find a '}' to match the '{' token here.
Found 1 error.
Expand Down
Expand Up @@ -56,11 +56,6 @@ Output::
4 ;
  ~
src/main.ts:2:11
2 const a = {
   ~
The parser expected to find a '}' to match the '{' token here.
[12:00:35 AM] Found 1 error. Watching for file changes.
Expand Down Expand Up @@ -113,11 +108,6 @@ Output::
4 ;
  ~
src/main.ts:2:11
2 const a = {
   ~
The parser expected to find a '}' to match the '{' token here.
[12:00:42 AM] Found 1 error. Watching for file changes.
Expand Down
Expand Up @@ -56,11 +56,6 @@ Output::
4 ;
  ~
src/main.ts:2:11
2 const a = {
   ~
The parser expected to find a '}' to match the '{' token here.
[12:00:35 AM] Found 1 error. Watching for file changes.
Expand Down Expand Up @@ -113,11 +108,6 @@ Output::
4 ;
  ~
src/main.ts:2:11
2 const a = {
   ~
The parser expected to find a '}' to match the '{' token here.
[12:00:42 AM] Found 1 error. Watching for file changes.
Expand Down
Expand Up @@ -47,11 +47,6 @@ Output::
4 ;
  ~
src/src/main.ts:2:11
2 const a = {
   ~
The parser expected to find a '}' to match the '{' token here.
Found 1 error.
Expand Down Expand Up @@ -166,11 +161,6 @@ Output::
4 ;
  ~
src/src/main.ts:2:11
2 const a = {
   ~
The parser expected to find a '}' to match the '{' token here.
Found 1 error.
Expand Down
Expand Up @@ -43,11 +43,6 @@ Output::
4 ;
  ~
src/main.ts:2:11
2 const a = {
   ~
The parser expected to find a '}' to match the '{' token here.
[12:00:37 AM] Found 1 error. Watching for file changes.
Expand Down Expand Up @@ -186,11 +181,6 @@ Output::
4 ;
  ~
src/main.ts:2:11
2 const a = {
   ~
The parser expected to find a '}' to match the '{' token here.
[12:00:44 AM] Found 1 error. Watching for file changes.
Expand Down
Expand Up @@ -43,11 +43,6 @@ Output::
4 ;
  ~
src/main.ts:2:11
2 const a = {
   ~
The parser expected to find a '}' to match the '{' token here.
[12:00:32 AM] Found 1 error. Watching for file changes.
Expand Down Expand Up @@ -104,11 +99,6 @@ Output::
4 ;
  ~
src/main.ts:2:11
2 const a = {
   ~
The parser expected to find a '}' to match the '{' token here.
[12:00:37 AM] Found 1 error. Watching for file changes.
Expand Down
Expand Up @@ -43,11 +43,6 @@ Output::
4 ;
  ~
src/main.ts:2:11
2 const a = {
   ~
The parser expected to find a '}' to match the '{' token here.
[12:00:37 AM] Found 1 error. Watching for file changes.
Expand Down Expand Up @@ -187,11 +182,6 @@ Output::
4 ;
  ~
src/main.ts:2:11
2 const a = {
   ~
The parser expected to find a '}' to match the '{' token here.
[12:00:44 AM] Found 1 error. Watching for file changes.
Expand Down
Expand Up @@ -43,11 +43,6 @@ Output::
4 ;
  ~
src/main.ts:2:11
2 const a = {
   ~
The parser expected to find a '}' to match the '{' token here.
[12:00:32 AM] Found 1 error. Watching for file changes.
Expand Down Expand Up @@ -104,11 +99,6 @@ Output::
4 ;
  ~
src/main.ts:2:11
2 const a = {
   ~
The parser expected to find a '}' to match the '{' token here.
[12:00:37 AM] Found 1 error. Watching for file changes.
Expand Down

0 comments on commit 76a2ae3

Please sign in to comment.