From d0af3a83304aba1cde9ec87508b509b474b8e4f2 Mon Sep 17 00:00:00 2001 From: overlookmotel Date: Wed, 2 Nov 2022 02:38:48 +0000 Subject: [PATCH 1/3] Parse option to allow `new.target` outside functions --- packages/babel-parser/data/schema.json | 4 +++ packages/babel-parser/src/options.ts | 4 +++ .../babel-parser/src/parser/expression.ts | 6 +++- .../input.js | 1 + .../options.json | 4 +++ .../input.js | 1 + .../options.json | 4 +++ .../output.json | 31 +++++++++++++++++++ .../babel-parser/typings/babel-parser.d.ts | 6 ++++ 9 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false/input.js create mode 100644 packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false/options.json create mode 100644 packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/input.js create mode 100644 packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/options.json create mode 100644 packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/output.json diff --git a/packages/babel-parser/data/schema.json b/packages/babel-parser/data/schema.json index 569e6747d1b3..ec354824d433 100644 --- a/packages/babel-parser/data/schema.json +++ b/packages/babel-parser/data/schema.json @@ -49,6 +49,10 @@ "description": "By default, a return statement at the top level raises an error.\nSet this to true to accept such code.", "type": "boolean" }, + "allowNewTargetOutsideFunction": { + "description": "By default, new.target use is not allowed outside of a function or class.\nSet this to true to accept such code.", + "type": "boolean" + }, "allowSuperOutsideMethod": { "type": "boolean" }, diff --git a/packages/babel-parser/src/options.ts b/packages/babel-parser/src/options.ts index 7abf8ba5d56a..72649f45935a 100644 --- a/packages/babel-parser/src/options.ts +++ b/packages/babel-parser/src/options.ts @@ -12,6 +12,7 @@ export type Options = { startLine: number; allowAwaitOutsideFunction: boolean; allowReturnOutsideFunction: boolean; + allowNewTargetOutsideFunction: boolean; allowImportExportEverywhere: boolean; allowSuperOutsideMethod: boolean; allowUndeclaredExports: boolean; @@ -42,6 +43,9 @@ export const defaultOptions: Options = { // When enabled, a return at the top level is not considered an // error. allowReturnOutsideFunction: false, + // When enabled, new.target at the top level is not considered an + // error. + allowNewTargetOutsideFunction: false, // When enabled, import/export statements are not constrained to // appearing at the top of the program. allowImportExportEverywhere: false, diff --git a/packages/babel-parser/src/parser/expression.ts b/packages/babel-parser/src/parser/expression.ts index 49f3eb5aa98a..60313e3d7138 100644 --- a/packages/babel-parser/src/parser/expression.ts +++ b/packages/babel-parser/src/parser/expression.ts @@ -1880,7 +1880,11 @@ export default abstract class ExpressionParser extends LValParser { "target", ); - if (!this.scope.inNonArrowFunction && !this.scope.inClass) { + if ( + !this.scope.inNonArrowFunction && + !this.scope.inClass && + !this.options.allowNewTargetOutsideFunction + ) { this.raise(Errors.UnexpectedNewTarget, { at: metaProp }); } diff --git a/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false/input.js b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false/input.js new file mode 100644 index 000000000000..6cf5edffe11b --- /dev/null +++ b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false/input.js @@ -0,0 +1 @@ +new.target diff --git a/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false/options.json b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false/options.json new file mode 100644 index 000000000000..9add1c5bbdee --- /dev/null +++ b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false/options.json @@ -0,0 +1,4 @@ +{ + "errorRecovery": false, + "throws": "`new.target` can only be used in functions or class properties. (1:0)" +} diff --git a/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/input.js b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/input.js new file mode 100644 index 000000000000..6cf5edffe11b --- /dev/null +++ b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/input.js @@ -0,0 +1 @@ +new.target diff --git a/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/options.json b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/options.json new file mode 100644 index 000000000000..ec9099e4a969 --- /dev/null +++ b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/options.json @@ -0,0 +1,4 @@ +{ + "allowNewTargetOutsideFunction": true, + "errorRecovery": false +} diff --git a/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/output.json b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/output.json new file mode 100644 index 000000000000..fd9400e52285 --- /dev/null +++ b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/output.json @@ -0,0 +1,31 @@ +{ + "type": "File", + "start":0,"end":10,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":10,"index":10}}, + "program": { + "type": "Program", + "start":0,"end":10,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":10,"index":10}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":10,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":10,"index":10}}, + "expression": { + "type": "MetaProperty", + "start":0,"end":10,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":10,"index":10}}, + "meta": { + "type": "Identifier", + "start":0,"end":3,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":3,"index":3},"identifierName":"new"}, + "name": "new" + }, + "property": { + "type": "Identifier", + "start":4,"end":10,"loc":{"start":{"line":1,"column":4,"index":4},"end":{"line":1,"column":10,"index":10},"identifierName":"target"}, + "name": "target" + } + } + } + ], + "directives": [] + } +} diff --git a/packages/babel-parser/typings/babel-parser.d.ts b/packages/babel-parser/typings/babel-parser.d.ts index b806352dbb35..e04fb4fb9459 100644 --- a/packages/babel-parser/typings/babel-parser.d.ts +++ b/packages/babel-parser/typings/babel-parser.d.ts @@ -122,6 +122,12 @@ interface ParserOptions { */ allowReturnOutsideFunction?: boolean; + /** + * By default, new.target use is not allowed outside of a function or class. + * Set this to true to accept such code. + */ + allowNewTargetOutsideFunction?: boolean; + allowSuperOutsideMethod?: boolean; /** From aee6416282307b22b7d09b4d2aec0c9fd608c11c Mon Sep 17 00:00:00 2001 From: overlookmotel Date: Thu, 3 Nov 2022 22:51:10 +0000 Subject: [PATCH 2/3] Test for within arrow functions --- .../input.js | 1 + .../options.json | 4 + .../input.js | 2 +- .../options.json | 2 +- .../input.js | 3 +- .../output.json | 84 +++++++++++++++---- 6 files changed, 76 insertions(+), 20 deletions(-) create mode 100644 packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false-2/input.js create mode 100644 packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false-2/options.json diff --git a/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false-2/input.js b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false-2/input.js new file mode 100644 index 000000000000..608666efc9bf --- /dev/null +++ b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false-2/input.js @@ -0,0 +1 @@ +const y = () => new.target; diff --git a/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false-2/options.json b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false-2/options.json new file mode 100644 index 000000000000..88c709852466 --- /dev/null +++ b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false-2/options.json @@ -0,0 +1,4 @@ +{ + "errorRecovery": false, + "throws": "`new.target` can only be used in functions or class properties. (1:16)" +} diff --git a/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false/input.js b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false/input.js index 6cf5edffe11b..85f7e4833373 100644 --- a/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false/input.js +++ b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false/input.js @@ -1 +1 @@ -new.target +const x = new.target; diff --git a/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false/options.json b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false/options.json index 9add1c5bbdee..a090fd8b90d8 100644 --- a/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false/options.json +++ b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-false/options.json @@ -1,4 +1,4 @@ { "errorRecovery": false, - "throws": "`new.target` can only be used in functions or class properties. (1:0)" + "throws": "`new.target` can only be used in functions or class properties. (1:10)" } diff --git a/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/input.js b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/input.js index 6cf5edffe11b..2896f435a2a3 100644 --- a/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/input.js +++ b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/input.js @@ -1 +1,2 @@ -new.target +const x = new.target; +const y = () => new.target; diff --git a/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/output.json b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/output.json index fd9400e52285..53eb2339ca5e 100644 --- a/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/output.json +++ b/packages/babel-parser/test/fixtures/core/opts/allowNewTargetOutsideFunction-true/output.json @@ -1,29 +1,79 @@ { "type": "File", - "start":0,"end":10,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":10,"index":10}}, + "start":0,"end":49,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":2,"column":27,"index":49}}, "program": { "type": "Program", - "start":0,"end":10,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":10,"index":10}}, + "start":0,"end":49,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":2,"column":27,"index":49}}, "sourceType": "script", "interpreter": null, "body": [ { - "type": "ExpressionStatement", - "start":0,"end":10,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":10,"index":10}}, - "expression": { - "type": "MetaProperty", - "start":0,"end":10,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":10,"index":10}}, - "meta": { - "type": "Identifier", - "start":0,"end":3,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":3,"index":3},"identifierName":"new"}, - "name": "new" - }, - "property": { - "type": "Identifier", - "start":4,"end":10,"loc":{"start":{"line":1,"column":4,"index":4},"end":{"line":1,"column":10,"index":10},"identifierName":"target"}, - "name": "target" + "type": "VariableDeclaration", + "start":0,"end":21,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":21,"index":21}}, + "declarations": [ + { + "type": "VariableDeclarator", + "start":6,"end":20,"loc":{"start":{"line":1,"column":6,"index":6},"end":{"line":1,"column":20,"index":20}}, + "id": { + "type": "Identifier", + "start":6,"end":7,"loc":{"start":{"line":1,"column":6,"index":6},"end":{"line":1,"column":7,"index":7},"identifierName":"x"}, + "name": "x" + }, + "init": { + "type": "MetaProperty", + "start":10,"end":20,"loc":{"start":{"line":1,"column":10,"index":10},"end":{"line":1,"column":20,"index":20}}, + "meta": { + "type": "Identifier", + "start":10,"end":13,"loc":{"start":{"line":1,"column":10,"index":10},"end":{"line":1,"column":13,"index":13},"identifierName":"new"}, + "name": "new" + }, + "property": { + "type": "Identifier", + "start":14,"end":20,"loc":{"start":{"line":1,"column":14,"index":14},"end":{"line":1,"column":20,"index":20},"identifierName":"target"}, + "name": "target" + } + } } - } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start":22,"end":49,"loc":{"start":{"line":2,"column":0,"index":22},"end":{"line":2,"column":27,"index":49}}, + "declarations": [ + { + "type": "VariableDeclarator", + "start":28,"end":48,"loc":{"start":{"line":2,"column":6,"index":28},"end":{"line":2,"column":26,"index":48}}, + "id": { + "type": "Identifier", + "start":28,"end":29,"loc":{"start":{"line":2,"column":6,"index":28},"end":{"line":2,"column":7,"index":29},"identifierName":"y"}, + "name": "y" + }, + "init": { + "type": "ArrowFunctionExpression", + "start":32,"end":48,"loc":{"start":{"line":2,"column":10,"index":32},"end":{"line":2,"column":26,"index":48}}, + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "MetaProperty", + "start":38,"end":48,"loc":{"start":{"line":2,"column":16,"index":38},"end":{"line":2,"column":26,"index":48}}, + "meta": { + "type": "Identifier", + "start":38,"end":41,"loc":{"start":{"line":2,"column":16,"index":38},"end":{"line":2,"column":19,"index":41},"identifierName":"new"}, + "name": "new" + }, + "property": { + "type": "Identifier", + "start":42,"end":48,"loc":{"start":{"line":2,"column":20,"index":42},"end":{"line":2,"column":26,"index":48},"identifierName":"target"}, + "name": "target" + } + } + } + } + ], + "kind": "const" } ], "directives": [] From bf0316b6adac81be2ce50da78951144158579479 Mon Sep 17 00:00:00 2001 From: overlookmotel Date: Thu, 3 Nov 2022 22:53:31 +0000 Subject: [PATCH 3/3] Change option description --- packages/babel-parser/src/options.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/babel-parser/src/options.ts b/packages/babel-parser/src/options.ts index 72649f45935a..91aaa2593026 100644 --- a/packages/babel-parser/src/options.ts +++ b/packages/babel-parser/src/options.ts @@ -43,8 +43,8 @@ export const defaultOptions: Options = { // When enabled, a return at the top level is not considered an // error. allowReturnOutsideFunction: false, - // When enabled, new.target at the top level is not considered an - // error. + // When enabled, new.target outside a function or class is not + // considered an error. allowNewTargetOutsideFunction: false, // When enabled, import/export statements are not constrained to // appearing at the top of the program.