From e8a5fc1cc1ac6b6d7d1ba497be1ca27be946a794 Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Wed, 10 Feb 2021 01:09:23 +0900 Subject: [PATCH 1/9] tsCheckModifiers --- .../src/plugins/typescript/index.js | 42 +++++++- .../interface/invalid-modifiers/input.ts | 8 ++ .../interface/invalid-modifiers/output.json | 102 ++++++++++++++++++ 3 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers/input.ts create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers/output.json diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index 86ec75450715..e20a3962d131 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -82,6 +82,7 @@ const TSErrors = Object.freeze({ IndexSignatureHasStatic: "Index signatures cannot have the 'static' modifier", IndexSignatureHasDeclare: "Index signatures cannot have the 'declare' modifier", + InvalidModifierOnTypeMember: "'%0' modifier cannot appear on a type member.", InvalidTupleMemberLabel: "Tuple members must be labeled with a simple identifier.", MixedLabeledAndUnlabeledElements: @@ -573,16 +574,33 @@ export default (superClass: Class): Class => } } - const readonly = !!this.tsParseModifier(["readonly"]); + this.tsParseModifiers(node, [ + "readonly", + "declare", + "abstract", + "private", + "protected", + "public", + "static", + ]); + + // type members allow only 'readonly' modifier. + this.tsCheckModifiers(node, [ + "declare", + "abstract", + "private", + "protected", + "public", + "static", + ]); const idx = this.tsTryParseIndexSignature(node); if (idx) { - if (readonly) node.readonly = true; return idx; } this.parsePropertyName(node, /* isPrivateNameAllowed */ false); - return this.tsParsePropertyOrMethodSignature(node, readonly); + return this.tsParsePropertyOrMethodSignature(node, !!node.readonly); } tsParseTypeLiteral(): N.TsTypeLiteral { @@ -2894,4 +2912,22 @@ export default (superClass: Class): Class => this.unexpected(null, tt._class); } } + + tsCheckModifiers( + modified: { + [key: TsModifier]: ?true, + accessibility?: N.Accessibility, + }, + denylist: TsModifier[], + ): void { + const startPos = this.state.start; + for (const modifier of denylist) { + if ( + modified[modifier] || + (tsIsAccessModifier(modifier) && modified.accessibility === modifier) + ) { + this.raise(startPos, TSErrors.InvalidModifierOnTypeMember, modifier); + } + } + } }; diff --git a/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers/input.ts b/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers/input.ts new file mode 100644 index 000000000000..d79fc481ff79 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers/input.ts @@ -0,0 +1,8 @@ +interface Foo { + private a; + public b; + protected c; + static d; + declare e; + abstract f; +} diff --git a/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers/output.json b/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers/output.json new file mode 100644 index 000000000000..44587b8543b5 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers/output.json @@ -0,0 +1,102 @@ +{ + "type": "File", + "start":0,"end":96,"loc":{"start":{"line":1,"column":0},"end":{"line":8,"column":1}}, + "errors": [ + "SyntaxError: 'private' modifier cannot appear on a type member. (2:10)", + "SyntaxError: 'public' modifier cannot appear on a type member. (3:9)", + "SyntaxError: 'protected' modifier cannot appear on a type member. (4:12)", + "SyntaxError: 'static' modifier cannot appear on a type member. (5:9)", + "SyntaxError: 'declare' modifier cannot appear on a type member. (6:10)", + "SyntaxError: 'abstract' modifier cannot appear on a type member. (7:11)" + ], + "program": { + "type": "Program", + "start":0,"end":96,"loc":{"start":{"line":1,"column":0},"end":{"line":8,"column":1}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TSInterfaceDeclaration", + "start":0,"end":96,"loc":{"start":{"line":1,"column":0},"end":{"line":8,"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":96,"loc":{"start":{"line":1,"column":14},"end":{"line":8,"column":1}}, + "body": [ + { + "type": "TSPropertySignature", + "start":18,"end":28,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":12}}, + "accessibility": "private", + "key": { + "type": "Identifier", + "start":26,"end":27,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":11},"identifierName":"a"}, + "name": "a" + }, + "computed": false + }, + { + "type": "TSPropertySignature", + "start":31,"end":40,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":11}}, + "accessibility": "public", + "key": { + "type": "Identifier", + "start":38,"end":39,"loc":{"start":{"line":3,"column":9},"end":{"line":3,"column":10},"identifierName":"b"}, + "name": "b" + }, + "computed": false + }, + { + "type": "TSPropertySignature", + "start":43,"end":55,"loc":{"start":{"line":4,"column":2},"end":{"line":4,"column":14}}, + "accessibility": "protected", + "key": { + "type": "Identifier", + "start":53,"end":54,"loc":{"start":{"line":4,"column":12},"end":{"line":4,"column":13},"identifierName":"c"}, + "name": "c" + }, + "computed": false + }, + { + "type": "TSPropertySignature", + "start":58,"end":67,"loc":{"start":{"line":5,"column":2},"end":{"line":5,"column":11}}, + "static": true, + "key": { + "type": "Identifier", + "start":65,"end":66,"loc":{"start":{"line":5,"column":9},"end":{"line":5,"column":10},"identifierName":"d"}, + "name": "d" + }, + "computed": false + }, + { + "type": "TSPropertySignature", + "start":70,"end":80,"loc":{"start":{"line":6,"column":2},"end":{"line":6,"column":12}}, + "declare": true, + "key": { + "type": "Identifier", + "start":78,"end":79,"loc":{"start":{"line":6,"column":10},"end":{"line":6,"column":11},"identifierName":"e"}, + "name": "e" + }, + "computed": false + }, + { + "type": "TSPropertySignature", + "start":83,"end":94,"loc":{"start":{"line":7,"column":2},"end":{"line":7,"column":13}}, + "abstract": true, + "key": { + "type": "Identifier", + "start":92,"end":93,"loc":{"start":{"line":7,"column":11},"end":{"line":7,"column":12},"identifierName":"f"}, + "name": "f" + }, + "computed": false + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file From 9b1b5d8763797bb216062acc35605c978c69026f Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Wed, 10 Feb 2021 01:19:18 +0900 Subject: [PATCH 2/9] Rasie error when tsParseModifiers --- .../src/plugins/typescript/index.js | 55 ++++++------------- .../interface/invalid-modifiers/output.json | 12 ++-- 2 files changed, 24 insertions(+), 43 deletions(-) diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index e20a3962d131..c67b39d924c5 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -208,6 +208,7 @@ export default (superClass: Class): Class => accessibility?: N.Accessibility, }, allowedModifiers: TsModifier[], + disallowedModifiers?: TsModifier[], ): void { for (;;) { const startPos = this.state.start; @@ -227,6 +228,10 @@ export default (superClass: Class): Class => } modified[modifier] = true; } + + if (disallowedModifiers && disallowedModifiers.includes(modifier)) { + this.raise(startPos, TSErrors.InvalidModifierOnTypeMember, modifier); + } } } @@ -574,25 +579,19 @@ export default (superClass: Class): Class => } } - this.tsParseModifiers(node, [ - "readonly", - "declare", - "abstract", - "private", - "protected", - "public", - "static", - ]); - - // type members allow only 'readonly' modifier. - this.tsCheckModifiers(node, [ - "declare", - "abstract", - "private", - "protected", - "public", - "static", - ]); + this.tsParseModifiers( + node, + [ + "readonly", + "declare", + "abstract", + "private", + "protected", + "public", + "static", + ], + ["declare", "abstract", "private", "protected", "public", "static"], + ); const idx = this.tsTryParseIndexSignature(node); if (idx) { @@ -2912,22 +2911,4 @@ export default (superClass: Class): Class => this.unexpected(null, tt._class); } } - - tsCheckModifiers( - modified: { - [key: TsModifier]: ?true, - accessibility?: N.Accessibility, - }, - denylist: TsModifier[], - ): void { - const startPos = this.state.start; - for (const modifier of denylist) { - if ( - modified[modifier] || - (tsIsAccessModifier(modifier) && modified.accessibility === modifier) - ) { - this.raise(startPos, TSErrors.InvalidModifierOnTypeMember, modifier); - } - } - } }; diff --git a/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers/output.json b/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers/output.json index 44587b8543b5..be58676dc3a4 100644 --- a/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers/output.json +++ b/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers/output.json @@ -2,12 +2,12 @@ "type": "File", "start":0,"end":96,"loc":{"start":{"line":1,"column":0},"end":{"line":8,"column":1}}, "errors": [ - "SyntaxError: 'private' modifier cannot appear on a type member. (2:10)", - "SyntaxError: 'public' modifier cannot appear on a type member. (3:9)", - "SyntaxError: 'protected' modifier cannot appear on a type member. (4:12)", - "SyntaxError: 'static' modifier cannot appear on a type member. (5:9)", - "SyntaxError: 'declare' modifier cannot appear on a type member. (6:10)", - "SyntaxError: 'abstract' modifier cannot appear on a type member. (7:11)" + "SyntaxError: 'private' modifier cannot appear on a type member. (2:2)", + "SyntaxError: 'public' modifier cannot appear on a type member. (3:2)", + "SyntaxError: 'protected' modifier cannot appear on a type member. (4:2)", + "SyntaxError: 'static' modifier cannot appear on a type member. (5:2)", + "SyntaxError: 'declare' modifier cannot appear on a type member. (6:2)", + "SyntaxError: 'abstract' modifier cannot appear on a type member. (7:2)" ], "program": { "type": "Program", From 82a8e85e41995d19373094fcc77fad989c22e8af Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Wed, 10 Feb 2021 01:44:09 +0900 Subject: [PATCH 3/9] Fix tests --- .../invalid-modifiers-method/input.ts | 8 ++ .../invalid-modifiers-method/output.json | 108 ++++++++++++++++++ .../input.ts | 0 .../output.json | 0 4 files changed, 116 insertions(+) create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers-method/input.ts create mode 100644 packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers-method/output.json rename packages/babel-parser/test/fixtures/typescript/interface/{invalid-modifiers => invalid-modifiers-property}/input.ts (100%) rename packages/babel-parser/test/fixtures/typescript/interface/{invalid-modifiers => invalid-modifiers-property}/output.json (100%) diff --git a/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers-method/input.ts b/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers-method/input.ts new file mode 100644 index 000000000000..4c02426ccffd --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers-method/input.ts @@ -0,0 +1,8 @@ +interface Foo { + private a(); + public b(); + protected c(); + static d(); + declare e(); + abstract f(); +} 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 new file mode 100644 index 000000000000..20267c62052b --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers-method/output.json @@ -0,0 +1,108 @@ +{ + "type": "File", + "start":0,"end":108,"loc":{"start":{"line":1,"column":0},"end":{"line":8,"column":1}}, + "errors": [ + "SyntaxError: 'private' modifier cannot appear on a type member. (2:2)", + "SyntaxError: 'public' modifier cannot appear on a type member. (3:2)", + "SyntaxError: 'protected' modifier cannot appear on a type member. (4:2)", + "SyntaxError: 'static' modifier cannot appear on a type member. (5:2)", + "SyntaxError: 'declare' modifier cannot appear on a type member. (6:2)", + "SyntaxError: 'abstract' modifier cannot appear on a type member. (7:2)" + ], + "program": { + "type": "Program", + "start":0,"end":108,"loc":{"start":{"line":1,"column":0},"end":{"line":8,"column":1}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "TSInterfaceDeclaration", + "start":0,"end":108,"loc":{"start":{"line":1,"column":0},"end":{"line":8,"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":108,"loc":{"start":{"line":1,"column":14},"end":{"line":8,"column":1}}, + "body": [ + { + "type": "TSMethodSignature", + "start":18,"end":30,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":14}}, + "accessibility": "private", + "key": { + "type": "Identifier", + "start":26,"end":27,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":11},"identifierName":"a"}, + "name": "a" + }, + "computed": false, + "parameters": [] + }, + { + "type": "TSMethodSignature", + "start":33,"end":44,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":13}}, + "accessibility": "public", + "key": { + "type": "Identifier", + "start":40,"end":41,"loc":{"start":{"line":3,"column":9},"end":{"line":3,"column":10},"identifierName":"b"}, + "name": "b" + }, + "computed": false, + "parameters": [] + }, + { + "type": "TSMethodSignature", + "start":47,"end":61,"loc":{"start":{"line":4,"column":2},"end":{"line":4,"column":16}}, + "accessibility": "protected", + "key": { + "type": "Identifier", + "start":57,"end":58,"loc":{"start":{"line":4,"column":12},"end":{"line":4,"column":13},"identifierName":"c"}, + "name": "c" + }, + "computed": false, + "parameters": [] + }, + { + "type": "TSMethodSignature", + "start":64,"end":75,"loc":{"start":{"line":5,"column":2},"end":{"line":5,"column":13}}, + "static": true, + "key": { + "type": "Identifier", + "start":71,"end":72,"loc":{"start":{"line":5,"column":9},"end":{"line":5,"column":10},"identifierName":"d"}, + "name": "d" + }, + "computed": false, + "parameters": [] + }, + { + "type": "TSMethodSignature", + "start":78,"end":90,"loc":{"start":{"line":6,"column":2},"end":{"line":6,"column":14}}, + "declare": true, + "key": { + "type": "Identifier", + "start":86,"end":87,"loc":{"start":{"line":6,"column":10},"end":{"line":6,"column":11},"identifierName":"e"}, + "name": "e" + }, + "computed": false, + "parameters": [] + }, + { + "type": "TSMethodSignature", + "start":93,"end":106,"loc":{"start":{"line":7,"column":2},"end":{"line":7,"column":15}}, + "abstract": true, + "key": { + "type": "Identifier", + "start":102,"end":103,"loc":{"start":{"line":7,"column":11},"end":{"line":7,"column":12},"identifierName":"f"}, + "name": "f" + }, + "computed": false, + "parameters": [] + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers/input.ts b/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers-property/input.ts similarity index 100% rename from packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers/input.ts rename to packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers-property/input.ts diff --git a/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers/output.json b/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers-property/output.json similarity index 100% rename from packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers/output.json rename to packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers-property/output.json From 6739d43251f57ed76304ee6c282e7a8903f25a5f Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Wed, 10 Feb 2021 01:52:42 +0900 Subject: [PATCH 4/9] Error for readonly method signature --- .../src/plugins/typescript/index.js | 7 +++++- .../invalid-modifiers-method/input.ts | 1 + .../invalid-modifiers-method/output.json | 23 +++++++++++++++---- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index c67b39d924c5..ac633c2dbec5 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -99,6 +99,8 @@ const TSErrors = Object.freeze({ "Private elements cannot have the 'abstract' modifier.", PrivateElementHasAccessibility: "Private elements cannot have an accessibility modifier ('%0')", + ReadonlyForMethodSignature: + "'readonly' modifier can only appear on a property declaration or index signature.", TypeAnnotationAfterAssign: "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`", UnexpectedParameterModifier: @@ -543,7 +545,10 @@ export default (superClass: Class): Class => if (this.eat(tt.question)) node.optional = true; const nodeAny: any = node; - if (!readonly && (this.match(tt.parenL) || this.isRelational("<"))) { + if (this.match(tt.parenL) || this.isRelational("<")) { + if (readonly) { + this.raise(node.start, TSErrors.ReadonlyForMethodSignature); + } const method: N.TsMethodSignature = nodeAny; this.tsFillSignature(tt.colon, method); this.tsParseTypeMemberSemicolon(); diff --git a/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers-method/input.ts b/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers-method/input.ts index 4c02426ccffd..d8a52921ddc3 100644 --- a/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers-method/input.ts +++ b/packages/babel-parser/test/fixtures/typescript/interface/invalid-modifiers-method/input.ts @@ -5,4 +5,5 @@ interface Foo { static d(); declare e(); abstract f(); + readonly g(); } 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 20267c62052b..080f46b132ef 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 @@ -1,23 +1,24 @@ { "type": "File", - "start":0,"end":108,"loc":{"start":{"line":1,"column":0},"end":{"line":8,"column":1}}, + "start":0,"end":124,"loc":{"start":{"line":1,"column":0},"end":{"line":9,"column":1}}, "errors": [ "SyntaxError: 'private' modifier cannot appear on a type member. (2:2)", "SyntaxError: 'public' modifier cannot appear on a type member. (3:2)", "SyntaxError: 'protected' modifier cannot appear on a type member. (4:2)", "SyntaxError: 'static' modifier cannot appear on a type member. (5:2)", "SyntaxError: 'declare' modifier cannot appear on a type member. (6:2)", - "SyntaxError: 'abstract' modifier cannot appear on a type member. (7:2)" + "SyntaxError: 'abstract' modifier cannot appear on a type member. (7:2)", + "SyntaxError: 'readonly' modifier can only appear on a property declaration or index signature. (8:2)" ], "program": { "type": "Program", - "start":0,"end":108,"loc":{"start":{"line":1,"column":0},"end":{"line":8,"column":1}}, + "start":0,"end":124,"loc":{"start":{"line":1,"column":0},"end":{"line":9,"column":1}}, "sourceType": "module", "interpreter": null, "body": [ { "type": "TSInterfaceDeclaration", - "start":0,"end":108,"loc":{"start":{"line":1,"column":0},"end":{"line":8,"column":1}}, + "start":0,"end":124,"loc":{"start":{"line":1,"column":0},"end":{"line":9,"column":1}}, "id": { "type": "Identifier", "start":10,"end":13,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":13},"identifierName":"Foo"}, @@ -25,7 +26,7 @@ }, "body": { "type": "TSInterfaceBody", - "start":14,"end":108,"loc":{"start":{"line":1,"column":14},"end":{"line":8,"column":1}}, + "start":14,"end":124,"loc":{"start":{"line":1,"column":14},"end":{"line":9,"column":1}}, "body": [ { "type": "TSMethodSignature", @@ -98,6 +99,18 @@ }, "computed": false, "parameters": [] + }, + { + "type": "TSMethodSignature", + "start":109,"end":122,"loc":{"start":{"line":8,"column":2},"end":{"line":8,"column":15}}, + "readonly": true, + "key": { + "type": "Identifier", + "start":118,"end":119,"loc":{"start":{"line":8,"column":11},"end":{"line":8,"column":12},"identifierName":"g"}, + "name": "g" + }, + "computed": false, + "parameters": [] } ] } From ededec2ca461225eed48408356057f6f89029cb4 Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Wed, 10 Feb 2021 02:32:58 +0900 Subject: [PATCH 5/9] Use callback --- .../src/plugins/typescript/index.js | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index ac633c2dbec5..38e6b1053d2e 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -210,7 +210,7 @@ export default (superClass: Class): Class => accessibility?: N.Accessibility, }, allowedModifiers: TsModifier[], - disallowedModifiers?: TsModifier[], + callback?: (startPos: number, modifer: TsModifier) => void, ): void { for (;;) { const startPos = this.state.start; @@ -231,8 +231,8 @@ export default (superClass: Class): Class => modified[modifier] = true; } - if (disallowedModifiers && disallowedModifiers.includes(modifier)) { - this.raise(startPos, TSErrors.InvalidModifierOnTypeMember, modifier); + if (callback) { + callback(startPos, modifier); } } } @@ -584,6 +584,14 @@ export default (superClass: Class): Class => } } + const denyModifiers = [ + "declare", + "abstract", + "private", + "protected", + "public", + "static", + ]; this.tsParseModifiers( node, [ @@ -595,7 +603,15 @@ export default (superClass: Class): Class => "public", "static", ], - ["declare", "abstract", "private", "protected", "public", "static"], + (startPos, modifier) => { + if (denyModifiers.includes(modifier)) { + this.raise( + startPos, + TSErrors.InvalidModifierOnTypeMember, + modifier, + ); + } + }, ); const idx = this.tsTryParseIndexSignature(node); From c6c531a5a4993041be61108479a170ecfae77a91 Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Fri, 12 Feb 2021 05:58:46 +0900 Subject: [PATCH 6/9] Better interface --- .../src/plugins/typescript/index.js | 32 +++++++------------ 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index 38e6b1053d2e..a51f832b5f7c 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -210,7 +210,8 @@ export default (superClass: Class): Class => accessibility?: N.Accessibility, }, allowedModifiers: TsModifier[], - callback?: (startPos: number, modifer: TsModifier) => void, + disallowedModifiers?: TsModifier[], + errorTemplate?: string, ): void { for (;;) { const startPos = this.state.start; @@ -231,8 +232,12 @@ export default (superClass: Class): Class => modified[modifier] = true; } - if (callback) { - callback(startPos, modifier); + if ( + errorTemplate && + disallowedModifiers && + disallowedModifiers.includes(modifier) + ) { + this.raise(startPos, errorTemplate, modifier); } } } @@ -594,24 +599,9 @@ export default (superClass: Class): Class => ]; this.tsParseModifiers( node, - [ - "readonly", - "declare", - "abstract", - "private", - "protected", - "public", - "static", - ], - (startPos, modifier) => { - if (denyModifiers.includes(modifier)) { - this.raise( - startPos, - TSErrors.InvalidModifierOnTypeMember, - modifier, - ); - } - }, + ["readonly", ...denyModifiers], + denyModifiers, + TSErrors.InvalidModifierOnTypeMember, ); const idx = this.tsTryParseIndexSignature(node); From dc1cfe50d0f51649720e6c6062e31bb5eee17b8e Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Fri, 12 Feb 2021 07:41:12 +0900 Subject: [PATCH 7/9] Add review --- .../babel-parser/src/plugins/typescript/index.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index a51f832b5f7c..3dae6efd30a1 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -232,12 +232,13 @@ export default (superClass: Class): Class => modified[modifier] = true; } - if ( - errorTemplate && - disallowedModifiers && - disallowedModifiers.includes(modifier) - ) { - this.raise(startPos, errorTemplate, modifier); + if (disallowedModifiers && disallowedModifiers.includes(modifier)) { + this.raise( + startPos, + // $FlowIgnore + errorTemplate, + modifier, + ); } } } From 2a8212358f5b2877c79d8678b55faa6a2fe8a2bc Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Fri, 12 Feb 2021 07:47:08 +0900 Subject: [PATCH 8/9] Address review --- .../babel-parser/src/plugins/typescript/index.js | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index 3dae6efd30a1..7ab71a2f3ba3 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -215,7 +215,9 @@ export default (superClass: Class): Class => ): void { for (;;) { const startPos = this.state.start; - const modifier: ?TsModifier = this.tsParseModifier(allowedModifiers); + const modifier: ?TsModifier = this.tsParseModifier( + allowedModifiers.concat(disallowedModifiers ?? []), + ); if (!modifier) break; @@ -590,18 +592,10 @@ export default (superClass: Class): Class => } } - const denyModifiers = [ - "declare", - "abstract", - "private", - "protected", - "public", - "static", - ]; this.tsParseModifiers( node, - ["readonly", ...denyModifiers], - denyModifiers, + ["readonly"], + ["declare", "abstract", "private", "protected", "public", "static"], TSErrors.InvalidModifierOnTypeMember, ); From b79fd6bff803c665577823dc75f2bc416b6b63bb Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Sat, 13 Feb 2021 00:36:32 +0900 Subject: [PATCH 9/9] Use optional chaining --- 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 7ab71a2f3ba3..aed992336b99 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -234,7 +234,7 @@ export default (superClass: Class): Class => modified[modifier] = true; } - if (disallowedModifiers && disallowedModifiers.includes(modifier)) { + if (disallowedModifiers?.includes(modifier)) { this.raise( startPos, // $FlowIgnore