From ec9d70ed0d2dc16a2cf2db79edbe66ac94e410e7 Mon Sep 17 00:00:00 2001 From: gonza Date: Tue, 22 Oct 2019 23:50:44 -0300 Subject: [PATCH 1/2] Parse only modifiers of actual methods --- packages/babel-parser/src/parser/statement.js | 3 ++- .../fixtures/typescript/class/optional-async-error/input.js | 4 ++++ .../typescript/class/optional-async-error/options.json | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 packages/babel-parser/test/fixtures/typescript/class/optional-async-error/input.js create mode 100644 packages/babel-parser/test/fixtures/typescript/class/optional-async-error/options.json diff --git a/packages/babel-parser/src/parser/statement.js b/packages/babel-parser/src/parser/statement.js index 81e310debd7b..a251fea7610d 100644 --- a/packages/babel-parser/src/parser/statement.js +++ b/packages/babel-parser/src/parser/statement.js @@ -1349,7 +1349,8 @@ export default class StatementParser extends ExpressionParser { // Check the key is not a computed expression or string literal. const isSimple = key.type === "Identifier"; - this.parsePostMemberNameModifiers(publicMember); + // "async" should not be treated as normal porperty names + if (key.name !== "async") this.parsePostMemberNameModifiers(publicMember); if (this.isClassMethod()) { method.kind = "method"; diff --git a/packages/babel-parser/test/fixtures/typescript/class/optional-async-error/input.js b/packages/babel-parser/test/fixtures/typescript/class/optional-async-error/input.js new file mode 100644 index 000000000000..01d6018a50d2 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/class/optional-async-error/input.js @@ -0,0 +1,4 @@ +class B { } +class A extends B { + async? method(val: string): Promise; +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/class/optional-async-error/options.json b/packages/babel-parser/test/fixtures/typescript/class/optional-async-error/options.json new file mode 100644 index 000000000000..8dde42aa3f55 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/class/optional-async-error/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Unexpected token (3:9)" +} \ No newline at end of file From aa4305ca07c1c34dbf76610e3ba7218e184dfbc0 Mon Sep 17 00:00:00 2001 From: gonza Date: Tue, 29 Oct 2019 11:03:50 -0300 Subject: [PATCH 2/2] Throw question token if is used before the real name --- packages/babel-parser/src/parser/statement.js | 8 +- .../class/async-named-properties/input.ts | 4 + .../class/async-named-properties/output.json | 221 ++++++++++++++++++ 3 files changed, 231 insertions(+), 2 deletions(-) create mode 100644 packages/babel-parser/test/fixtures/typescript/class/async-named-properties/input.ts create mode 100644 packages/babel-parser/test/fixtures/typescript/class/async-named-properties/output.json diff --git a/packages/babel-parser/src/parser/statement.js b/packages/babel-parser/src/parser/statement.js index a251fea7610d..d926d51c1ef0 100644 --- a/packages/babel-parser/src/parser/statement.js +++ b/packages/babel-parser/src/parser/statement.js @@ -1348,9 +1348,9 @@ export default class StatementParser extends ExpressionParser { const isPrivate = key.type === "PrivateName"; // Check the key is not a computed expression or string literal. const isSimple = key.type === "Identifier"; + const maybeQuestionTokenStart = this.state.start; - // "async" should not be treated as normal porperty names - if (key.name !== "async") this.parsePostMemberNameModifiers(publicMember); + this.parsePostMemberNameModifiers(publicMember); if (this.isClassMethod()) { method.kind = "method"; @@ -1404,6 +1404,10 @@ export default class StatementParser extends ExpressionParser { // an async method const isGenerator = this.eat(tt.star); + if (publicMember.optional) { + this.unexpected(maybeQuestionTokenStart); + } + method.kind = "method"; // The so-called parsed name would have been "async": get the real name. this.parseClassPropertyName(method); diff --git a/packages/babel-parser/test/fixtures/typescript/class/async-named-properties/input.ts b/packages/babel-parser/test/fixtures/typescript/class/async-named-properties/input.ts new file mode 100644 index 000000000000..1e0af756a626 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/class/async-named-properties/input.ts @@ -0,0 +1,4 @@ +class A { + async?(): void + async?: boolean +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/class/async-named-properties/output.json b/packages/babel-parser/test/fixtures/typescript/class/async-named-properties/output.json new file mode 100644 index 000000000000..e0ac8a5907fa --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/class/async-named-properties/output.json @@ -0,0 +1,221 @@ +{ + "type": "File", + "start": 0, + "end": 46, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 4, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 46, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 4, + "column": 1 + } + }, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 46, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 4, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 7 + }, + "identifierName": "A" + }, + "name": "A" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 8, + "end": 46, + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 4, + "column": 1 + } + }, + "body": [ + { + "type": "TSDeclareMethod", + "start": 12, + "end": 26, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 16 + } + }, + "static": false, + "key": { + "type": "Identifier", + "start": 12, + "end": 17, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 7 + }, + "identifierName": "async" + }, + "name": "async" + }, + "computed": false, + "optional": true, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [], + "returnType": { + "type": "TSTypeAnnotation", + "start": 20, + "end": 26, + "loc": { + "start": { + "line": 2, + "column": 10 + }, + "end": { + "line": 2, + "column": 16 + } + }, + "typeAnnotation": { + "type": "TSVoidKeyword", + "start": 22, + "end": 26, + "loc": { + "start": { + "line": 2, + "column": 12 + }, + "end": { + "line": 2, + "column": 16 + } + } + } + } + }, + { + "type": "ClassProperty", + "start": 29, + "end": 44, + "loc": { + "start": { + "line": 3, + "column": 2 + }, + "end": { + "line": 3, + "column": 17 + } + }, + "static": false, + "key": { + "type": "Identifier", + "start": 29, + "end": 34, + "loc": { + "start": { + "line": 3, + "column": 2 + }, + "end": { + "line": 3, + "column": 7 + }, + "identifierName": "async" + }, + "name": "async" + }, + "computed": false, + "optional": true, + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 35, + "end": 44, + "loc": { + "start": { + "line": 3, + "column": 8 + }, + "end": { + "line": 3, + "column": 17 + } + }, + "typeAnnotation": { + "type": "TSBooleanKeyword", + "start": 37, + "end": 44, + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 17 + } + } + } + }, + "value": null + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file