Skip to content

Commit

Permalink
Token hints for missing closing braces: classes, enums, jsx, modules,…
Browse files Browse the repository at this point in the history
… types

This commit adds token hints for missing close braces in

- Class definitions
- Enum definitions
- JSX expressions
- Module definitions (this includes augmentations and namespaces)
- Type member lists (this includes interfaces)

The token hint refers to the opening brace for which the parser expected
a corresponding closing brace.

Note that this commit *does not* update all occurences of an expectation
for a close brace to provide token hints. Constructs for which this
token hint is not provided include:

- Mapped types
- Switch statements
- Object binding patterns
- JSX spread attributes (`<div {...props}></div>`)
- JSDoc implements/augments tags (`/* @implements {SomeInterface} */`)

Part of #35597.
  • Loading branch information
Ayaz Hafiz committed Mar 20, 2020
1 parent 5e9c436 commit eb22100
Show file tree
Hide file tree
Showing 48 changed files with 9,541 additions and 7,967 deletions.
2 changes: 1 addition & 1 deletion src/compiler/diagnosticMessages.json
Expand Up @@ -15,7 +15,7 @@
"category": "Error",
"code": 1006
},
"The parser expected to find a '}' to match the '{' token here.": {
"The parser expected to find a '{0}' to match the '{1}' token here.": {
"category": "Error",
"code": 1007
},
Expand Down
17,174 changes: 9,217 additions & 7,957 deletions src/compiler/parser.ts

Large diffs are not rendered by default.

Expand Up @@ -10,6 +10,7 @@ tests/cases/compiler/classMemberWithMissingIdentifier.ts(3,1): error TS1128: Dec
!!! error TS1146: Declaration expected.
~
!!! error TS1005: ';' expected.
!!! related TS1007 tests/cases/compiler/classMemberWithMissingIdentifier.ts:1:9: The parser expected to find a '}' to match the '{' token here.
}
~
!!! error TS1128: Declaration or statement expected.
Expand Up @@ -14,6 +14,7 @@ tests/cases/compiler/classMemberWithMissingIdentifier2.ts(3,1): error TS1128: De
!!! error TS1146: Declaration expected.
~
!!! error TS1005: ';' expected.
!!! related TS1007 tests/cases/compiler/classMemberWithMissingIdentifier2.ts:1:9: The parser expected to find a '}' to match the '{' token here.
~
!!! error TS1005: ',' expected.
~~~~~~
Expand Down
Expand Up @@ -142,6 +142,7 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(261,1): error TS
if (retValue != 0) {
~~
!!! error TS1005: ',' expected.
!!! related TS1007 tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts:15:26: The parser expected to find a '}' to match the '{' token here.
~
!!! error TS1005: ';' expected.

Expand Down
Expand Up @@ -50,6 +50,7 @@ tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassS
!!! error TS2304: Cannot find name 'super'.
~
!!! error TS1005: ';' expected.
!!! related TS1007 tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts:7:28: The parser expected to find a '}' to match the '{' token here.
~
!!! error TS1109: Expression expected.
b() {
Expand Down
Expand Up @@ -17,4 +17,5 @@ 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:2:20: The parser expected to find a '}' to match the '{' token here.
!!! related TS1007 tests/cases/compiler/errorRecoveryWithDotFollowedByNamespaceKeyword.ts:1:13: The parser expected to find a '}' to match the '{' token here.
15 changes: 14 additions & 1 deletion tests/baselines/reference/jsxAndTypeAssertion.errors.txt
Expand Up @@ -21,9 +21,11 @@ tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(18,69): error TS1381: Unexpe
tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(18,76): error TS1381: Unexpected token. Did you mean `{'}'}` or `&rbrace;`?
tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(21,1): error TS1005: ':' expected.
tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(21,1): error TS1005: '</' expected.
tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(21,1): error TS1005: '</' expected.
tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(21,1): error TS1005: '</' expected.


==== tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx (23 errors) ====
==== tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx (25 errors) ====
declare var createElement: any;

class foo {}
Expand All @@ -36,6 +38,7 @@ tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(21,1): error TS1005: '</' ex
!!! error TS2582: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha`.
~
!!! error TS1005: '}' expected.
!!! related TS1007 tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx:6:11: The parser expected to find a '}' to match the '{' token here.
~
!!! error TS1381: Unexpected token. Did you mean `{'}'}` or `&rbrace;`?

Expand All @@ -50,6 +53,7 @@ tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(21,1): error TS1005: '</' ex
!!! error TS1381: Unexpected token. Did you mean `{'}'}` or `&rbrace;`?
~
!!! error TS1005: '}' expected.
!!! related TS1007 tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx:10:16: The parser expected to find a '}' to match the '{' token here.

x = <foo test={<foo>{}}>hello</foo>;
~
Expand All @@ -58,6 +62,7 @@ tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(21,1): error TS1005: '</' ex
!!! error TS1382: Unexpected token. Did you mean `{'>'}` or `&gt;`?
~
!!! error TS1005: '}' expected.
!!! related TS1007 tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx:12:15: The parser expected to find a '}' to match the '{' token here.

x = <foo test={<foo>{}}>hello{<foo>{}}</foo>;
~~~
Expand All @@ -70,6 +75,7 @@ tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(21,1): error TS1005: '</' ex
!!! error TS1381: Unexpected token. Did you mean `{'}'}` or `&rbrace;`?
~
!!! error TS1005: '}' expected.
!!! related TS1007 tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx:14:30: The parser expected to find a '}' to match the '{' token here.

x = <foo>x</foo>, x = <foo/>;

Expand All @@ -89,5 +95,12 @@ tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(21,1): error TS1005: '</' ex


!!! error TS1005: ':' expected.
!!! related TS1007 tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx:18:17: The parser expected to find a '}' to match the '{' token here.

!!! error TS1005: '</' expected.
!!! related TS1007 tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx:14:15: The parser expected to find a '}' to match the '{' token here.

!!! error TS1005: '</' expected.
!!! related TS1007 tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx:18:6: The parser expected to find a '}' to match the '{' token here.

!!! error TS1005: '</' expected.
Expand Up @@ -244,6 +244,7 @@ tests/cases/conformance/jsx/9.tsx(1,16): error TS1109: Expression expected.
<a>{"str";}</a>;
~
!!! error TS1005: '}' expected.
!!! related TS1007 tests/cases/conformance/jsx/20.tsx:1:4: The parser expected to find a '}' to match the '{' token here.
~
!!! error TS1381: Unexpected token. Did you mean `{'}'}` or `&rbrace;`?
==== tests/cases/conformance/jsx/21.tsx (1 errors) ====
Expand Down
@@ -0,0 +1,14 @@
tests/cases/compiler/missingCloseBraceInClassDeclaration.ts(7,1): error TS1005: '}' expected.


==== tests/cases/compiler/missingCloseBraceInClassDeclaration.ts (1 errors) ====
class TestCls {
prop = 0;
method() {
return this.prop;
}



!!! error TS1005: '}' expected.
!!! related TS1007 tests/cases/compiler/missingCloseBraceInClassDeclaration.ts:1:15: The parser expected to find a '}' to match the '{' token here.
19 changes: 19 additions & 0 deletions tests/baselines/reference/missingCloseBraceInClassDeclaration.js
@@ -0,0 +1,19 @@
//// [missingCloseBraceInClassDeclaration.ts]
class TestCls {
prop = 0;
method() {
return this.prop;
}



//// [missingCloseBraceInClassDeclaration.js]
var TestCls = /** @class */ (function () {
function TestCls() {
this.prop = 0;
}
TestCls.prototype.method = function () {
return this.prop;
};
return TestCls;
}());
@@ -0,0 +1,17 @@
=== tests/cases/compiler/missingCloseBraceInClassDeclaration.ts ===
class TestCls {
>TestCls : Symbol(TestCls, Decl(missingCloseBraceInClassDeclaration.ts, 0, 0))

prop = 0;
>prop : Symbol(TestCls.prop, Decl(missingCloseBraceInClassDeclaration.ts, 0, 15))

method() {
>method : Symbol(TestCls.method, Decl(missingCloseBraceInClassDeclaration.ts, 1, 11))

return this.prop;
>this.prop : Symbol(TestCls.prop, Decl(missingCloseBraceInClassDeclaration.ts, 0, 15))
>this : Symbol(TestCls, Decl(missingCloseBraceInClassDeclaration.ts, 0, 0))
>prop : Symbol(TestCls.prop, Decl(missingCloseBraceInClassDeclaration.ts, 0, 15))
}


@@ -0,0 +1,18 @@
=== tests/cases/compiler/missingCloseBraceInClassDeclaration.ts ===
class TestCls {
>TestCls : TestCls

prop = 0;
>prop : number
>0 : 0

method() {
>method : () => number

return this.prop;
>this.prop : number
>this : this
>prop : number
}


13 changes: 13 additions & 0 deletions tests/baselines/reference/missingCloseBraceInEnum.errors.txt
@@ -0,0 +1,13 @@
tests/cases/compiler/missingCloseBraceInEnum.ts(6,1): error TS1005: '}' expected.


==== tests/cases/compiler/missingCloseBraceInEnum.ts (1 errors) ====
enum Colors {
Red,
Green,
Blue,



!!! error TS1005: '}' expected.
!!! related TS1007 tests/cases/compiler/missingCloseBraceInEnum.ts:1:13: The parser expected to find a '}' to match the '{' token here.
15 changes: 15 additions & 0 deletions tests/baselines/reference/missingCloseBraceInEnum.js
@@ -0,0 +1,15 @@
//// [missingCloseBraceInEnum.ts]
enum Colors {
Red,
Green,
Blue,



//// [missingCloseBraceInEnum.js]
var Colors;
(function (Colors) {
Colors[Colors["Red"] = 0] = "Red";
Colors[Colors["Green"] = 1] = "Green";
Colors[Colors["Blue"] = 2] = "Blue";
})(Colors || (Colors = {}));
14 changes: 14 additions & 0 deletions tests/baselines/reference/missingCloseBraceInEnum.symbols
@@ -0,0 +1,14 @@
=== tests/cases/compiler/missingCloseBraceInEnum.ts ===
enum Colors {
>Colors : Symbol(Colors, Decl(missingCloseBraceInEnum.ts, 0, 0))

Red,
>Red : Symbol(Colors.Red, Decl(missingCloseBraceInEnum.ts, 0, 13))

Green,
>Green : Symbol(Colors.Green, Decl(missingCloseBraceInEnum.ts, 1, 6))

Blue,
>Blue : Symbol(Colors.Blue, Decl(missingCloseBraceInEnum.ts, 2, 8))


14 changes: 14 additions & 0 deletions tests/baselines/reference/missingCloseBraceInEnum.types
@@ -0,0 +1,14 @@
=== tests/cases/compiler/missingCloseBraceInEnum.ts ===
enum Colors {
>Colors : Colors

Red,
>Red : Colors.Red

Green,
>Green : Colors.Green

Blue,
>Blue : Colors.Blue


@@ -0,0 +1,18 @@
tests/cases/compiler/missingCloseBraceInJsxAttributeExpression.tsx(1,23): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
tests/cases/compiler/missingCloseBraceInJsxAttributeExpression.tsx(1,30): error TS1109: Expression expected.
tests/cases/compiler/missingCloseBraceInJsxAttributeExpression.tsx(1,31): error TS1109: Expression expected.
tests/cases/compiler/missingCloseBraceInJsxAttributeExpression.tsx(2,1): error TS1005: '}' expected.


==== tests/cases/compiler/missingCloseBraceInJsxAttributeExpression.tsx (4 errors) ====
let el = <input prop={'abc' />
~~~~~
!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
~
!!! error TS1109: Expression expected.

!!! error TS1109: Expression expected.


!!! error TS1005: '}' expected.
!!! related TS1007 tests/cases/compiler/missingCloseBraceInJsxAttributeExpression.tsx:1:22: The parser expected to find a '}' to match the '{' token here.
@@ -0,0 +1,7 @@
//// [missingCloseBraceInJsxAttributeExpression.tsx]
let el = <input prop={'abc' />


//// [missingCloseBraceInJsxAttributeExpression.jsx]
var el = <input prop={'abc' / >
}/>;
@@ -0,0 +1,5 @@
=== tests/cases/compiler/missingCloseBraceInJsxAttributeExpression.tsx ===
let el = <input prop={'abc' />
>el : Symbol(el, Decl(missingCloseBraceInJsxAttributeExpression.tsx, 0, 3))
>prop : Symbol(prop, Decl(missingCloseBraceInJsxAttributeExpression.tsx, 0, 15))

@@ -0,0 +1,13 @@
=== tests/cases/compiler/missingCloseBraceInJsxAttributeExpression.tsx ===
let el = <input prop={'abc' />
>el : any
><input prop={'abc' /> : any
>input : any
>prop : boolean
>'abc' /> : boolean
>'abc' / : number
>'abc' : "abc"
> : any

> : any

@@ -0,0 +1,9 @@
tests/cases/compiler/missingCloseBraceInJsxExpression.tsx(1,23): error TS1005: '}' expected.


==== tests/cases/compiler/missingCloseBraceInJsxExpression.tsx (1 errors) ====
let el = <div>{'hello'</div>
~~
!!! error TS1005: '}' expected.
!!! related TS1007 tests/cases/compiler/missingCloseBraceInJsxExpression.tsx:1:15: The parser expected to find a '}' to match the '{' token here.

6 changes: 6 additions & 0 deletions tests/baselines/reference/missingCloseBraceInJsxExpression.js
@@ -0,0 +1,6 @@
//// [missingCloseBraceInJsxExpression.tsx]
let el = <div>{'hello'</div>


//// [missingCloseBraceInJsxExpression.jsx]
var el = <div>{'hello'}</div>;
@@ -0,0 +1,4 @@
=== tests/cases/compiler/missingCloseBraceInJsxExpression.tsx ===
let el = <div>{'hello'</div>
>el : Symbol(el, Decl(missingCloseBraceInJsxExpression.tsx, 0, 3))

@@ -0,0 +1,8 @@
=== tests/cases/compiler/missingCloseBraceInJsxExpression.tsx ===
let el = <div>{'hello'</div>
>el : any
><div>{'hello'</div> : any
>div : any
>'hello' : "hello"
>div : any

@@ -0,0 +1,11 @@
tests/cases/compiler/missingCloseBraceInModuleBlock.ts(4,1): error TS1005: '}' expected.


==== tests/cases/compiler/missingCloseBraceInModuleBlock.ts (1 errors) ====
module "dummy" {
interface Dummy {}



!!! error TS1005: '}' expected.
!!! related TS1007 tests/cases/compiler/missingCloseBraceInModuleBlock.ts:1:16: The parser expected to find a '}' to match the '{' token here.
7 changes: 7 additions & 0 deletions tests/baselines/reference/missingCloseBraceInModuleBlock.js
@@ -0,0 +1,7 @@
//// [missingCloseBraceInModuleBlock.ts]
module "dummy" {
interface Dummy {}



//// [missingCloseBraceInModuleBlock.js]
@@ -0,0 +1,8 @@
=== tests/cases/compiler/missingCloseBraceInModuleBlock.ts ===
module "dummy" {
>"dummy" : Symbol("dummy", Decl(missingCloseBraceInModuleBlock.ts, 0, 0))

interface Dummy {}
>Dummy : Symbol(Dummy, Decl(missingCloseBraceInModuleBlock.ts, 0, 16))


@@ -0,0 +1,7 @@
=== tests/cases/compiler/missingCloseBraceInModuleBlock.ts ===
module "dummy" {
>"dummy" : typeof import("dummy")

interface Dummy {}


@@ -0,0 +1,11 @@
tests/cases/compiler/missingCloseBraceInTypeMemberList.ts(4,1): error TS1005: '}' expected.


==== tests/cases/compiler/missingCloseBraceInTypeMemberList.ts (1 errors) ====
type ITest = {
num: number;



!!! error TS1005: '}' expected.
!!! related TS1007 tests/cases/compiler/missingCloseBraceInTypeMemberList.ts:1:14: The parser expected to find a '}' to match the '{' token here.
@@ -0,0 +1,7 @@
//// [missingCloseBraceInTypeMemberList.ts]
type ITest = {
num: number;



//// [missingCloseBraceInTypeMemberList.js]
@@ -0,0 +1,8 @@
=== tests/cases/compiler/missingCloseBraceInTypeMemberList.ts ===
type ITest = {
>ITest : Symbol(ITest, Decl(missingCloseBraceInTypeMemberList.ts, 0, 0))

num: number;
>num : Symbol(num, Decl(missingCloseBraceInTypeMemberList.ts, 0, 14))


0 comments on commit eb22100

Please sign in to comment.