From 2660c13636817d0d45a0f84bdf970801d7b29076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Thu, 2 Sep 2021 23:23:36 +0200 Subject: [PATCH 1/6] Disallow `#a in #b in c` and similar expressions --- .../babel-parser/src/parser/expression.js | 62 ++++++--- .../asi-failure-generator/options.json | 2 +- .../invalid-private-followed-by-in-1/input.js | 7 + .../output.json | 122 ++++++++++++++++++ .../invalid-private-followed-by-in-2/input.js | 6 + .../output.json | 107 +++++++++++++++ .../invalid-private-followed-by-in-3/input.js | 7 + .../output.json | 109 ++++++++++++++++ 8 files changed, 406 insertions(+), 16 deletions(-) create mode 100644 packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-1/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-1/output.json create mode 100644 packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-2/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-2/output.json create mode 100644 packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-3/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-3/output.json diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index a7daba941ff1..15a74031a319 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -364,6 +364,14 @@ export default class ExpressionParser extends LValParser { return expr; } + parseMaybeUnaryOrPrivate( + refExpressionErrors?: ExpressionErrors, + ): N.Expression | N.PrivateName { + return this.match(tt.privateName) + ? this.parsePrivateName() + : this.parseMaybeUnary(refExpressionErrors); + } + // Start the precedence parser. // https://tc39.es/ecma262/#prod-ShortCircuitExpression @@ -371,7 +379,7 @@ export default class ExpressionParser extends LValParser { const startPos = this.state.start; const startLoc = this.state.startLoc; const potentialArrowAt = this.state.potentialArrowAt; - const expr = this.parseMaybeUnary(refExpressionErrors); + const expr = this.parseMaybeUnaryOrPrivate(refExpressionErrors); if (this.shouldExitDescending(expr, potentialArrowAt)) { return expr; @@ -387,11 +395,34 @@ export default class ExpressionParser extends LValParser { // operator that has a lower precedence than the set it is parsing. parseExprOp( - left: N.Expression, + left: N.Expression | N.PrivateName, leftStartPos: number, leftStartLoc: Position, minPrec: number, ): N.Expression { + if (this.isPrivateName(left)) { + // https://tc39.es/proposal-private-fields-in-in + // RelationalExpression [In, Yield, Await] + // [+In] PrivateIdentifier in ShiftExpression[?Yield, ?Await] + + const value = this.getPrivateNameSV(left); + const { start } = left; + + if ( + minPrec >= tt._in.binop || + !this.prodParam.hasIn || + !this.match(tt._in) + ) { + this.raise( + left.start, + Errors.PrivateInExpectedIn, + this.getPrivateNameSV(left), + ); + } + + this.classScope.usePrivateName(value, start); + } + let prec = this.state.type.binop; if (prec != null && (this.prodParam.hasIn || !this.match(tt._in))) { if (prec > minPrec) { @@ -504,7 +535,7 @@ export default class ExpressionParser extends LValParser { const startLoc = this.state.startLoc; return this.parseExprOp( - this.parseMaybeUnary(), + this.parseMaybeUnaryOrPrivate(), startPos, startLoc, op.rightAssociative ? prec - 1 : prec, @@ -1213,17 +1244,18 @@ export default class ExpressionParser extends LValParser { } case tt.privateName: { - // https://tc39.es/proposal-private-fields-in-in - // RelationalExpression [In, Yield, Await] - // [+In] PrivateIdentifier in ShiftExpression[?Yield, ?Await] - const { value, start } = this.state; - node = this.parsePrivateName(); - if (this.match(tt._in)) { - this.classScope.usePrivateName(value, start); - } else { - this.raise(start, Errors.PrivateInExpectedIn, value); - } - return node; + // Standalone private names are only allowed in "#x in obj" + // expressions, and they are directly handled by callers of + // parseExprOp. If we reach this, the input is always invalid. + // We can throw a better error message and recover, rather than + // just throwing "Unexpected token" (which is the default + // behavior of this big switch statement). + this.raise( + this.state.start, + Errors.PrivateInExpectedIn, + this.state.value, + ); + return this.parsePrivateName(); } case tt.moduloAssign: @@ -2904,7 +2936,7 @@ export default class ExpressionParser extends LValParser { this.state.inFSharpPipelineDirectBody = true; const ret = this.parseExprOp( - this.parseMaybeUnary(), + this.parseMaybeUnaryOrPrivate(), startPos, startLoc, prec, diff --git a/packages/babel-parser/test/fixtures/es2022/class-private-methods/asi-failure-generator/options.json b/packages/babel-parser/test/fixtures/es2022/class-private-methods/asi-failure-generator/options.json index 8dde42aa3f55..7261fe1a5aff 100644 --- a/packages/babel-parser/test/fixtures/es2022/class-private-methods/asi-failure-generator/options.json +++ b/packages/babel-parser/test/fixtures/es2022/class-private-methods/asi-failure-generator/options.json @@ -1,3 +1,3 @@ { - "throws": "Unexpected token (3:9)" + "throws": "Unexpected token (3:6)" } \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-1/input.js b/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-1/input.js new file mode 100644 index 000000000000..45db8afc4da7 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-1/input.js @@ -0,0 +1,7 @@ +class Foo { + #a; + #b; + method() { + #a in #b in c + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-1/output.json b/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-1/output.json new file mode 100644 index 000000000000..d58cdfa359bf --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-1/output.json @@ -0,0 +1,122 @@ +{ + "type": "File", + "start":0,"end":60,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":1}}, + "errors": [ + "SyntaxError: Private names are only allowed in property accesses (`obj.#b`) or in `in` expressions (`#b in obj`). (5:10)" + ], + "program": { + "type": "Program", + "start":0,"end":60,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ClassDeclaration", + "start":0,"end":60,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"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":60,"loc":{"start":{"line":1,"column":10},"end":{"line":7,"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":"a"}, + "name": "a" + } + }, + "value": null + }, + { + "type": "ClassPrivateProperty", + "start":20,"end":23,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":5}}, + "static": false, + "key": { + "type": "PrivateName", + "start":20,"end":22,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":4}}, + "id": { + "type": "Identifier", + "start":21,"end":22,"loc":{"start":{"line":3,"column":3},"end":{"line":3,"column":4},"identifierName":"b"}, + "name": "b" + } + }, + "value": null + }, + { + "type": "ClassMethod", + "start":26,"end":58,"loc":{"start":{"line":4,"column":2},"end":{"line":6,"column":3}}, + "static": false, + "key": { + "type": "Identifier", + "start":26,"end":32,"loc":{"start":{"line":4,"column":2},"end":{"line":4,"column":8},"identifierName":"method"}, + "name": "method" + }, + "computed": false, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start":35,"end":58,"loc":{"start":{"line":4,"column":11},"end":{"line":6,"column":3}}, + "body": [ + { + "type": "ExpressionStatement", + "start":41,"end":54,"loc":{"start":{"line":5,"column":4},"end":{"line":5,"column":17}}, + "expression": { + "type": "BinaryExpression", + "start":41,"end":54,"loc":{"start":{"line":5,"column":4},"end":{"line":5,"column":17}}, + "left": { + "type": "BinaryExpression", + "start":41,"end":49,"loc":{"start":{"line":5,"column":4},"end":{"line":5,"column":12}}, + "left": { + "type": "PrivateName", + "start":41,"end":43,"loc":{"start":{"line":5,"column":4},"end":{"line":5,"column":6}}, + "id": { + "type": "Identifier", + "start":42,"end":43,"loc":{"start":{"line":5,"column":5},"end":{"line":5,"column":6},"identifierName":"a"}, + "name": "a" + } + }, + "operator": "in", + "right": { + "type": "PrivateName", + "start":47,"end":49,"loc":{"start":{"line":5,"column":10},"end":{"line":5,"column":12}}, + "id": { + "type": "Identifier", + "start":48,"end":49,"loc":{"start":{"line":5,"column":11},"end":{"line":5,"column":12},"identifierName":"b"}, + "name": "b" + } + } + }, + "operator": "in", + "right": { + "type": "Identifier", + "start":53,"end":54,"loc":{"start":{"line":5,"column":16},"end":{"line":5,"column":17},"identifierName":"c"}, + "name": "c" + } + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-2/input.js b/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-2/input.js new file mode 100644 index 000000000000..d35caba84ed2 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-2/input.js @@ -0,0 +1,6 @@ +class Foo { + #a; + method() { + 1 + #a in b + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-2/output.json b/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-2/output.json new file mode 100644 index 000000000000..7998581fe587 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-2/output.json @@ -0,0 +1,107 @@ +{ + "type": "File", + "start":0,"end":52,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, + "errors": [ + "SyntaxError: Private names are only allowed in property accesses (`obj.#a`) or in `in` expressions (`#a in obj`). (4:8)" + ], + "program": { + "type": "Program", + "start":0,"end":52,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ClassDeclaration", + "start":0,"end":52,"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":52,"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":"a"}, + "name": "a" + } + }, + "value": null + }, + { + "type": "ClassMethod", + "start":20,"end":50,"loc":{"start":{"line":3,"column":2},"end":{"line":5,"column":3}}, + "static": false, + "key": { + "type": "Identifier", + "start":20,"end":26,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":8},"identifierName":"method"}, + "name": "method" + }, + "computed": false, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start":29,"end":50,"loc":{"start":{"line":3,"column":11},"end":{"line":5,"column":3}}, + "body": [ + { + "type": "ExpressionStatement", + "start":35,"end":46,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":15}}, + "expression": { + "type": "BinaryExpression", + "start":35,"end":46,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":15}}, + "left": { + "type": "BinaryExpression", + "start":35,"end":41,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":10}}, + "left": { + "type": "NumericLiteral", + "start":35,"end":36,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":5}}, + "extra": { + "rawValue": 1, + "raw": "1" + }, + "value": 1 + }, + "operator": "+", + "right": { + "type": "PrivateName", + "start":39,"end":41,"loc":{"start":{"line":4,"column":8},"end":{"line":4,"column":10}}, + "id": { + "type": "Identifier", + "start":40,"end":41,"loc":{"start":{"line":4,"column":9},"end":{"line":4,"column":10},"identifierName":"a"}, + "name": "a" + } + } + }, + "operator": "in", + "right": { + "type": "Identifier", + "start":45,"end":46,"loc":{"start":{"line":4,"column":14},"end":{"line":4,"column":15},"identifierName":"b"}, + "name": "b" + } + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-3/input.js b/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-3/input.js new file mode 100644 index 000000000000..d91e022aba10 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-3/input.js @@ -0,0 +1,7 @@ +class Foo { + #a; + + method() { + for (var x = #a in y); + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-3/output.json b/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-3/output.json new file mode 100644 index 000000000000..e48404c3c5e5 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-3/output.json @@ -0,0 +1,109 @@ +{ + "type": "File", + "start":0,"end":64,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":1}}, + "errors": [ + "SyntaxError: Private names are only allowed in property accesses (`obj.#a`) or in `in` expressions (`#a in obj`). (5:17)", + "SyntaxError: 'for-in' loop variable declaration may not have an initializer. (5:9)" + ], + "program": { + "type": "Program", + "start":0,"end":64,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ClassDeclaration", + "start":0,"end":64,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"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":64,"loc":{"start":{"line":1,"column":10},"end":{"line":7,"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":"a"}, + "name": "a" + } + }, + "value": null + }, + { + "type": "ClassMethod", + "start":21,"end":62,"loc":{"start":{"line":4,"column":2},"end":{"line":6,"column":3}}, + "static": false, + "key": { + "type": "Identifier", + "start":21,"end":27,"loc":{"start":{"line":4,"column":2},"end":{"line":4,"column":8},"identifierName":"method"}, + "name": "method" + }, + "computed": false, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start":30,"end":62,"loc":{"start":{"line":4,"column":11},"end":{"line":6,"column":3}}, + "body": [ + { + "type": "ForInStatement", + "start":36,"end":58,"loc":{"start":{"line":5,"column":4},"end":{"line":5,"column":26}}, + "left": { + "type": "VariableDeclaration", + "start":41,"end":51,"loc":{"start":{"line":5,"column":9},"end":{"line":5,"column":19}}, + "declarations": [ + { + "type": "VariableDeclarator", + "start":45,"end":51,"loc":{"start":{"line":5,"column":13},"end":{"line":5,"column":19}}, + "id": { + "type": "Identifier", + "start":45,"end":46,"loc":{"start":{"line":5,"column":13},"end":{"line":5,"column":14},"identifierName":"x"}, + "name": "x" + }, + "init": { + "type": "PrivateName", + "start":49,"end":51,"loc":{"start":{"line":5,"column":17},"end":{"line":5,"column":19}}, + "id": { + "type": "Identifier", + "start":50,"end":51,"loc":{"start":{"line":5,"column":18},"end":{"line":5,"column":19},"identifierName":"a"}, + "name": "a" + } + } + } + ], + "kind": "var" + }, + "right": { + "type": "Identifier", + "start":55,"end":56,"loc":{"start":{"line":5,"column":23},"end":{"line":5,"column":24},"identifierName":"y"}, + "name": "y" + }, + "body": { + "type": "EmptyStatement", + "start":57,"end":58,"loc":{"start":{"line":5,"column":25},"end":{"line":5,"column":26}} + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file From 55ec170a7dbb9bb21a1a31ef37d58123335a9a92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 3 Sep 2021 11:04:02 +0200 Subject: [PATCH 2/6] Update packages/babel-parser/src/parser/expression.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Huáng Jùnliàng --- packages/babel-parser/src/parser/expression.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index 15a74031a319..f6f7109cff3d 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -413,11 +413,7 @@ export default class ExpressionParser extends LValParser { !this.prodParam.hasIn || !this.match(tt._in) ) { - this.raise( - left.start, - Errors.PrivateInExpectedIn, - this.getPrivateNameSV(left), - ); + this.raise(start, Errors.PrivateInExpectedIn, value); } this.classScope.usePrivateName(value, start); From 04fbb060833398f330db3fdc601003ab404c239e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 3 Sep 2021 15:45:47 +0200 Subject: [PATCH 3/6] Add test for `await #x in` --- .../invalid-private-followed-by-in-4/input.js | 6 ++ .../output.json | 96 +++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-4/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-4/output.json diff --git a/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-4/input.js b/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-4/input.js new file mode 100644 index 000000000000..6248ead0cb4b --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-4/input.js @@ -0,0 +1,6 @@ +class C { + #x; + async test() { + await #x in this + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-4/output.json b/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-4/output.json new file mode 100644 index 000000000000..7b5475e5eacb --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/private-in/invalid-private-followed-by-in-4/output.json @@ -0,0 +1,96 @@ +{ + "type": "File", + "start":0,"end":59,"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:10)" + ], + "program": { + "type": "Program", + "start":0,"end":59,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ClassDeclaration", + "start":0,"end":59,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}}, + "id": { + "type": "Identifier", + "start":6,"end":7,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":7},"identifierName":"C"}, + "name": "C" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start":8,"end":59,"loc":{"start":{"line":1,"column":8},"end":{"line":6,"column":1}}, + "body": [ + { + "type": "ClassPrivateProperty", + "start":12,"end":15,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":5}}, + "static": false, + "key": { + "type": "PrivateName", + "start":12,"end":14,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":4}}, + "id": { + "type": "Identifier", + "start":13,"end":14,"loc":{"start":{"line":2,"column":3},"end":{"line":2,"column":4},"identifierName":"x"}, + "name": "x" + } + }, + "value": null + }, + { + "type": "ClassMethod", + "start":18,"end":57,"loc":{"start":{"line":3,"column":2},"end":{"line":5,"column":3}}, + "static": false, + "key": { + "type": "Identifier", + "start":24,"end":28,"loc":{"start":{"line":3,"column":8},"end":{"line":3,"column":12},"identifierName":"test"}, + "name": "test" + }, + "computed": false, + "kind": "method", + "id": null, + "generator": false, + "async": true, + "params": [], + "body": { + "type": "BlockStatement", + "start":31,"end":57,"loc":{"start":{"line":3,"column":15},"end":{"line":5,"column":3}}, + "body": [ + { + "type": "ExpressionStatement", + "start":37,"end":53,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":20}}, + "expression": { + "type": "BinaryExpression", + "start":37,"end":53,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":20}}, + "left": { + "type": "AwaitExpression", + "start":37,"end":45,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":12}}, + "argument": { + "type": "PrivateName", + "start":43,"end":45,"loc":{"start":{"line":4,"column":10},"end":{"line":4,"column":12}}, + "id": { + "type": "Identifier", + "start":44,"end":45,"loc":{"start":{"line":4,"column":11},"end":{"line":4,"column":12},"identifierName":"x"}, + "name": "x" + } + } + }, + "operator": "in", + "right": { + "type": "ThisExpression", + "start":49,"end":53,"loc":{"start":{"line":4,"column":16},"end":{"line":4,"column":20}} + } + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file From bb3d1a20375a668ae584eab99996f59a8b70bab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 3 Sep 2021 15:49:31 +0200 Subject: [PATCH 4/6] Flow --- packages/babel-parser/src/parser/expression.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index f6f7109cff3d..c75e3e824423 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -409,7 +409,7 @@ export default class ExpressionParser extends LValParser { const { start } = left; if ( - minPrec >= tt._in.binop || + minPrec >= (tt._in.binop: number) || !this.prodParam.hasIn || !this.match(tt._in) ) { From 6d800a491276c24574a2dbf9359470160261b184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Sat, 4 Sep 2021 09:36:58 +0200 Subject: [PATCH 5/6] Update flow allowlist --- scripts/parser-tests/test262/allowlist.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/parser-tests/test262/allowlist.txt b/scripts/parser-tests/test262/allowlist.txt index ee02d35010e6..8fd07d652582 100644 --- a/scripts/parser-tests/test262/allowlist.txt +++ b/scripts/parser-tests/test262/allowlist.txt @@ -1,5 +1,3 @@ -language/expressions/in/private-field-in-nested.js(default) -language/expressions/in/private-field-in-nested.js(strict mode) language/import/json-invalid.js(default) language/import/json-invalid.js(strict mode) language/import/json-named-bindings.js(default) From 7779a6c898356c593ace2f79c6a5a1c9d0e76728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Sat, 4 Sep 2021 09:46:33 +0200 Subject: [PATCH 6/6] Flow --- packages/babel-parser/src/parser/expression.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index c75e3e824423..65507e2193de 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -409,7 +409,8 @@ export default class ExpressionParser extends LValParser { const { start } = left; if ( - minPrec >= (tt._in.binop: number) || + // TODO: When migrating to TS, use tt._in.binop! + minPrec >= ((tt._in.binop: any): number) || !this.prodParam.hasIn || !this.match(tt._in) ) {