From fdf2ff4ecba70179790ef36956fac8f16364c251 Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Fri, 2 Apr 2021 13:15:20 +0900 Subject: [PATCH 01/12] Add parsing support TS 4.3 get/set --- .../src/plugins/typescript/index.js | 25 +++++++++++++++++++ packages/babel-parser/src/types.js | 1 + 2 files changed, 26 insertions(+) diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index 7178ea62f61d..f298d4268bd3 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -603,6 +603,9 @@ export default (superClass: Class): Class => const method: N.TsMethodSignature = nodeAny; this.tsFillSignature(tt.colon, method); this.tsParseTypeMemberSemicolon(); + if (!method.kind) { + method.kind = "method"; + } return this.finishNode(method, "TSMethodSignature"); } else { const property: N.TsPropertySignature = nodeAny; @@ -614,6 +617,27 @@ export default (superClass: Class): Class => } } + tsParseMethodSignatureKind(node: any) { + if (!this.isContextual("get") && !this.isContextual("set")) { + return; + } + const kind = this.state.value; + if ( + this.tsTryParse(() => { + if (this.tsNextTokenCanFollowModifier()) { + // Check if a property is a method signature + const lookahead = this.lookahead(); + return ( + lookahead.type === tt.parenL || + (lookahead.type === tt.relational && lookahead.value === "<") + ); + } + }) + ) { + node.kind = kind; + } + } + tsParseTypeMember(): N.TsTypeElement { const node: any = this.startNode(); @@ -655,6 +679,7 @@ export default (superClass: Class): Class => return idx; } + this.tsParseMethodSignatureKind(node); this.parsePropertyName(node, /* isPrivateNameAllowed */ false); return this.tsParsePropertyOrMethodSignature(node, !!node.readonly); } diff --git a/packages/babel-parser/src/types.js b/packages/babel-parser/src/types.js index 6bf9b9cb0f78..c0c996389981 100644 --- a/packages/babel-parser/src/types.js +++ b/packages/babel-parser/src/types.js @@ -1208,6 +1208,7 @@ export type TsPropertySignature = TsNamedTypeElementBase & { export type TsMethodSignature = TsSignatureDeclarationBase & TsNamedTypeElementBase & { type: "TSMethodSignature", + kind: "method" | "get" | "set", }; // *Not* a ClassMemberBase: Can't have accessibility, can't be abstract, can't be optional. From 4adfa298bd2990b28a89248c1c7e9f1c7af3293c Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Fri, 2 Apr 2021 13:47:16 +0900 Subject: [PATCH 02/12] Update existing snapshots --- .../declare/pattern-parameters/output.json | 9 +++++--- .../invalid-modifiers-method/output.json | 21 ++++++++++++------- .../interface/method-computed/output.json | 14 +++++++------ .../interface/method-generic/output.json | 3 ++- .../interface/method-optional/output.json | 3 ++- .../interface/method-plain/output.json | 6 ++++-- .../interface/pattern-parameters/output.json | 9 +++++--- .../reserved-method-name/output.json | 3 ++- .../types/pattern-parameters/output.json | 9 +++++--- 9 files changed, 50 insertions(+), 27 deletions(-) diff --git a/packages/babel-parser/test/fixtures/typescript/declare/pattern-parameters/output.json b/packages/babel-parser/test/fixtures/typescript/declare/pattern-parameters/output.json index e38f277d47ad..5a0f8fbc624d 100644 --- a/packages/babel-parser/test/fixtures/typescript/declare/pattern-parameters/output.json +++ b/packages/babel-parser/test/fixtures/typescript/declare/pattern-parameters/output.json @@ -43,7 +43,8 @@ "type": "TSVoidKeyword", "start":34,"end":38,"loc":{"start":{"line":2,"column":12},"end":{"line":2,"column":16}} } - } + }, + "kind": "method" }, { "type": "TSMethodSignature", @@ -74,7 +75,8 @@ "type": "TSAnyKeyword", "start":56,"end":59,"loc":{"start":{"line":3,"column":16},"end":{"line":3,"column":19}} } - } + }, + "kind": "method" }, { "type": "TSMethodSignature", @@ -126,7 +128,8 @@ "type": "TSVoidKeyword", "start":95,"end":99,"loc":{"start":{"line":4,"column":34},"end":{"line":4,"column":38}} } - } + }, + "kind": "method" } ] }, diff --git a/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers-method/output.json b/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers-method/output.json index 080f46b132ef..ac8626f2cc4e 100644 --- a/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers-method/output.json +++ b/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers-method/output.json @@ -38,7 +38,8 @@ "name": "a" }, "computed": false, - "parameters": [] + "parameters": [], + "kind": "method" }, { "type": "TSMethodSignature", @@ -50,7 +51,8 @@ "name": "b" }, "computed": false, - "parameters": [] + "parameters": [], + "kind": "method" }, { "type": "TSMethodSignature", @@ -62,7 +64,8 @@ "name": "c" }, "computed": false, - "parameters": [] + "parameters": [], + "kind": "method" }, { "type": "TSMethodSignature", @@ -74,7 +77,8 @@ "name": "d" }, "computed": false, - "parameters": [] + "parameters": [], + "kind": "method" }, { "type": "TSMethodSignature", @@ -86,7 +90,8 @@ "name": "e" }, "computed": false, - "parameters": [] + "parameters": [], + "kind": "method" }, { "type": "TSMethodSignature", @@ -98,7 +103,8 @@ "name": "f" }, "computed": false, - "parameters": [] + "parameters": [], + "kind": "method" }, { "type": "TSMethodSignature", @@ -110,7 +116,8 @@ "name": "g" }, "computed": false, - "parameters": [] + "parameters": [], + "kind": "method" } ] } diff --git a/packages/babel-parser/test/fixtures/typescript/interface/method-computed/output.json b/packages/babel-parser/test/fixtures/typescript/interface/method-computed/output.json index 0546e0e21df5..112c4b21bedc 100644 --- a/packages/babel-parser/test/fixtures/typescript/interface/method-computed/output.json +++ b/packages/babel-parser/test/fixtures/typescript/interface/method-computed/output.json @@ -31,12 +31,12 @@ "start":19,"end":25,"loc":{"start":{"line":2,"column":5},"end":{"line":2,"column":11},"identifierName":"Symbol"}, "name": "Symbol" }, + "computed": false, "property": { "type": "Identifier", "start":26,"end":34,"loc":{"start":{"line":2,"column":12},"end":{"line":2,"column":20},"identifierName":"iterator"}, "name": "iterator" - }, - "computed": false + } }, "parameters": [], "typeAnnotation": { @@ -46,7 +46,8 @@ "type": "TSVoidKeyword", "start":39,"end":43,"loc":{"start":{"line":2,"column":25},"end":{"line":2,"column":29}} } - } + }, + "kind": "method" }, { "type": "TSMethodSignature", @@ -60,12 +61,12 @@ "start":50,"end":56,"loc":{"start":{"line":3,"column":5},"end":{"line":3,"column":11},"identifierName":"Symbol"}, "name": "Symbol" }, + "computed": false, "property": { "type": "Identifier", "start":57,"end":65,"loc":{"start":{"line":3,"column":12},"end":{"line":3,"column":20},"identifierName":"iterator"}, "name": "iterator" - }, - "computed": false + } }, "optional": true, "parameters": [], @@ -76,7 +77,8 @@ "type": "TSNumberKeyword", "start":71,"end":77,"loc":{"start":{"line":3,"column":26},"end":{"line":3,"column":32}} } - } + }, + "kind": "method" } ] } diff --git a/packages/babel-parser/test/fixtures/typescript/interface/method-generic/output.json b/packages/babel-parser/test/fixtures/typescript/interface/method-generic/output.json index dcd0be5cd357..36810e05164b 100644 --- a/packages/babel-parser/test/fixtures/typescript/interface/method-generic/output.json +++ b/packages/babel-parser/test/fixtures/typescript/interface/method-generic/output.json @@ -80,7 +80,8 @@ "name": "T" } } - } + }, + "kind": "method" } ] } diff --git a/packages/babel-parser/test/fixtures/typescript/interface/method-optional/output.json b/packages/babel-parser/test/fixtures/typescript/interface/method-optional/output.json index dfaf36169aef..353478b4def8 100644 --- a/packages/babel-parser/test/fixtures/typescript/interface/method-optional/output.json +++ b/packages/babel-parser/test/fixtures/typescript/interface/method-optional/output.json @@ -37,7 +37,8 @@ "type": "TSVoidKeyword", "start":24,"end":28,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":14}} } - } + }, + "kind": "method" } ] } diff --git a/packages/babel-parser/test/fixtures/typescript/interface/method-plain/output.json b/packages/babel-parser/test/fixtures/typescript/interface/method-plain/output.json index 48f549db12a4..3db978d83f5c 100644 --- a/packages/babel-parser/test/fixtures/typescript/interface/method-plain/output.json +++ b/packages/babel-parser/test/fixtures/typescript/interface/method-plain/output.json @@ -28,7 +28,8 @@ "name": "m" }, "computed": false, - "parameters": [] + "parameters": [], + "kind": "method" }, { "type": "TSMethodSignature", @@ -83,7 +84,8 @@ "type": "TSVoidKeyword", "start":58,"end":62,"loc":{"start":{"line":3,"column":35},"end":{"line":3,"column":39}} } - } + }, + "kind": "method" } ] } diff --git a/packages/babel-parser/test/fixtures/typescript/interface/pattern-parameters/output.json b/packages/babel-parser/test/fixtures/typescript/interface/pattern-parameters/output.json index 9924e1f55778..4664dc3b8951 100644 --- a/packages/babel-parser/test/fixtures/typescript/interface/pattern-parameters/output.json +++ b/packages/babel-parser/test/fixtures/typescript/interface/pattern-parameters/output.json @@ -43,7 +43,8 @@ "type": "TSVoidKeyword", "start":26,"end":30,"loc":{"start":{"line":2,"column":12},"end":{"line":2,"column":16}} } - } + }, + "kind": "method" }, { "type": "TSMethodSignature", @@ -74,7 +75,8 @@ "type": "TSAnyKeyword", "start":48,"end":51,"loc":{"start":{"line":3,"column":16},"end":{"line":3,"column":19}} } - } + }, + "kind": "method" }, { "type": "TSMethodSignature", @@ -126,7 +128,8 @@ "type": "TSVoidKeyword", "start":87,"end":91,"loc":{"start":{"line":4,"column":34},"end":{"line":4,"column":38}} } - } + }, + "kind": "method" } ] } diff --git a/packages/babel-parser/test/fixtures/typescript/interface/reserved-method-name/output.json b/packages/babel-parser/test/fixtures/typescript/interface/reserved-method-name/output.json index 59bb78a048ef..c32fcfd2edfb 100644 --- a/packages/babel-parser/test/fixtures/typescript/interface/reserved-method-name/output.json +++ b/packages/babel-parser/test/fixtures/typescript/interface/reserved-method-name/output.json @@ -36,7 +36,8 @@ "type": "TSVoidKeyword", "start":27,"end":31,"loc":{"start":{"line":2,"column":13},"end":{"line":2,"column":17}} } - } + }, + "kind": "method" } ] } diff --git a/packages/babel-parser/test/fixtures/typescript/types/pattern-parameters/output.json b/packages/babel-parser/test/fixtures/typescript/types/pattern-parameters/output.json index f9b74326a9a0..ad11ca49f7e6 100644 --- a/packages/babel-parser/test/fixtures/typescript/types/pattern-parameters/output.json +++ b/packages/babel-parser/test/fixtures/typescript/types/pattern-parameters/output.json @@ -43,7 +43,8 @@ "type": "TSVoidKeyword", "start":23,"end":27,"loc":{"start":{"line":2,"column":12},"end":{"line":2,"column":16}} } - } + }, + "kind": "method" }, { "type": "TSMethodSignature", @@ -74,7 +75,8 @@ "type": "TSAnyKeyword", "start":45,"end":48,"loc":{"start":{"line":3,"column":16},"end":{"line":3,"column":19}} } - } + }, + "kind": "method" }, { "type": "TSMethodSignature", @@ -126,7 +128,8 @@ "type": "TSVoidKeyword", "start":84,"end":88,"loc":{"start":{"line":4,"column":34},"end":{"line":4,"column":38}} } - } + }, + "kind": "method" } ] } From 48d5f8e48bc6d6dc7cb31fd5d5987868f80a1395 Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Fri, 2 Apr 2021 14:42:53 +0900 Subject: [PATCH 03/12] Add Syntax Errors --- .../src/plugins/typescript/index.js | 33 ++++++- .../interface/get-set-ambiguous/input.ts | 6 ++ .../interface/get-set-ambiguous/output.json | 86 +++++++++++++++++ .../interface/get-set-methods/input.ts | 4 + .../interface/get-set-methods/output.json | 68 ++++++++++++++ .../interface/get-set-properties/input.ts | 4 + .../interface/get-set-properties/output.json | 88 ++++++++++++++++++ .../get-set-type-parameters/input.ts | 4 + .../get-set-type-parameters/output.json | 92 +++++++++++++++++++ .../typescript/interface/get-set/input.ts | 4 + .../typescript/interface/get-set/output.json | 66 +++++++++++++ .../types/type-literal-get-set/input.ts | 4 + .../types/type-literal-get-set/output.json | 78 ++++++++++++++++ .../src/ast-types/generated/index.ts | 1 + 14 files changed, 533 insertions(+), 5 deletions(-) create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set-ambiguous/input.ts create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set-ambiguous/output.json create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set-methods/input.ts create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set-methods/output.json create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set-properties/input.ts create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set-properties/output.json create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set-type-parameters/input.ts create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set-type-parameters/output.json create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set/input.ts create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set/output.json create mode 100644 packages/babel-parser/test/fixtures/typescript/types/type-literal-get-set/input.ts create mode 100644 packages/babel-parser/test/fixtures/typescript/types/type-literal-get-set/output.json diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index f298d4268bd3..25f255866c13 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -70,6 +70,7 @@ const TSErrors = makeErrorTemplates( { AbstractMethodHasImplementation: "Method '%0' cannot have an implementation because it is marked abstract.", + AccesorCannotHaveTypeParameters: "An accessor cannot have type parameters.", ClassMethodHasDeclare: "Class methods cannot have the 'declare' modifier.", ClassMethodHasReadonly: "Class methods cannot have the 'readonly' modifier.", @@ -121,6 +122,8 @@ const TSErrors = makeErrorTemplates( "Private elements cannot have an accessibility modifier ('%0').", ReadonlyForMethodSignature: "'readonly' modifier can only appear on a property declaration or index signature.", + SetAccesorCannotHaveReturnType: + "A 'set' accessor cannot have a return type annotation.", TypeAnnotationAfterAssign: "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`.", TypeImportCannotSpecifyDefaultAndNamed: @@ -603,7 +606,21 @@ export default (superClass: Class): Class => const method: N.TsMethodSignature = nodeAny; this.tsFillSignature(tt.colon, method); this.tsParseTypeMemberSemicolon(); - if (!method.kind) { + if (method.kind === "get") { + if (method.parameters.length > 0) { + this.raise(this.state.pos, Errors.BadGetterArity); + } + } else if (method.kind === "set") { + if (method.parameters.length < 1) { + this.raise(this.state.pos, Errors.BadSetterArity); + } + if (method.typeAnnotation) { + this.raise( + method.typeAnnotation.start, + TSErrors.SetAccesorCannotHaveReturnType, + ); + } + } else { method.kind = "method"; } return this.finishNode(method, "TSMethodSignature"); @@ -627,10 +644,16 @@ export default (superClass: Class): Class => if (this.tsNextTokenCanFollowModifier()) { // Check if a property is a method signature const lookahead = this.lookahead(); - return ( - lookahead.type === tt.parenL || - (lookahead.type === tt.relational && lookahead.value === "<") - ); + if (lookahead.type === tt.parenL) { + return true; + } + if (lookahead.type === tt.relational && lookahead.value === "<") { + this.raise( + this.state.pos, + TSErrors.AccesorCannotHaveTypeParameters, + ); + return true; + } } }) ) { diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-ambiguous/input.ts b/packages/babel-parser/test/fixtures/typescript/interface/get-set-ambiguous/input.ts new file mode 100644 index 000000000000..8663a711f90b --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-ambiguous/input.ts @@ -0,0 +1,6 @@ +interface Foo { + get + foo(): string; + set + bar(v); +} diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-ambiguous/output.json b/packages/babel-parser/test/fixtures/typescript/interface/get-set-ambiguous/output.json new file mode 100644 index 000000000000..be21c57f2c3a --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-ambiguous/output.json @@ -0,0 +1,86 @@ +{ + "type": "File", + "start":0,"end":56,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":56,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TSInterfaceDeclaration", + "start":0,"end":56,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, + "id": { + "type": "Identifier", + "start":10,"end":13,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":13},"identifierName":"Foo"}, + "name": "Foo" + }, + "body": { + "type": "TSInterfaceBody", + "start":14,"end":56,"loc":{"start":{"line":1,"column":14},"end":{"line":6,"column":1}}, + "body": [ + { + "type": "TSPropertySignature", + "start":18,"end":21,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":5}}, + "key": { + "type": "Identifier", + "start":18,"end":21,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":5},"identifierName":"get"}, + "name": "get" + }, + "computed": false + }, + { + "type": "TSMethodSignature", + "start":24,"end":38,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":16}}, + "key": { + "type": "Identifier", + "start":24,"end":27,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":5},"identifierName":"foo"}, + "name": "foo" + }, + "computed": false, + "parameters": [], + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":29,"end":37,"loc":{"start":{"line":3,"column":7},"end":{"line":3,"column":15}}, + "typeAnnotation": { + "type": "TSStringKeyword", + "start":31,"end":37,"loc":{"start":{"line":3,"column":9},"end":{"line":3,"column":15}} + } + }, + "kind": "method" + }, + { + "type": "TSPropertySignature", + "start":41,"end":44,"loc":{"start":{"line":4,"column":2},"end":{"line":4,"column":5}}, + "key": { + "type": "Identifier", + "start":41,"end":44,"loc":{"start":{"line":4,"column":2},"end":{"line":4,"column":5},"identifierName":"set"}, + "name": "set" + }, + "computed": false + }, + { + "type": "TSMethodSignature", + "start":47,"end":54,"loc":{"start":{"line":5,"column":2},"end":{"line":5,"column":9}}, + "key": { + "type": "Identifier", + "start":47,"end":50,"loc":{"start":{"line":5,"column":2},"end":{"line":5,"column":5},"identifierName":"bar"}, + "name": "bar" + }, + "computed": false, + "parameters": [ + { + "type": "Identifier", + "start":51,"end":52,"loc":{"start":{"line":5,"column":6},"end":{"line":5,"column":7},"identifierName":"v"}, + "name": "v" + } + ], + "kind": "method" + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-methods/input.ts b/packages/babel-parser/test/fixtures/typescript/interface/get-set-methods/input.ts new file mode 100644 index 000000000000..d9df5e022250 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-methods/input.ts @@ -0,0 +1,4 @@ +interface Foo { + get(): string; + set(): string; +} diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-methods/output.json b/packages/babel-parser/test/fixtures/typescript/interface/get-set-methods/output.json new file mode 100644 index 000000000000..e2119a7de9aa --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-methods/output.json @@ -0,0 +1,68 @@ +{ + "type": "File", + "start":0,"end":51,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":51,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TSInterfaceDeclaration", + "start":0,"end":51,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "id": { + "type": "Identifier", + "start":10,"end":13,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":13},"identifierName":"Foo"}, + "name": "Foo" + }, + "body": { + "type": "TSInterfaceBody", + "start":14,"end":51,"loc":{"start":{"line":1,"column":14},"end":{"line":4,"column":1}}, + "body": [ + { + "type": "TSMethodSignature", + "start":18,"end":32,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":16}}, + "key": { + "type": "Identifier", + "start":18,"end":21,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":5},"identifierName":"get"}, + "name": "get" + }, + "computed": false, + "parameters": [], + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":23,"end":31,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":15}}, + "typeAnnotation": { + "type": "TSStringKeyword", + "start":25,"end":31,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":15}} + } + }, + "kind": "method" + }, + { + "type": "TSMethodSignature", + "start":35,"end":49,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":16}}, + "key": { + "type": "Identifier", + "start":35,"end":38,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":5},"identifierName":"set"}, + "name": "set" + }, + "computed": false, + "parameters": [], + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":40,"end":48,"loc":{"start":{"line":3,"column":7},"end":{"line":3,"column":15}}, + "typeAnnotation": { + "type": "TSStringKeyword", + "start":42,"end":48,"loc":{"start":{"line":3,"column":9},"end":{"line":3,"column":15}} + } + }, + "kind": "method" + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-properties/input.ts b/packages/babel-parser/test/fixtures/typescript/interface/get-set-properties/input.ts new file mode 100644 index 000000000000..135b4db01abd --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-properties/input.ts @@ -0,0 +1,4 @@ +interface Foo { + get foo: string; + set bar: string; +} diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-properties/output.json b/packages/babel-parser/test/fixtures/typescript/interface/get-set-properties/output.json new file mode 100644 index 000000000000..4af2041fda2e --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-properties/output.json @@ -0,0 +1,88 @@ +{ + "type": "File", + "start":0,"end":55,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "errors": [ + "SyntaxError: Missing semicolon. (2:5)", + "SyntaxError: Missing semicolon. (3:5)" + ], + "program": { + "type": "Program", + "start":0,"end":55,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TSInterfaceDeclaration", + "start":0,"end":55,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "id": { + "type": "Identifier", + "start":10,"end":13,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":13},"identifierName":"Foo"}, + "name": "Foo" + }, + "body": { + "type": "TSInterfaceBody", + "start":14,"end":55,"loc":{"start":{"line":1,"column":14},"end":{"line":4,"column":1}}, + "body": [ + { + "type": "TSPropertySignature", + "start":18,"end":21,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":5}}, + "key": { + "type": "Identifier", + "start":18,"end":21,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":5},"identifierName":"get"}, + "name": "get" + }, + "computed": false + }, + { + "type": "TSPropertySignature", + "start":22,"end":34,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":18}}, + "key": { + "type": "Identifier", + "start":22,"end":25,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":9},"identifierName":"foo"}, + "name": "foo" + }, + "computed": false, + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":25,"end":33,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":17}}, + "typeAnnotation": { + "type": "TSStringKeyword", + "start":27,"end":33,"loc":{"start":{"line":2,"column":11},"end":{"line":2,"column":17}} + } + } + }, + { + "type": "TSPropertySignature", + "start":37,"end":40,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":5}}, + "key": { + "type": "Identifier", + "start":37,"end":40,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":5},"identifierName":"set"}, + "name": "set" + }, + "computed": false + }, + { + "type": "TSPropertySignature", + "start":41,"end":53,"loc":{"start":{"line":3,"column":6},"end":{"line":3,"column":18}}, + "key": { + "type": "Identifier", + "start":41,"end":44,"loc":{"start":{"line":3,"column":6},"end":{"line":3,"column":9},"identifierName":"bar"}, + "name": "bar" + }, + "computed": false, + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":44,"end":52,"loc":{"start":{"line":3,"column":9},"end":{"line":3,"column":17}}, + "typeAnnotation": { + "type": "TSStringKeyword", + "start":46,"end":52,"loc":{"start":{"line":3,"column":11},"end":{"line":3,"column":17}} + } + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-type-parameters/input.ts b/packages/babel-parser/test/fixtures/typescript/interface/get-set-type-parameters/input.ts new file mode 100644 index 000000000000..085b06d811bf --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-type-parameters/input.ts @@ -0,0 +1,4 @@ +interface Foo { + get foo(): string; + set bar(v); +} diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-type-parameters/output.json b/packages/babel-parser/test/fixtures/typescript/interface/get-set-type-parameters/output.json new file mode 100644 index 000000000000..3bb72034eaa9 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-type-parameters/output.json @@ -0,0 +1,92 @@ +{ + "type": "File", + "start":0,"end":58,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "errors": [ + "SyntaxError: An accessor cannot have type parameters. (2:9)", + "SyntaxError: An accessor cannot have type parameters. (3:9)" + ], + "program": { + "type": "Program", + "start":0,"end":58,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TSInterfaceDeclaration", + "start":0,"end":58,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "id": { + "type": "Identifier", + "start":10,"end":13,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":13},"identifierName":"Foo"}, + "name": "Foo" + }, + "body": { + "type": "TSInterfaceBody", + "start":14,"end":58,"loc":{"start":{"line":1,"column":14},"end":{"line":4,"column":1}}, + "body": [ + { + "type": "TSMethodSignature", + "start":18,"end":39,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":23}}, + "kind": "get", + "key": { + "type": "Identifier", + "start":22,"end":25,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":9},"identifierName":"foo"}, + "name": "foo" + }, + "computed": false, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "start":25,"end":28,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":12}}, + "params": [ + { + "type": "TSTypeParameter", + "start":26,"end":27,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":11}}, + "name": "T" + } + ] + }, + "parameters": [], + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":30,"end":38,"loc":{"start":{"line":2,"column":14},"end":{"line":2,"column":22}}, + "typeAnnotation": { + "type": "TSStringKeyword", + "start":32,"end":38,"loc":{"start":{"line":2,"column":16},"end":{"line":2,"column":22}} + } + } + }, + { + "type": "TSMethodSignature", + "start":42,"end":56,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":16}}, + "kind": "set", + "key": { + "type": "Identifier", + "start":46,"end":49,"loc":{"start":{"line":3,"column":6},"end":{"line":3,"column":9},"identifierName":"bar"}, + "name": "bar" + }, + "computed": false, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "start":49,"end":52,"loc":{"start":{"line":3,"column":9},"end":{"line":3,"column":12}}, + "params": [ + { + "type": "TSTypeParameter", + "start":50,"end":51,"loc":{"start":{"line":3,"column":10},"end":{"line":3,"column":11}}, + "name": "T" + } + ] + }, + "parameters": [ + { + "type": "Identifier", + "start":53,"end":54,"loc":{"start":{"line":3,"column":13},"end":{"line":3,"column":14},"identifierName":"v"}, + "name": "v" + } + ] + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set/input.ts b/packages/babel-parser/test/fixtures/typescript/interface/get-set/input.ts new file mode 100644 index 000000000000..1d700d78aed8 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set/input.ts @@ -0,0 +1,4 @@ +interface Foo { + get foo(): string; + set bar(v); +} diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set/output.json b/packages/babel-parser/test/fixtures/typescript/interface/get-set/output.json new file mode 100644 index 000000000000..fd035cd7cd87 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set/output.json @@ -0,0 +1,66 @@ +{ + "type": "File", + "start":0,"end":52,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "program": { + "type": "Program", + "start":0,"end":52,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TSInterfaceDeclaration", + "start":0,"end":52,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "id": { + "type": "Identifier", + "start":10,"end":13,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":13},"identifierName":"Foo"}, + "name": "Foo" + }, + "body": { + "type": "TSInterfaceBody", + "start":14,"end":52,"loc":{"start":{"line":1,"column":14},"end":{"line":4,"column":1}}, + "body": [ + { + "type": "TSMethodSignature", + "start":18,"end":36,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":20}}, + "kind": "get", + "key": { + "type": "Identifier", + "start":22,"end":25,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":9},"identifierName":"foo"}, + "name": "foo" + }, + "computed": false, + "parameters": [], + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":27,"end":35,"loc":{"start":{"line":2,"column":11},"end":{"line":2,"column":19}}, + "typeAnnotation": { + "type": "TSStringKeyword", + "start":29,"end":35,"loc":{"start":{"line":2,"column":13},"end":{"line":2,"column":19}} + } + } + }, + { + "type": "TSMethodSignature", + "start":39,"end":50,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":13}}, + "kind": "set", + "key": { + "type": "Identifier", + "start":43,"end":46,"loc":{"start":{"line":3,"column":6},"end":{"line":3,"column":9},"identifierName":"bar"}, + "name": "bar" + }, + "computed": false, + "parameters": [ + { + "type": "Identifier", + "start":47,"end":48,"loc":{"start":{"line":3,"column":10},"end":{"line":3,"column":11},"identifierName":"v"}, + "name": "v" + } + ] + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/types/type-literal-get-set/input.ts b/packages/babel-parser/test/fixtures/typescript/types/type-literal-get-set/input.ts new file mode 100644 index 000000000000..a3a21e03ca1e --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/types/type-literal-get-set/input.ts @@ -0,0 +1,4 @@ +var obj: { + get foo(): string; + set bar(v); +}; diff --git a/packages/babel-parser/test/fixtures/typescript/types/type-literal-get-set/output.json b/packages/babel-parser/test/fixtures/typescript/types/type-literal-get-set/output.json new file mode 100644 index 000000000000..1709b69d53a0 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/types/type-literal-get-set/output.json @@ -0,0 +1,78 @@ +{ + "type": "File", + "start":0,"end":48,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":2}}, + "program": { + "type": "Program", + "start":0,"end":48,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":2}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "VariableDeclaration", + "start":0,"end":48,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":2}}, + "declarations": [ + { + "type": "VariableDeclarator", + "start":4,"end":47,"loc":{"start":{"line":1,"column":4},"end":{"line":4,"column":1}}, + "id": { + "type": "Identifier", + "start":4,"end":47,"loc":{"start":{"line":1,"column":4},"end":{"line":4,"column":1},"identifierName":"obj"}, + "name": "obj", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":7,"end":47,"loc":{"start":{"line":1,"column":7},"end":{"line":4,"column":1}}, + "typeAnnotation": { + "type": "TSTypeLiteral", + "start":9,"end":47,"loc":{"start":{"line":1,"column":9},"end":{"line":4,"column":1}}, + "members": [ + { + "type": "TSMethodSignature", + "start":13,"end":31,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":20}}, + "kind": "get", + "key": { + "type": "Identifier", + "start":17,"end":20,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":9},"identifierName":"foo"}, + "name": "foo" + }, + "computed": false, + "parameters": [], + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":22,"end":30,"loc":{"start":{"line":2,"column":11},"end":{"line":2,"column":19}}, + "typeAnnotation": { + "type": "TSStringKeyword", + "start":24,"end":30,"loc":{"start":{"line":2,"column":13},"end":{"line":2,"column":19}} + } + } + }, + { + "type": "TSMethodSignature", + "start":34,"end":45,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":13}}, + "kind": "set", + "key": { + "type": "Identifier", + "start":38,"end":41,"loc":{"start":{"line":3,"column":6},"end":{"line":3,"column":9},"identifierName":"bar"}, + "name": "bar" + }, + "computed": false, + "parameters": [ + { + "type": "Identifier", + "start":42,"end":43,"loc":{"start":{"line":3,"column":10},"end":{"line":3,"column":11},"identifierName":"v"}, + "name": "v" + } + ] + } + ] + } + } + }, + "init": null + } + ], + "kind": "var" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-types/src/ast-types/generated/index.ts b/packages/babel-types/src/ast-types/generated/index.ts index da47784f7529..a5f105c87cda 100755 --- a/packages/babel-types/src/ast-types/generated/index.ts +++ b/packages/babel-types/src/ast-types/generated/index.ts @@ -1712,6 +1712,7 @@ export interface TSMethodSignature extends BaseNode { parameters: Array; typeAnnotation?: TSTypeAnnotation | null; computed?: boolean | null; + kind: "method" | "get" | "set"; optional?: boolean | null; } From 0ffbbd9804f3e6142c4d8817b008633f6708a191 Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Fri, 2 Apr 2021 14:49:24 +0900 Subject: [PATCH 04/12] Add test cases for Syntax Errors --- .../get-set-invalid-parameters/input.ts | 4 ++ .../get-set-invalid-parameters/output.json | 70 +++++++++++++++++++ .../get-set-invalid-return-types/input.ts | 3 + .../get-set-invalid-return-types/output.json | 57 +++++++++++++++ 4 files changed, 134 insertions(+) create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-parameters/input.ts create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-parameters/output.json create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-return-types/input.ts create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-return-types/output.json diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-parameters/input.ts b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-parameters/input.ts new file mode 100644 index 000000000000..571a874d30a1 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-parameters/input.ts @@ -0,0 +1,4 @@ +interface Foo { + get foo(param): string; + set foo(); +} diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-parameters/output.json b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-parameters/output.json new file mode 100644 index 000000000000..68f98675c817 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-parameters/output.json @@ -0,0 +1,70 @@ +{ + "type": "File", + "start":0,"end":56,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "errors": [ + "SyntaxError: getter must not have any formal parameters (3:5)", + "SyntaxError: setter must have exactly one formal parameter (4:1)" + ], + "program": { + "type": "Program", + "start":0,"end":56,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TSInterfaceDeclaration", + "start":0,"end":56,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "id": { + "type": "Identifier", + "start":10,"end":13,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":13},"identifierName":"Foo"}, + "name": "Foo" + }, + "body": { + "type": "TSInterfaceBody", + "start":14,"end":56,"loc":{"start":{"line":1,"column":14},"end":{"line":4,"column":1}}, + "body": [ + { + "type": "TSMethodSignature", + "start":18,"end":41,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":25}}, + "kind": "get", + "key": { + "type": "Identifier", + "start":22,"end":25,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":9},"identifierName":"foo"}, + "name": "foo" + }, + "computed": false, + "parameters": [ + { + "type": "Identifier", + "start":26,"end":31,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":15},"identifierName":"param"}, + "name": "param" + } + ], + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":32,"end":40,"loc":{"start":{"line":2,"column":16},"end":{"line":2,"column":24}}, + "typeAnnotation": { + "type": "TSStringKeyword", + "start":34,"end":40,"loc":{"start":{"line":2,"column":18},"end":{"line":2,"column":24}} + } + } + }, + { + "type": "TSMethodSignature", + "start":44,"end":54,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":12}}, + "kind": "set", + "key": { + "type": "Identifier", + "start":48,"end":51,"loc":{"start":{"line":3,"column":6},"end":{"line":3,"column":9},"identifierName":"foo"}, + "name": "foo" + }, + "computed": false, + "parameters": [] + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-return-types/input.ts b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-return-types/input.ts new file mode 100644 index 000000000000..ee80bfe1d836 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-return-types/input.ts @@ -0,0 +1,3 @@ +interface Foo { + set foo(param): string; +} diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-return-types/output.json b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-return-types/output.json new file mode 100644 index 000000000000..3d085079205f --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-return-types/output.json @@ -0,0 +1,57 @@ +{ + "type": "File", + "start":0,"end":43,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "errors": [ + "SyntaxError: A 'set' accessor cannot have a return type annotation. (2:16)" + ], + "program": { + "type": "Program", + "start":0,"end":43,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TSInterfaceDeclaration", + "start":0,"end":43,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "id": { + "type": "Identifier", + "start":10,"end":13,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":13},"identifierName":"Foo"}, + "name": "Foo" + }, + "body": { + "type": "TSInterfaceBody", + "start":14,"end":43,"loc":{"start":{"line":1,"column":14},"end":{"line":3,"column":1}}, + "body": [ + { + "type": "TSMethodSignature", + "start":18,"end":41,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":25}}, + "kind": "set", + "key": { + "type": "Identifier", + "start":22,"end":25,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":9},"identifierName":"foo"}, + "name": "foo" + }, + "computed": false, + "parameters": [ + { + "type": "Identifier", + "start":26,"end":31,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":15},"identifierName":"param"}, + "name": "param" + } + ], + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":32,"end":40,"loc":{"start":{"line":2,"column":16},"end":{"line":2,"column":24}}, + "typeAnnotation": { + "type": "TSStringKeyword", + "start":34,"end":40,"loc":{"start":{"line":2,"column":18},"end":{"line":2,"column":24}} + } + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file From 7b5117464ed356a6cac8839dd44dbc3c56afc1fd Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Fri, 2 Apr 2021 15:03:21 +0900 Subject: [PATCH 05/12] Add support in babel-types babel-generator --- packages/babel-generator/src/generators/typescript.ts | 5 +++++ .../test/fixtures/typescript/interface-method-kind/input.js | 4 ++++ .../test/fixtures/typescript/interface-method-kind/output.js | 4 ++++ packages/babel-types/src/definitions/typescript.ts | 3 +++ 4 files changed, 16 insertions(+) create mode 100644 packages/babel-generator/test/fixtures/typescript/interface-method-kind/input.js create mode 100644 packages/babel-generator/test/fixtures/typescript/interface-method-kind/output.js diff --git a/packages/babel-generator/src/generators/typescript.ts b/packages/babel-generator/src/generators/typescript.ts index af70e81923d5..742cefa1dfaa 100644 --- a/packages/babel-generator/src/generators/typescript.ts +++ b/packages/babel-generator/src/generators/typescript.ts @@ -127,6 +127,11 @@ export function tsPrintPropertyOrMethodName(this: Printer, node) { } export function TSMethodSignature(this: Printer, node: t.TSMethodSignature) { + const { kind } = node; + if (kind === "set" || kind === "get") { + this.word(kind); + this.space(); + } this.tsPrintPropertyOrMethodName(node); this.tsPrintSignatureDeclarationBase(node); this.token(";"); diff --git a/packages/babel-generator/test/fixtures/typescript/interface-method-kind/input.js b/packages/babel-generator/test/fixtures/typescript/interface-method-kind/input.js new file mode 100644 index 000000000000..3e2f9d8af07b --- /dev/null +++ b/packages/babel-generator/test/fixtures/typescript/interface-method-kind/input.js @@ -0,0 +1,4 @@ +interface Foo { + get foo(); + set bar(v); +} diff --git a/packages/babel-generator/test/fixtures/typescript/interface-method-kind/output.js b/packages/babel-generator/test/fixtures/typescript/interface-method-kind/output.js new file mode 100644 index 000000000000..2ac4a6d0bf01 --- /dev/null +++ b/packages/babel-generator/test/fixtures/typescript/interface-method-kind/output.js @@ -0,0 +1,4 @@ +interface Foo { + get foo(); + set bar(v); +} \ No newline at end of file diff --git a/packages/babel-types/src/definitions/typescript.ts b/packages/babel-types/src/definitions/typescript.ts index c805c0b751d0..5d2f7d764b91 100644 --- a/packages/babel-types/src/definitions/typescript.ts +++ b/packages/babel-types/src/definitions/typescript.ts @@ -118,6 +118,9 @@ defineType("TSMethodSignature", { fields: { ...signatureDeclarationCommon, ...namedTypeElementCommon, + kind: { + validate: assertOneOf("method", "get", "set"), + }, }, }); From 190f01522425c2ffd07bb9862ca00b32393c7f59 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Sat, 3 Apr 2021 10:31:52 +0900 Subject: [PATCH 06/12] Update packages/babel-parser/src/plugins/typescript/index.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nicolò Ribaudo --- packages/babel-parser/src/plugins/typescript/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index 25f255866c13..8a988a310e32 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -611,7 +611,7 @@ export default (superClass: Class): Class => this.raise(this.state.pos, Errors.BadGetterArity); } } else if (method.kind === "set") { - if (method.parameters.length < 1) { + if (method.parameters.length !== 1) { this.raise(this.state.pos, Errors.BadSetterArity); } if (method.typeAnnotation) { From 81b97c6d1157194b130af8fe04bb9756e80a0ab0 Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Wed, 7 Apr 2021 14:57:43 +0900 Subject: [PATCH 07/12] Avoid lookahead --- .../src/plugins/typescript/index.js | 60 ++++++++----------- .../interface/get-set-properties/output.json | 30 ++-------- .../get-set-type-parameters/output.json | 8 +-- 3 files changed, 32 insertions(+), 66 deletions(-) diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index 8a988a310e32..884d3e873a04 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -195,12 +195,7 @@ export default (superClass: Class): Class => return this.match(tt.name); } - tsNextTokenCanFollowModifier() { - // Note: TypeScript's implementation is much more complicated because - // more things are considered modifiers there. - // This implementation only handles modifiers not handled by @babel/parser itself. And "static". - // TODO: Would be nice to avoid lookahead. Want a hasLineBreakUpNext() method... - this.next(); + tsTokenCanFollowModifier() { return ( (this.match(tt.bracketL) || this.match(tt.braceL) || @@ -212,6 +207,15 @@ export default (superClass: Class): Class => ); } + tsNextTokenCanFollowModifier() { + // Note: TypeScript's implementation is much more complicated because + // more things are considered modifiers there. + // This implementation only handles modifiers not handled by @babel/parser itself. And "static". + // TODO: Would be nice to avoid lookahead. Want a hasLineBreakUpNext() method... + this.next(); + return this.tsTokenCanFollowModifier(); + } + /** Parses a modifier matching one the given modifier names. */ tsParseModifier(allowedModifiers: T[]): ?T { if (!this.match(tt.name)) { @@ -549,8 +553,8 @@ export default (superClass: Class): Class => } tsParseTypeMemberSemicolon(): void { - if (!this.eat(tt.comma)) { - this.semicolon(); + if (!this.eat(tt.comma) && !this.isLineTerminator()) { + this.expect(tt.semi); } } @@ -604,6 +608,9 @@ export default (superClass: Class): Class => this.raise(node.start, TSErrors.ReadonlyForMethodSignature); } const method: N.TsMethodSignature = nodeAny; + if (method.kind && this.isRelational("<")) { + this.raise(this.state.pos, TSErrors.AccesorCannotHaveTypeParameters); + } this.tsFillSignature(tt.colon, method); this.tsParseTypeMemberSemicolon(); if (method.kind === "get") { @@ -634,33 +641,6 @@ export default (superClass: Class): Class => } } - tsParseMethodSignatureKind(node: any) { - if (!this.isContextual("get") && !this.isContextual("set")) { - return; - } - const kind = this.state.value; - if ( - this.tsTryParse(() => { - if (this.tsNextTokenCanFollowModifier()) { - // Check if a property is a method signature - const lookahead = this.lookahead(); - if (lookahead.type === tt.parenL) { - return true; - } - if (lookahead.type === tt.relational && lookahead.value === "<") { - this.raise( - this.state.pos, - TSErrors.AccesorCannotHaveTypeParameters, - ); - return true; - } - } - }) - ) { - node.kind = kind; - } - } - tsParseTypeMember(): N.TsTypeElement { const node: any = this.startNode(); @@ -702,8 +682,16 @@ export default (superClass: Class): Class => return idx; } - this.tsParseMethodSignatureKind(node); this.parsePropertyName(node, /* isPrivateNameAllowed */ false); + if ( + !node.computed && + node.key.type === "Identifier" && + (node.key.name === "get" || node.key.name === "set") && + this.tsTokenCanFollowModifier() + ) { + node.kind = node.key.name; + this.parsePropertyName(node, /* isPrivateNameAllowed */ false); + } return this.tsParsePropertyOrMethodSignature(node, !!node.readonly); } diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-properties/output.json b/packages/babel-parser/test/fixtures/typescript/interface/get-set-properties/output.json index 4af2041fda2e..6f286bc4dfe2 100644 --- a/packages/babel-parser/test/fixtures/typescript/interface/get-set-properties/output.json +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-properties/output.json @@ -1,10 +1,6 @@ { "type": "File", "start":0,"end":55,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, - "errors": [ - "SyntaxError: Missing semicolon. (2:5)", - "SyntaxError: Missing semicolon. (3:5)" - ], "program": { "type": "Program", "start":0,"end":55,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, @@ -25,23 +21,14 @@ "body": [ { "type": "TSPropertySignature", - "start":18,"end":21,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":5}}, - "key": { - "type": "Identifier", - "start":18,"end":21,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":5},"identifierName":"get"}, - "name": "get" - }, - "computed": false - }, - { - "type": "TSPropertySignature", - "start":22,"end":34,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":18}}, + "start":18,"end":34,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":18}}, "key": { "type": "Identifier", "start":22,"end":25,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":9},"identifierName":"foo"}, "name": "foo" }, "computed": false, + "kind": "get", "typeAnnotation": { "type": "TSTypeAnnotation", "start":25,"end":33,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":17}}, @@ -53,23 +40,14 @@ }, { "type": "TSPropertySignature", - "start":37,"end":40,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":5}}, - "key": { - "type": "Identifier", - "start":37,"end":40,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":5},"identifierName":"set"}, - "name": "set" - }, - "computed": false - }, - { - "type": "TSPropertySignature", - "start":41,"end":53,"loc":{"start":{"line":3,"column":6},"end":{"line":3,"column":18}}, + "start":37,"end":53,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":18}}, "key": { "type": "Identifier", "start":41,"end":44,"loc":{"start":{"line":3,"column":6},"end":{"line":3,"column":9},"identifierName":"bar"}, "name": "bar" }, "computed": false, + "kind": "set", "typeAnnotation": { "type": "TSTypeAnnotation", "start":44,"end":52,"loc":{"start":{"line":3,"column":9},"end":{"line":3,"column":17}}, diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-type-parameters/output.json b/packages/babel-parser/test/fixtures/typescript/interface/get-set-type-parameters/output.json index 3bb72034eaa9..0548c7796bf0 100644 --- a/packages/babel-parser/test/fixtures/typescript/interface/get-set-type-parameters/output.json +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-type-parameters/output.json @@ -2,8 +2,8 @@ "type": "File", "start":0,"end":58,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, "errors": [ - "SyntaxError: An accessor cannot have type parameters. (2:9)", - "SyntaxError: An accessor cannot have type parameters. (3:9)" + "SyntaxError: An accessor cannot have type parameters. (2:10)", + "SyntaxError: An accessor cannot have type parameters. (3:10)" ], "program": { "type": "Program", @@ -26,13 +26,13 @@ { "type": "TSMethodSignature", "start":18,"end":39,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":23}}, - "kind": "get", "key": { "type": "Identifier", "start":22,"end":25,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":9},"identifierName":"foo"}, "name": "foo" }, "computed": false, + "kind": "get", "typeParameters": { "type": "TSTypeParameterDeclaration", "start":25,"end":28,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":12}}, @@ -57,13 +57,13 @@ { "type": "TSMethodSignature", "start":42,"end":56,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":16}}, - "kind": "set", "key": { "type": "Identifier", "start":46,"end":49,"loc":{"start":{"line":3,"column":6},"end":{"line":3,"column":9},"identifierName":"bar"}, "name": "bar" }, "computed": false, + "kind": "set", "typeParameters": { "type": "TSTypeParameterDeclaration", "start":49,"end":52,"loc":{"start":{"line":3,"column":9},"end":{"line":3,"column":12}}, From 4d57c56463e532168b5d9d3d0ad2810217d74014 Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Mon, 12 Apr 2021 03:56:15 +0900 Subject: [PATCH 08/12] Raise errror for invalid this parameters --- packages/babel-parser/src/parser/statement.js | 8 ++ .../babel-parser/src/plugins/flow/index.js | 5 - .../src/plugins/typescript/index.js | 13 +++ .../get-set-invalid-this-parameters/input.ts | 4 + .../output.json | 95 +++++++++++++++++++ 5 files changed, 120 insertions(+), 5 deletions(-) create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-this-parameters/input.ts create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-this-parameters/output.json diff --git a/packages/babel-parser/src/parser/statement.js b/packages/babel-parser/src/parser/statement.js index 52fe66190f68..f8c05d912709 100644 --- a/packages/babel-parser/src/parser/statement.js +++ b/packages/babel-parser/src/parser/statement.js @@ -2384,4 +2384,12 @@ export default class StatementParser extends ExpressionParser { this.checkLVal(specifier.local, "import specifier", BIND_LEXICAL); node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); } + + // This is used in flow and typescript plugin + // Determine whether a parameter is a this param + isThisParam( + param: N.Pattern | N.Identifier | N.TSParameterProperty, + ): boolean { + return param.type === "Identifier" && param.name === "this"; + } } diff --git a/packages/babel-parser/src/plugins/flow/index.js b/packages/babel-parser/src/plugins/flow/index.js index 0afeaa3379ff..76895dcc93fb 100644 --- a/packages/babel-parser/src/plugins/flow/index.js +++ b/packages/babel-parser/src/plugins/flow/index.js @@ -2392,11 +2392,6 @@ export default (superClass: Class): Class => return !this.match(tt.colon) && super.isNonstaticConstructor(method); } - // determine whether a parameter is a this param - isThisParam(param) { - return param.type === "Identifier" && param.name === "this"; - } - // parse type parameters for class methods pushClassMethod( classBody: N.ClassBody, diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index 884d3e873a04..1f492fc3ab9f 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -70,6 +70,8 @@ const TSErrors = makeErrorTemplates( { AbstractMethodHasImplementation: "Method '%0' cannot have an implementation because it is marked abstract.", + AccesorCannotDeclareThisParameter: + "'get' and 'set' accessors cannot declare 'this' parameters.", AccesorCannotHaveTypeParameters: "An accessor cannot have type parameters.", ClassMethodHasDeclare: "Class methods cannot have the 'declare' modifier.", ClassMethodHasReadonly: @@ -616,10 +618,21 @@ export default (superClass: Class): Class => if (method.kind === "get") { if (method.parameters.length > 0) { this.raise(this.state.pos, Errors.BadGetterArity); + if (this.isThisParam(method.parameters[0])) { + this.raise( + this.state.pos, + TSErrors.AccesorCannotDeclareThisParameter, + ); + } } } else if (method.kind === "set") { if (method.parameters.length !== 1) { this.raise(this.state.pos, Errors.BadSetterArity); + } else if (this.isThisParam(method.parameters[0])) { + this.raise( + this.state.pos, + TSErrors.AccesorCannotDeclareThisParameter, + ); } if (method.typeAnnotation) { this.raise( diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-this-parameters/input.ts b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-this-parameters/input.ts new file mode 100644 index 000000000000..0c35d67abc6d --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-this-parameters/input.ts @@ -0,0 +1,4 @@ +interface Foo { + get bar(this: Foo); + set bar(this: Foo); +} diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-this-parameters/output.json b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-this-parameters/output.json new file mode 100644 index 000000000000..6487346bcf0b --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-this-parameters/output.json @@ -0,0 +1,95 @@ +{ + "type": "File", + "start":0,"end":61,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "errors": [ + "SyntaxError: getter must not have any formal parameters (3:5)", + "SyntaxError: 'get' and 'set' accessors cannot declare 'this' parameters. (3:5)", + "SyntaxError: 'get' and 'set' accessors cannot declare 'this' parameters. (4:1)" + ], + "program": { + "type": "Program", + "start":0,"end":61,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TSInterfaceDeclaration", + "start":0,"end":61,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, + "id": { + "type": "Identifier", + "start":10,"end":13,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":13},"identifierName":"Foo"}, + "name": "Foo" + }, + "body": { + "type": "TSInterfaceBody", + "start":14,"end":61,"loc":{"start":{"line":1,"column":14},"end":{"line":4,"column":1}}, + "body": [ + { + "type": "TSMethodSignature", + "start":18,"end":37,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":21}}, + "key": { + "type": "Identifier", + "start":22,"end":25,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":9},"identifierName":"bar"}, + "name": "bar" + }, + "computed": false, + "kind": "get", + "parameters": [ + { + "type": "Identifier", + "start":26,"end":35,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":19},"identifierName":"this"}, + "name": "this", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":30,"end":35,"loc":{"start":{"line":2,"column":14},"end":{"line":2,"column":19}}, + "typeAnnotation": { + "type": "TSTypeReference", + "start":32,"end":35,"loc":{"start":{"line":2,"column":16},"end":{"line":2,"column":19}}, + "typeName": { + "type": "Identifier", + "start":32,"end":35,"loc":{"start":{"line":2,"column":16},"end":{"line":2,"column":19},"identifierName":"Foo"}, + "name": "Foo" + } + } + } + } + ] + }, + { + "type": "TSMethodSignature", + "start":40,"end":59,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":21}}, + "key": { + "type": "Identifier", + "start":44,"end":47,"loc":{"start":{"line":3,"column":6},"end":{"line":3,"column":9},"identifierName":"bar"}, + "name": "bar" + }, + "computed": false, + "kind": "set", + "parameters": [ + { + "type": "Identifier", + "start":48,"end":57,"loc":{"start":{"line":3,"column":10},"end":{"line":3,"column":19},"identifierName":"this"}, + "name": "this", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":52,"end":57,"loc":{"start":{"line":3,"column":14},"end":{"line":3,"column":19}}, + "typeAnnotation": { + "type": "TSTypeReference", + "start":54,"end":57,"loc":{"start":{"line":3,"column":16},"end":{"line":3,"column":19}}, + "typeName": { + "type": "Identifier", + "start":54,"end":57,"loc":{"start":{"line":3,"column":16},"end":{"line":3,"column":19},"identifierName":"Foo"}, + "name": "Foo" + } + } + } + } + ] + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file From f81ff17eb39b5ff9c591dbf3eb8375ce82695d2f Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Mon, 12 Apr 2021 04:09:55 +0900 Subject: [PATCH 09/12] Raise errors for optional parameters --- .../src/plugins/typescript/index.js | 24 ++++++-- .../input.ts | 3 + .../output.json | 58 +++++++++++++++++++ 3 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-optional-parameter/input.ts create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-optional-parameter/output.json diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index 1f492fc3ab9f..96f6a4513499 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -124,6 +124,8 @@ const TSErrors = makeErrorTemplates( "Private elements cannot have an accessibility modifier ('%0').", ReadonlyForMethodSignature: "'readonly' modifier can only appear on a property declaration or index signature.", + SetAccesorCannotHaveOptionalParameter: + "A 'set' accessor cannot have an optional parameter.", SetAccesorCannotHaveReturnType: "A 'set' accessor cannot have a return type annotation.", TypeAnnotationAfterAssign: @@ -628,11 +630,23 @@ export default (superClass: Class): Class => } else if (method.kind === "set") { if (method.parameters.length !== 1) { this.raise(this.state.pos, Errors.BadSetterArity); - } else if (this.isThisParam(method.parameters[0])) { - this.raise( - this.state.pos, - TSErrors.AccesorCannotDeclareThisParameter, - ); + } else { + const firstParameter = method.parameters[0]; + if (this.isThisParam(firstParameter)) { + this.raise( + this.state.pos, + TSErrors.AccesorCannotDeclareThisParameter, + ); + } + if ( + firstParameter.type === "Identifier" && + firstParameter.optional + ) { + this.raise( + this.state.pos, + TSErrors.SetAccesorCannotHaveOptionalParameter, + ); + } } if (method.typeAnnotation) { this.raise( diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-optional-parameter/input.ts b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-optional-parameter/input.ts new file mode 100644 index 000000000000..94dab3cd7318 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-optional-parameter/input.ts @@ -0,0 +1,3 @@ +interface Foo { + set bar(foo?: string); +} diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-optional-parameter/output.json b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-optional-parameter/output.json new file mode 100644 index 000000000000..7ceb61f8f992 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-optional-parameter/output.json @@ -0,0 +1,58 @@ +{ + "type": "File", + "start":0,"end":42,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "errors": [ + "SyntaxError: A 'set' accessor cannot have an optional parameter. (3:1)" + ], + "program": { + "type": "Program", + "start":0,"end":42,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TSInterfaceDeclaration", + "start":0,"end":42,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "id": { + "type": "Identifier", + "start":10,"end":13,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":13},"identifierName":"Foo"}, + "name": "Foo" + }, + "body": { + "type": "TSInterfaceBody", + "start":14,"end":42,"loc":{"start":{"line":1,"column":14},"end":{"line":3,"column":1}}, + "body": [ + { + "type": "TSMethodSignature", + "start":18,"end":40,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":24}}, + "key": { + "type": "Identifier", + "start":22,"end":25,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":9},"identifierName":"bar"}, + "name": "bar" + }, + "computed": false, + "kind": "set", + "parameters": [ + { + "type": "Identifier", + "start":26,"end":38,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":22},"identifierName":"foo"}, + "name": "foo", + "optional": true, + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start":30,"end":38,"loc":{"start":{"line":2,"column":14},"end":{"line":2,"column":22}}, + "typeAnnotation": { + "type": "TSStringKeyword", + "start":32,"end":38,"loc":{"start":{"line":2,"column":16},"end":{"line":2,"column":22}} + } + } + } + ] + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file From 6a0c3876c46c3df0ecc4da5d1930c0e8700385aa Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Mon, 12 Apr 2021 04:14:49 +0900 Subject: [PATCH 10/12] Raise error for rest parameters --- .../src/plugins/typescript/index.js | 8 +++ .../get-set-invalid-reset-parameter/input.ts | 3 ++ .../output.json | 53 +++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-reset-parameter/input.ts create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-reset-parameter/output.json diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index 96f6a4513499..aaefac4a7a90 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -126,6 +126,8 @@ const TSErrors = makeErrorTemplates( "'readonly' modifier can only appear on a property declaration or index signature.", SetAccesorCannotHaveOptionalParameter: "A 'set' accessor cannot have an optional parameter.", + SetAccesorCannotHaveRestParameter: + "A 'set' accessor cannot have rest parameter.", SetAccesorCannotHaveReturnType: "A 'set' accessor cannot have a return type annotation.", TypeAnnotationAfterAssign: @@ -647,6 +649,12 @@ export default (superClass: Class): Class => TSErrors.SetAccesorCannotHaveOptionalParameter, ); } + if (firstParameter.type === "RestElement") { + this.raise( + this.state.pos, + TSErrors.SetAccesorCannotHaveRestParameter, + ); + } } if (method.typeAnnotation) { this.raise( diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-reset-parameter/input.ts b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-reset-parameter/input.ts new file mode 100644 index 000000000000..9acf2deb4869 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-reset-parameter/input.ts @@ -0,0 +1,3 @@ +interface Foo { + set bar(...v); +} diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-reset-parameter/output.json b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-reset-parameter/output.json new file mode 100644 index 000000000000..81831562369b --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-reset-parameter/output.json @@ -0,0 +1,53 @@ +{ + "type": "File", + "start":0,"end":34,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "errors": [ + "SyntaxError: A 'set' accessor cannot have rest parameter. (3:1)" + ], + "program": { + "type": "Program", + "start":0,"end":34,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TSInterfaceDeclaration", + "start":0,"end":34,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}}, + "id": { + "type": "Identifier", + "start":10,"end":13,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":13},"identifierName":"Foo"}, + "name": "Foo" + }, + "body": { + "type": "TSInterfaceBody", + "start":14,"end":34,"loc":{"start":{"line":1,"column":14},"end":{"line":3,"column":1}}, + "body": [ + { + "type": "TSMethodSignature", + "start":18,"end":32,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":16}}, + "key": { + "type": "Identifier", + "start":22,"end":25,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":9},"identifierName":"bar"}, + "name": "bar" + }, + "computed": false, + "kind": "set", + "parameters": [ + { + "type": "RestElement", + "start":26,"end":30,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":14}}, + "argument": { + "type": "Identifier", + "start":29,"end":30,"loc":{"start":{"line":2,"column":13},"end":{"line":2,"column":14},"identifierName":"v"}, + "name": "v" + } + } + ] + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file From fe00e0e4e258a150979d8133d6a9ca9c2ecb3fdf Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Mon, 12 Apr 2021 04:42:59 +0900 Subject: [PATCH 11/12] Update typescript allowlist --- scripts/parser-tests/typescript/allowlist.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/parser-tests/typescript/allowlist.txt b/scripts/parser-tests/typescript/allowlist.txt index 5ea3208fa25b..857715df1055 100644 --- a/scripts/parser-tests/typescript/allowlist.txt +++ b/scripts/parser-tests/typescript/allowlist.txt @@ -138,6 +138,8 @@ deleteOperator1.ts deleteOperatorInStrictMode.ts dependencyViaImportAlias.ts destructuredDeclarationEmit.ts +divergentAccessors1.ts +divergentAccessorsTypes1.ts doubleUnderscoreExportStarConflict.ts duplicateIdentifierBindingElementInParameterDeclaration1.ts duplicateIdentifierBindingElementInParameterDeclaration2.ts From 64e389b76ee4fd3d89305ffde08fa41cefe3f552 Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Mon, 12 Apr 2021 08:54:36 +0900 Subject: [PATCH 12/12] Update tests --- .../interface/get-set-invalid-parameters/output.json | 8 ++++---- .../interface/get-set-invalid-this-parameters/output.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-parameters/output.json b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-parameters/output.json index 68f98675c817..15833b14b38a 100644 --- a/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-parameters/output.json +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-parameters/output.json @@ -2,8 +2,8 @@ "type": "File", "start":0,"end":56,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, "errors": [ - "SyntaxError: getter must not have any formal parameters (3:5)", - "SyntaxError: setter must have exactly one formal parameter (4:1)" + "SyntaxError: A 'get' accesor must not have any formal parameters. (3:5)", + "SyntaxError: A 'set' accesor must have exactly one formal parameter. (4:1)" ], "program": { "type": "Program", @@ -26,13 +26,13 @@ { "type": "TSMethodSignature", "start":18,"end":41,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":25}}, - "kind": "get", "key": { "type": "Identifier", "start":22,"end":25,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":9},"identifierName":"foo"}, "name": "foo" }, "computed": false, + "kind": "get", "parameters": [ { "type": "Identifier", @@ -52,13 +52,13 @@ { "type": "TSMethodSignature", "start":44,"end":54,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":12}}, - "kind": "set", "key": { "type": "Identifier", "start":48,"end":51,"loc":{"start":{"line":3,"column":6},"end":{"line":3,"column":9},"identifierName":"foo"}, "name": "foo" }, "computed": false, + "kind": "set", "parameters": [] } ] diff --git a/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-this-parameters/output.json b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-this-parameters/output.json index 6487346bcf0b..53aad5599247 100644 --- a/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-this-parameters/output.json +++ b/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-this-parameters/output.json @@ -2,7 +2,7 @@ "type": "File", "start":0,"end":61,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":1}}, "errors": [ - "SyntaxError: getter must not have any formal parameters (3:5)", + "SyntaxError: A 'get' accesor must not have any formal parameters. (3:5)", "SyntaxError: 'get' and 'set' accessors cannot declare 'this' parameters. (3:5)", "SyntaxError: 'get' and 'set' accessors cannot declare 'this' parameters. (4:1)" ],