From c6e966cac95f5fb415984af430e9f1a153ec3078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Thu, 5 Dec 2019 02:23:53 -0500 Subject: [PATCH] [parser] Use scope flags to check arguments (#10801) * chore: add test case Co-authored-by: Jens Maier * use scope flags to check arguments --- .../babel-parser/src/parser/expression.js | 6 +- packages/babel-parser/src/util/scope.js | 5 +- .../input.js | 5 + .../options.json | 3 + .../output.json | 328 ++++++++++++++++++ .../arguments-in-nested-class/input.js | 5 + .../arguments-in-nested-class/options.json | 3 + .../arguments-in-nested-class/output.json | 311 +++++++++++++++++ 8 files changed, 664 insertions(+), 2 deletions(-) create mode 100644 packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class-decorator-call-expression/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class-decorator-call-expression/options.json create mode 100644 packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class-decorator-call-expression/output.json create mode 100644 packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class/options.json create mode 100644 packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class/output.json diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index 81d34b837d2d..99f0d0977929 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -2208,7 +2208,11 @@ export default class ExpressionParser extends LValParser { } } - if (this.state.inClassProperty && word === "arguments") { + if ( + this.scope.inClass && + !this.scope.inNonArrowFunction && + word === "arguments" + ) { this.raise( startLoc, "'arguments' is not allowed in class field initializer", diff --git a/packages/babel-parser/src/util/scope.js b/packages/babel-parser/src/util/scope.js index e40cb53e3e33..f367ae5e76b6 100644 --- a/packages/babel-parser/src/util/scope.js +++ b/packages/babel-parser/src/util/scope.js @@ -64,6 +64,9 @@ export default class ScopeHandler { get allowDirectSuper() { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0; } + get inClass() { + return (this.currentThisScope().flags & SCOPE_CLASS) > 0; + } get inNonArrowFunction() { return (this.currentThisScope().flags & SCOPE_FUNCTION) > 0; } @@ -199,7 +202,7 @@ export default class ScopeHandler { } } - // Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`. + // Could be useful for `arguments`, `this`, `new.target`, `super()`, `super.property`, and `super[property]`. // $FlowIgnore currentThisScope(): IScope { for (let i = this.scopeStack.length - 1; ; i--) { diff --git a/packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class-decorator-call-expression/input.js b/packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class-decorator-call-expression/input.js new file mode 100644 index 000000000000..4594b01a45b6 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class-decorator-call-expression/input.js @@ -0,0 +1,5 @@ +function fn() { + class A { + foo = class B { @bar(arguments) foo }; + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class-decorator-call-expression/options.json b/packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class-decorator-call-expression/options.json new file mode 100644 index 000000000000..c61fa716aeb5 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class-decorator-call-expression/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classProperties", ["decorators", { "decoratorsBeforeExport": false }]] +} diff --git a/packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class-decorator-call-expression/output.json b/packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class-decorator-call-expression/output.json new file mode 100644 index 000000000000..deb781226e7f --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class-decorator-call-expression/output.json @@ -0,0 +1,328 @@ +{ + "type": "File", + "start": 0, + "end": 76, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "errors": [ + "SyntaxError: 'arguments' is not allowed in class field initializer (3:25)" + ], + "program": { + "type": "Program", + "start": 0, + "end": 76, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "FunctionDeclaration", + "start": 0, + "end": 76, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 9, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 11 + }, + "identifierName": "fn" + }, + "name": "fn" + }, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 14, + "end": 76, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "body": [ + { + "type": "ClassDeclaration", + "start": 18, + "end": 74, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 4, + "column": 3 + } + }, + "id": { + "type": "Identifier", + "start": 24, + "end": 25, + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 9 + }, + "identifierName": "A" + }, + "name": "A" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 26, + "end": 74, + "loc": { + "start": { + "line": 2, + "column": 10 + }, + "end": { + "line": 4, + "column": 3 + } + }, + "body": [ + { + "type": "ClassProperty", + "start": 32, + "end": 70, + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 42 + } + }, + "static": false, + "key": { + "type": "Identifier", + "start": 32, + "end": 35, + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 7 + }, + "identifierName": "foo" + }, + "name": "foo" + }, + "computed": false, + "value": { + "type": "ClassExpression", + "start": 38, + "end": 69, + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 41 + } + }, + "id": { + "type": "Identifier", + "start": 44, + "end": 45, + "loc": { + "start": { + "line": 3, + "column": 16 + }, + "end": { + "line": 3, + "column": 17 + }, + "identifierName": "B" + }, + "name": "B" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 46, + "end": 69, + "loc": { + "start": { + "line": 3, + "column": 18 + }, + "end": { + "line": 3, + "column": 41 + } + }, + "body": [ + { + "type": "ClassProperty", + "start": 48, + "end": 67, + "loc": { + "start": { + "line": 3, + "column": 20 + }, + "end": { + "line": 3, + "column": 39 + } + }, + "decorators": [ + { + "type": "Decorator", + "start": 48, + "end": 63, + "loc": { + "start": { + "line": 3, + "column": 20 + }, + "end": { + "line": 3, + "column": 35 + } + }, + "expression": { + "type": "CallExpression", + "start": 49, + "end": 63, + "loc": { + "start": { + "line": 3, + "column": 21 + }, + "end": { + "line": 3, + "column": 35 + } + }, + "callee": { + "type": "Identifier", + "start": 49, + "end": 52, + "loc": { + "start": { + "line": 3, + "column": 21 + }, + "end": { + "line": 3, + "column": 24 + }, + "identifierName": "bar" + }, + "name": "bar" + }, + "arguments": [ + { + "type": "Identifier", + "start": 53, + "end": 62, + "loc": { + "start": { + "line": 3, + "column": 25 + }, + "end": { + "line": 3, + "column": 34 + }, + "identifierName": "arguments" + }, + "name": "arguments" + } + ] + } + } + ], + "static": false, + "key": { + "type": "Identifier", + "start": 64, + "end": 67, + "loc": { + "start": { + "line": 3, + "column": 36 + }, + "end": { + "line": 3, + "column": 39 + }, + "identifierName": "foo" + }, + "name": "foo" + }, + "computed": false, + "value": null + } + ] + } + } + } + ] + } + } + ], + "directives": [] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class/input.js b/packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class/input.js new file mode 100644 index 000000000000..5bcc6b3ee5fa --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class/input.js @@ -0,0 +1,5 @@ +function fn() { + class A { + foo = class B { bar() { arguments } }; + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class/options.json b/packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class/options.json new file mode 100644 index 000000000000..9c27576d4ad0 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classProperties"] +} diff --git a/packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class/output.json b/packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class/output.json new file mode 100644 index 000000000000..107a090b5e92 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-properties/arguments-in-nested-class/output.json @@ -0,0 +1,311 @@ +{ + "type": "File", + "start": 0, + "end": 76, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 76, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "FunctionDeclaration", + "start": 0, + "end": 76, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 9, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 11 + }, + "identifierName": "fn" + }, + "name": "fn" + }, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 14, + "end": 76, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "body": [ + { + "type": "ClassDeclaration", + "start": 18, + "end": 74, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 4, + "column": 3 + } + }, + "id": { + "type": "Identifier", + "start": 24, + "end": 25, + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 9 + }, + "identifierName": "A" + }, + "name": "A" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 26, + "end": 74, + "loc": { + "start": { + "line": 2, + "column": 10 + }, + "end": { + "line": 4, + "column": 3 + } + }, + "body": [ + { + "type": "ClassProperty", + "start": 32, + "end": 70, + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 42 + } + }, + "static": false, + "key": { + "type": "Identifier", + "start": 32, + "end": 35, + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 7 + }, + "identifierName": "foo" + }, + "name": "foo" + }, + "computed": false, + "value": { + "type": "ClassExpression", + "start": 38, + "end": 69, + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 41 + } + }, + "id": { + "type": "Identifier", + "start": 44, + "end": 45, + "loc": { + "start": { + "line": 3, + "column": 16 + }, + "end": { + "line": 3, + "column": 17 + }, + "identifierName": "B" + }, + "name": "B" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 46, + "end": 69, + "loc": { + "start": { + "line": 3, + "column": 18 + }, + "end": { + "line": 3, + "column": 41 + } + }, + "body": [ + { + "type": "ClassMethod", + "start": 48, + "end": 67, + "loc": { + "start": { + "line": 3, + "column": 20 + }, + "end": { + "line": 3, + "column": 39 + } + }, + "static": false, + "key": { + "type": "Identifier", + "start": 48, + "end": 51, + "loc": { + "start": { + "line": 3, + "column": 20 + }, + "end": { + "line": 3, + "column": 23 + }, + "identifierName": "bar" + }, + "name": "bar" + }, + "computed": false, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 54, + "end": 67, + "loc": { + "start": { + "line": 3, + "column": 26 + }, + "end": { + "line": 3, + "column": 39 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 56, + "end": 65, + "loc": { + "start": { + "line": 3, + "column": 28 + }, + "end": { + "line": 3, + "column": 37 + } + }, + "expression": { + "type": "Identifier", + "start": 56, + "end": 65, + "loc": { + "start": { + "line": 3, + "column": 28 + }, + "end": { + "line": 3, + "column": 37 + }, + "identifierName": "arguments" + }, + "name": "arguments" + } + } + ], + "directives": [] + } + } + ] + } + } + } + ] + } + } + ], + "directives": [] + } + } + ], + "directives": [] + } +} \ No newline at end of file