From 3b282c4c09d267fefbaae9398c88358a5967873f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Tue, 28 Apr 2020 16:43:08 -0400 Subject: [PATCH] fix: throw expect privateIn when we see tt._in after private name --- .../babel-parser/src/parser/expression.js | 15 ++-- .../_no-plugin/private-in/input.js | 7 ++ .../_no-plugin/private-in/options.json | 6 ++ .../asi-failure-generator/options.json | 2 +- .../failure-shorthand/options.json | 1 - .../failure-shorthand/output.json | 89 +++++++++++++++++++ 6 files changed, 110 insertions(+), 10 deletions(-) create mode 100644 packages/babel-parser/test/fixtures/experimental/_no-plugin/private-in/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/_no-plugin/private-in/options.json create mode 100644 packages/babel-parser/test/fixtures/experimental/class-private-properties/failure-shorthand/output.json diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index 0cf4bc3aad33..03a7a61c89f0 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -27,6 +27,7 @@ import { isReservedWord, isStrictReservedWord, isStrictBindReservedWord, + isIdentifierStart, } from "../util/identifier"; import type { Pos, Position } from "../util/location"; import * as charCodes from "charcodes"; @@ -1139,10 +1140,12 @@ export default class ExpressionParser extends LValParser { return this.finishNode(node, "PipelinePrimaryTopicReference"); } - if (this.hasPlugin("privateIn")) { + if (isIdentifierStart(this.input.codePointAt(this.state.end))) { node = (this.parseMaybePrivateName(true): N.PrivateName); - this.classScope.usePrivateName(node.id.name, node.start); - if (!this.match(tt._in)) { + if (this.match(tt._in)) { + this.expectPlugin("privateIn"); + this.classScope.usePrivateName(node.id.name, node.start); + } else { this.raise( this.state.start, Errors.PrivateInExpectedIn, @@ -1171,11 +1174,7 @@ export default class ExpressionParser extends LValParser { const isPrivate = this.match(tt.hash); if (isPrivate) { - this.expectOnePlugin([ - "classPrivateProperties", - "classPrivateMethods", - "privateIn", - ]); + this.expectOnePlugin(["classPrivateProperties", "classPrivateMethods"]); if (!isPrivateNameAllowed) { this.raise(this.state.pos, Errors.UnexpectedPrivateField); } diff --git a/packages/babel-parser/test/fixtures/experimental/_no-plugin/private-in/input.js b/packages/babel-parser/test/fixtures/experimental/_no-plugin/private-in/input.js new file mode 100644 index 000000000000..3cc8ada625d1 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/_no-plugin/private-in/input.js @@ -0,0 +1,7 @@ +class Point { + #x = 1; + #y = 2; + static isPoint(obj) { + return #x in obj && #y in obj; + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/_no-plugin/private-in/options.json b/packages/babel-parser/test/fixtures/experimental/_no-plugin/private-in/options.json new file mode 100644 index 000000000000..582e8a659ab4 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/_no-plugin/private-in/options.json @@ -0,0 +1,6 @@ +{ + "plugins": [ + "classPrivateProperties" + ], + "throws": "This experimental syntax requires enabling the parser plugin: 'privateIn' (5:14)" +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/class-private-methods/asi-failure-generator/options.json b/packages/babel-parser/test/fixtures/experimental/class-private-methods/asi-failure-generator/options.json index ab97abb8eb41..f36464eacb6a 100644 --- a/packages/babel-parser/test/fixtures/experimental/class-private-methods/asi-failure-generator/options.json +++ b/packages/babel-parser/test/fixtures/experimental/class-private-methods/asi-failure-generator/options.json @@ -1,5 +1,5 @@ { - "throws": "Unexpected token (3:3)", + "throws": "Unexpected token, expected \";\" (3:9)", "plugins": [ "classProperties", "classPrivateMethods" diff --git a/packages/babel-parser/test/fixtures/experimental/class-private-properties/failure-shorthand/options.json b/packages/babel-parser/test/fixtures/experimental/class-private-properties/failure-shorthand/options.json index 60ff5445cf7b..1ca5069a3a2f 100644 --- a/packages/babel-parser/test/fixtures/experimental/class-private-properties/failure-shorthand/options.json +++ b/packages/babel-parser/test/fixtures/experimental/class-private-properties/failure-shorthand/options.json @@ -1,5 +1,4 @@ { - "throws": "Unexpected token (4:11)", "plugins": [ "classPrivateProperties" ] diff --git a/packages/babel-parser/test/fixtures/experimental/class-private-properties/failure-shorthand/output.json b/packages/babel-parser/test/fixtures/experimental/class-private-properties/failure-shorthand/output.json new file mode 100644 index 000000000000..94683cae2e81 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-private-properties/failure-shorthand/output.json @@ -0,0 +1,89 @@ +{ + "type": "File", + "start":0,"end":56,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, + "errors": [ + "SyntaxError: Private names are only allowed in property accesses (`obj.#x`) or in `in` expressions (`#x in obj`) (4:13)" + ], + "program": { + "type": "Program", + "start":0,"end":56,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ClassDeclaration", + "start":0,"end":56,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, + "id": { + "type": "Identifier", + "start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9},"identifierName":"Foo"}, + "name": "Foo" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start":10,"end":56,"loc":{"start":{"line":1,"column":10},"end":{"line":6,"column":1}}, + "body": [ + { + "type": "ClassPrivateProperty", + "start":14,"end":17,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":5}}, + "static": false, + "key": { + "type": "PrivateName", + "start":14,"end":16,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":4}}, + "id": { + "type": "Identifier", + "start":15,"end":16,"loc":{"start":{"line":2,"column":3},"end":{"line":2,"column":4},"identifierName":"x"}, + "name": "x" + } + }, + "value": null + }, + { + "type": "ClassMethod", + "start":20,"end":54,"loc":{"start":{"line":3,"column":2},"end":{"line":5,"column":3}}, + "static": false, + "key": { + "type": "Identifier", + "start":20,"end":31,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":13},"identifierName":"constructor"}, + "name": "constructor" + }, + "computed": false, + "kind": "constructor", + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start":34,"end":54,"loc":{"start":{"line":3,"column":16},"end":{"line":5,"column":3}}, + "body": [ + { + "type": "ExpressionStatement", + "start":40,"end":50,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":14}}, + "expression": { + "type": "UnaryExpression", + "start":40,"end":49,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":13}}, + "operator": "delete", + "prefix": true, + "argument": { + "type": "PrivateName", + "start":47,"end":49,"loc":{"start":{"line":4,"column":11},"end":{"line":4,"column":13}}, + "id": { + "type": "Identifier", + "start":48,"end":49,"loc":{"start":{"line":4,"column":12},"end":{"line":4,"column":13},"identifierName":"x"}, + "name": "x" + } + } + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file