From b014e2b568836f816a019722cf2c689a6ac39f06 Mon Sep 17 00:00:00 2001 From: Sheon Han Date: Thu, 12 Mar 2020 18:52:02 -0400 Subject: [PATCH] Show token hints for missing closing braces (#36317) * Add error for missing brace in object literal * Add new baseline test * Update all affected tests --- src/compiler/parser.ts | 11 ++++++++++- .../missingCloseBraceInObjectLiteral.errors.txt | 12 ++++++++++++ .../missingCloseBraceInObjectLiteral.js | 13 +++++++++++++ .../missingCloseBraceInObjectLiteral.symbols | 13 +++++++++++++ .../missingCloseBraceInObjectLiteral.types | 17 +++++++++++++++++ .../reference/nestedClassDeclaration.errors.txt | 1 + .../objectLiteralWithSemicolons4.errors.txt | 3 ++- .../objectSpreadNegativeParse.errors.txt | 1 + .../parseErrorIncorrectReturnToken.errors.txt | 1 + ...arserErrorRecovery_ObjectLiteral2.errors.txt | 3 ++- ...arserErrorRecovery_ObjectLiteral3.errors.txt | 3 ++- ...arserErrorRecovery_ObjectLiteral4.errors.txt | 3 ++- ...arserErrorRecovery_ObjectLiteral5.errors.txt | 3 ++- .../missingCloseBraceInObjectLiteral.ts | 4 ++++ 14 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 tests/baselines/reference/missingCloseBraceInObjectLiteral.errors.txt create mode 100644 tests/baselines/reference/missingCloseBraceInObjectLiteral.js create mode 100644 tests/baselines/reference/missingCloseBraceInObjectLiteral.symbols create mode 100644 tests/baselines/reference/missingCloseBraceInObjectLiteral.types create mode 100644 tests/cases/compiler/missingCloseBraceInObjectLiteral.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 8434674fef3..06d0f22a2ad 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5110,13 +5110,22 @@ namespace ts { function parseObjectLiteralExpression(): ObjectLiteralExpression { const node = createNode(SyntaxKind.ObjectLiteralExpression); + const openBracePosition = scanner.getTokenPos(); parseExpected(SyntaxKind.OpenBraceToken); if (scanner.hasPrecedingLineBreak()) { node.multiLine = true; } node.properties = parseDelimitedList(ParsingContext.ObjectLiteralMembers, parseObjectLiteralElement, /*considerSemicolonAsDelimiter*/ true); - parseExpected(SyntaxKind.CloseBraceToken); + if (!parseExpected(SyntaxKind.CloseBraceToken)) { + const lastError = lastOrUndefined(parseDiagnostics); + if (lastError && lastError.code === Diagnostics._0_expected.code) { + addRelatedInfo( + lastError, + createFileDiagnostic(sourceFile, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_to_match_the_token_here) + ); + } + } return finishNode(node); } diff --git a/tests/baselines/reference/missingCloseBraceInObjectLiteral.errors.txt b/tests/baselines/reference/missingCloseBraceInObjectLiteral.errors.txt new file mode 100644 index 00000000000..436c8843c75 --- /dev/null +++ b/tests/baselines/reference/missingCloseBraceInObjectLiteral.errors.txt @@ -0,0 +1,12 @@ +tests/cases/compiler/missingCloseBraceInObjectLiteral.ts(5,1): error TS1005: '}' expected. + + +==== tests/cases/compiler/missingCloseBraceInObjectLiteral.ts (1 errors) ==== + var foo = { + a: 'a', + b: 'b', + c: 'c' + + +!!! error TS1005: '}' expected. +!!! related TS1007 tests/cases/compiler/missingCloseBraceInObjectLiteral.ts:1:11: The parser expected to find a '}' to match the '{' token here. \ No newline at end of file diff --git a/tests/baselines/reference/missingCloseBraceInObjectLiteral.js b/tests/baselines/reference/missingCloseBraceInObjectLiteral.js new file mode 100644 index 00000000000..b79faf349e3 --- /dev/null +++ b/tests/baselines/reference/missingCloseBraceInObjectLiteral.js @@ -0,0 +1,13 @@ +//// [missingCloseBraceInObjectLiteral.ts] +var foo = { + a: 'a', + b: 'b', + c: 'c' + + +//// [missingCloseBraceInObjectLiteral.js] +var foo = { + a: 'a', + b: 'b', + c: 'c' +}; diff --git a/tests/baselines/reference/missingCloseBraceInObjectLiteral.symbols b/tests/baselines/reference/missingCloseBraceInObjectLiteral.symbols new file mode 100644 index 00000000000..a816ed464c6 --- /dev/null +++ b/tests/baselines/reference/missingCloseBraceInObjectLiteral.symbols @@ -0,0 +1,13 @@ +=== tests/cases/compiler/missingCloseBraceInObjectLiteral.ts === +var foo = { +>foo : Symbol(foo, Decl(missingCloseBraceInObjectLiteral.ts, 0, 3)) + + a: 'a', +>a : Symbol(a, Decl(missingCloseBraceInObjectLiteral.ts, 0, 11)) + + b: 'b', +>b : Symbol(b, Decl(missingCloseBraceInObjectLiteral.ts, 1, 11)) + + c: 'c' +>c : Symbol(c, Decl(missingCloseBraceInObjectLiteral.ts, 2, 11)) + diff --git a/tests/baselines/reference/missingCloseBraceInObjectLiteral.types b/tests/baselines/reference/missingCloseBraceInObjectLiteral.types new file mode 100644 index 00000000000..3aca7d03d2d --- /dev/null +++ b/tests/baselines/reference/missingCloseBraceInObjectLiteral.types @@ -0,0 +1,17 @@ +=== tests/cases/compiler/missingCloseBraceInObjectLiteral.ts === +var foo = { +>foo : { a: string; b: string; c: string; } +>{ a: 'a', b: 'b', c: 'c' : { a: string; b: string; c: string; } + + a: 'a', +>a : string +>'a' : "a" + + b: 'b', +>b : string +>'b' : "b" + + c: 'c' +>c : string +>'c' : "c" + diff --git a/tests/baselines/reference/nestedClassDeclaration.errors.txt b/tests/baselines/reference/nestedClassDeclaration.errors.txt index f897c38d681..5540ee02437 100644 --- a/tests/baselines/reference/nestedClassDeclaration.errors.txt +++ b/tests/baselines/reference/nestedClassDeclaration.errors.txt @@ -32,6 +32,7 @@ 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. } } ~ diff --git a/tests/baselines/reference/objectLiteralWithSemicolons4.errors.txt b/tests/baselines/reference/objectLiteralWithSemicolons4.errors.txt index 544bddafff2..651c0b66df7 100644 --- a/tests/baselines/reference/objectLiteralWithSemicolons4.errors.txt +++ b/tests/baselines/reference/objectLiteralWithSemicolons4.errors.txt @@ -9,4 +9,5 @@ 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. \ No newline at end of file +!!! error TS1005: ',' expected. +!!! related TS1007 tests/cases/compiler/objectLiteralWithSemicolons4.ts:1:9: The parser expected to find a '}' to match the '{' token here. \ No newline at end of file diff --git a/tests/baselines/reference/objectSpreadNegativeParse.errors.txt b/tests/baselines/reference/objectSpreadNegativeParse.errors.txt index b37200c4f02..692fb7617da 100644 --- a/tests/baselines/reference/objectSpreadNegativeParse.errors.txt +++ b/tests/baselines/reference/objectSpreadNegativeParse.errors.txt @@ -28,6 +28,7 @@ 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; }}; diff --git a/tests/baselines/reference/parseErrorIncorrectReturnToken.errors.txt b/tests/baselines/reference/parseErrorIncorrectReturnToken.errors.txt index 2cf728848e4..bc43cd5b776 100644 --- a/tests/baselines/reference/parseErrorIncorrectReturnToken.errors.txt +++ b/tests/baselines/reference/parseErrorIncorrectReturnToken.errors.txt @@ -25,6 +25,7 @@ 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. ~ diff --git a/tests/baselines/reference/parserErrorRecovery_ObjectLiteral2.errors.txt b/tests/baselines/reference/parserErrorRecovery_ObjectLiteral2.errors.txt index 05c6ba6c8d6..1b1cb56af70 100644 --- a/tests/baselines/reference/parserErrorRecovery_ObjectLiteral2.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_ObjectLiteral2.errors.txt @@ -14,4 +14,5 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserEr ~ !!! error TS1005: ':' expected. -!!! error TS1005: '}' expected. \ No newline at end of file +!!! error TS1005: '}' expected. +!!! related TS1007 tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral2.ts:1:9: The parser expected to find a '}' to match the '{' token here. \ No newline at end of file diff --git a/tests/baselines/reference/parserErrorRecovery_ObjectLiteral3.errors.txt b/tests/baselines/reference/parserErrorRecovery_ObjectLiteral3.errors.txt index 8f319f6dcd7..cfde9bcd8a3 100644 --- a/tests/baselines/reference/parserErrorRecovery_ObjectLiteral3.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_ObjectLiteral3.errors.txt @@ -11,4 +11,5 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserEr ~ !!! error TS1005: ':' expected. -!!! error TS1005: '}' expected. \ No newline at end of file +!!! error TS1005: '}' expected. +!!! related TS1007 tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral3.ts:1:9: The parser expected to find a '}' to match the '{' token here. \ No newline at end of file diff --git a/tests/baselines/reference/parserErrorRecovery_ObjectLiteral4.errors.txt b/tests/baselines/reference/parserErrorRecovery_ObjectLiteral4.errors.txt index 0f8415e9015..8b67b285eb7 100644 --- a/tests/baselines/reference/parserErrorRecovery_ObjectLiteral4.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_ObjectLiteral4.errors.txt @@ -11,4 +11,5 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserEr ~ !!! error TS1005: ':' expected. -!!! error TS1005: '}' expected. \ No newline at end of file +!!! error TS1005: '}' expected. +!!! related TS1007 tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral4.ts:1:9: The parser expected to find a '}' to match the '{' token here. \ No newline at end of file diff --git a/tests/baselines/reference/parserErrorRecovery_ObjectLiteral5.errors.txt b/tests/baselines/reference/parserErrorRecovery_ObjectLiteral5.errors.txt index 7f1f15d7c6d..3915b915e46 100644 --- a/tests/baselines/reference/parserErrorRecovery_ObjectLiteral5.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_ObjectLiteral5.errors.txt @@ -8,4 +8,5 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserEr ~ !!! error TS1005: ':' expected. -!!! error TS1005: '}' expected. \ No newline at end of file +!!! error TS1005: '}' expected. +!!! related TS1007 tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ObjectLiterals/parserErrorRecovery_ObjectLiteral5.ts:1:9: The parser expected to find a '}' to match the '{' token here. \ No newline at end of file diff --git a/tests/cases/compiler/missingCloseBraceInObjectLiteral.ts b/tests/cases/compiler/missingCloseBraceInObjectLiteral.ts new file mode 100644 index 00000000000..cd0a4294087 --- /dev/null +++ b/tests/cases/compiler/missingCloseBraceInObjectLiteral.ts @@ -0,0 +1,4 @@ +var foo = { + a: 'a', + b: 'b', + c: 'c'