From b0e6902876e5cfeb7bd3266fd55ee92a12c20a3b Mon Sep 17 00:00:00 2001 From: Justin Ridgewell Date: Thu, 12 Mar 2020 01:28:21 -0400 Subject: [PATCH] Handle private access chained on an optional chain See the resolution from https://github.com/tc39/proposal-class-fields/pull/301. --- .../src/fields.js | 54 +- .../src/index.js | 115 ++- .../babel-parser/src/parser/expression.js | 5 +- packages/babel-parser/src/parser/location.js | 2 + .../optional-chain-object/input.js | 14 + .../optional-chain-object/options.json | 3 + .../optional-chain-object/output.json | 969 ++++++++++++++++++ .../optional-chain-start-call/input.js | 7 + .../optional-chain-start-call/options.json | 3 + .../optional-chain-start-call/output.json | 326 ++++++ .../optional-chain-start-member-call/input.js | 7 + .../options.json | 3 + .../output.json | 365 +++++++ .../optional-chain-start-member/input.js | 7 + .../optional-chain-start-member/options.json | 3 + .../optional-chain-start-member/output.json | 328 ++++++ .../optional-chain-start-simple/input.js | 7 + .../optional-chain-start-simple/options.json | 3 + .../optional-chain-start-simple/output.json | 294 ++++++ .../optional-chain-with-transform/exec.js | 25 + .../optional-chain-with-transform/input.js | 25 + .../options.json | 6 + .../optional-chain-with-transform/output.js | 47 + .../private-loose/optional-chain/input.js | 25 + .../private-loose/optional-chain/options.json | 3 + .../private-loose/optional-chain/output.js | 47 + .../optional-chain-with-transform/exec.js | 25 + .../optional-chain-with-transform/input.js | 25 + .../options.json | 3 + .../optional-chain-with-transform/output.js | 43 + .../fixtures/private/optional-chain/input.js | 25 + .../private/optional-chain/options.json | 3 + .../fixtures/private/optional-chain/output.js | 43 + 33 files changed, 2831 insertions(+), 29 deletions(-) create mode 100644 packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-object/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-object/options.json create mode 100644 packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-object/output.json create mode 100644 packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-call/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-call/options.json create mode 100644 packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-call/output.json create mode 100644 packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member-call/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member-call/options.json create mode 100644 packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member-call/output.json create mode 100644 packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member/options.json create mode 100644 packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member/output.json create mode 100644 packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-simple/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-simple/options.json create mode 100644 packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-simple/output.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain-with-transform/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain-with-transform/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain-with-transform/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain-with-transform/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain-with-transform/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain-with-transform/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain-with-transform/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain-with-transform/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain/output.js diff --git a/packages/babel-helper-create-class-features-plugin/src/fields.js b/packages/babel-helper-create-class-features-plugin/src/fields.js index 167e894cae33f..688f724f7c13d 100644 --- a/packages/babel-helper-create-class-features-plugin/src/fields.js +++ b/packages/babel-helper-create-class-features-plugin/src/fields.js @@ -75,7 +75,12 @@ const privateNameVisitor = { const { privateNamesMap } = this; const { node, parentPath } = path; - if (!parentPath.isMemberExpression({ property: node })) return; + if ( + !parentPath.isMemberExpression({ property: node }) && + !parentPath.isOptionalMemberExpression({ property: node }) + ) { + return; + } if (!privateNamesMap.has(node.id.name)) return; this.handle(parentPath); @@ -241,18 +246,28 @@ const privateNameHandlerSpec = { }; const privateNameHandlerLoose = { - handle(member) { + get(member) { const { privateNamesMap, file } = this; const { object } = member.node; const { name } = member.node.property.id; - member.replaceWith( - template.expression`BASE(REF, PROP)[PROP]`({ - BASE: file.addHelper("classPrivateFieldLooseBase"), - REF: object, - PROP: privateNamesMap.get(name).id, - }), - ); + return template.expression`BASE(REF, PROP)[PROP]`({ + BASE: file.addHelper("classPrivateFieldLooseBase"), + REF: object, + PROP: privateNamesMap.get(name).id, + }); + }, + + simpleSet(member) { + return this.get(member); + }, + + destructureSet(member) { + return this.get(member); + }, + + call(member, args) { + return t.callExpression(this.get(member), args); }, }; @@ -264,21 +279,14 @@ export function transformPrivateNamesUsage( state, ) { const body = path.get("body"); + const handler = loose ? privateNameHandlerLoose : privateNameHandlerSpec; - if (loose) { - body.traverse(privateNameVisitor, { - privateNamesMap, - file: state, - ...privateNameHandlerLoose, - }); - } else { - memberExpressionToFunctions(body, privateNameVisitor, { - privateNamesMap, - classRef: ref, - file: state, - ...privateNameHandlerSpec, - }); - } + memberExpressionToFunctions(body, privateNameVisitor, { + privateNamesMap, + classRef: ref, + file: state, + ...handler, + }); } function buildPrivateFieldInitLoose(ref, prop, privateNamesMap) { diff --git a/packages/babel-helper-member-expression-to-functions/src/index.js b/packages/babel-helper-member-expression-to-functions/src/index.js index 88b8514c2cdfe..28d814df35df9 100644 --- a/packages/babel-helper-member-expression-to-functions/src/index.js +++ b/packages/babel-helper-member-expression-to-functions/src/index.js @@ -37,9 +37,113 @@ const handle = { handle(member) { const { node, parent, parentPath } = member; + if (member.isOptionalMemberExpression()) { + const root = member.find(({ node, parent, parentPath }) => { + if (parentPath.isOptionalMemberExpression()) { + return parent.optional || parent.object !== node; + } + if (parentPath.isOptionalCallExpression()) { + return parent.optional || parent.callee !== node; + } + return true; + }); + + const rootParentPath = root.parentPath; + if ( + rootParentPath.isUpdateExpression({ argument: node }) || + rootParentPath.isAssignmentExpression({ left: node }) + ) { + throw member.buildCodeFrameError(`can't handle assignment`); + } + if (rootParentPath.isUnaryExpression({ operator: "delete" })) { + throw member.buildCodeFrameError(`can't handle delete`); + } + + if (node.optional) { + throw member.buildCodeFrameError( + `can't handle '?.' directly before ${node.property.type}`, + ); + } + + let nearestOptional = member; + for (;;) { + if (nearestOptional.isOptionalMemberExpression()) { + if (nearestOptional.node.optional) break; + nearestOptional = nearestOptional.get("object"); + continue; + } else if (nearestOptional.isOptionalCallExpression()) { + if (nearestOptional.node.optional) break; + nearestOptional = nearestOptional.get("object"); + continue; + } + + throw nearestOptional.buildCodeFrameError( + "failed to find nearest optional", + ); + } + + const { scope } = member; + const { object } = node; + const baseRef = scope.generateUidIdentifierBasedOnNode( + nearestOptional.node.object, + ); + const valueRef = scope.generateUidIdentifierBasedOnNode(object); + scope.push({ id: baseRef }); + scope.push({ id: valueRef }); + + nearestOptional + .get("object") + .replaceWith( + t.assignmentExpression("=", baseRef, nearestOptional.node.object), + ); + member.replaceWith(t.memberExpression(valueRef, node.property)); + + if (parentPath.isOptionalCallExpression({ callee: node })) { + parentPath.replaceWith(this.call(member, parent.arguments)); + } else { + member.replaceWith(this.get(member)); + } + + let regular = member.node; + for (let current = member; current !== root; ) { + const { parentPath, parent } = current; + if (parentPath.isOptionalMemberExpression()) { + regular = t.memberExpression( + regular, + parent.property, + parent.computed, + ); + } else { + regular = t.callExpression(regular, parent.arguments); + } + current = parentPath; + } + + root.replaceWith( + t.conditionalExpression( + t.sequenceExpression([ + t.assignmentExpression("=", valueRef, object), + t.logicalExpression( + "||", + t.binaryExpression("===", baseRef, scope.buildUndefinedNode()), + t.binaryExpression("===", baseRef, t.nullLiteral()), + ), + ]), + scope.buildUndefinedNode(), + regular, + ), + ); + return; + } + // MEMBER++ -> _set(MEMBER, (_ref = (+_get(MEMBER))) + 1), _ref // ++MEMBER -> _set(MEMBER, (+_get(MEMBER)) + 1) if (parentPath.isUpdateExpression({ argument: node })) { + if (this.simpleSet) { + member.replaceWith(this.simpleSet(member)); + return; + } + const { operator, prefix } = parent; // Give the state handler a chance to memoise the member, since we'll @@ -72,6 +176,11 @@ const handle = { // MEMBER = VALUE -> _set(MEMBER, VALUE) // MEMBER += VALUE -> _set(MEMBER, _get(MEMBER) + VALUE) if (parentPath.isAssignmentExpression({ left: node })) { + if (this.simpleSet) { + member.replaceWith(this.simpleSet(member)); + return; + } + const { operator, right } = parent; let value = right; @@ -92,11 +201,9 @@ const handle = { return; } - // MEMBER(ARGS) -> _call(MEMBER, ARGS) + // MEMBER(ARGS) -> _call(MEMBER, ARGS) if (parentPath.isCallExpression({ callee: node })) { - const { arguments: args } = parent; - - parentPath.replaceWith(this.call(member, args)); + parentPath.replaceWith(this.call(member, parent.arguments)); return; } diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index 91f49064c3724..e81f12f1deb9e 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -610,8 +610,6 @@ export default class ExpressionParser extends LValParser { node.object = base; node.property = computed ? this.parseExpression() - : optional - ? this.parseIdentifier(true) : this.parseMaybePrivateName(true); node.computed = computed; @@ -619,6 +617,9 @@ export default class ExpressionParser extends LValParser { if (node.object.type === "Super") { this.raise(startPos, Errors.SuperPrivateField); } + if (optional) { + this.raise(node.property.start, Errors.OptionalChainingNoPrivate); + } this.classScope.usePrivateName( node.property.id.name, node.property.start, diff --git a/packages/babel-parser/src/parser/location.js b/packages/babel-parser/src/parser/location.js index fc548b0b726e5..799a445ae0174 100644 --- a/packages/babel-parser/src/parser/location.js +++ b/packages/babel-parser/src/parser/location.js @@ -109,6 +109,8 @@ export const Errors = Object.freeze({ "await* has been removed from the async functions proposal. Use Promise.all() instead.", OptionalChainingNoNew: "constructors in/after an Optional Chain are not allowed", + OptionalChainingNoPrivate: + "Private property access cannot immediately follow an optional chain's `?.`", OptionalChainingNoTemplate: "Tagged Template Literals are not allowed in optionalChain", ParamDupe: "Argument name clash", diff --git a/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-object/input.js b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-object/input.js new file mode 100644 index 0000000000000..8f152088b2ef5 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-object/input.js @@ -0,0 +1,14 @@ +class Foo { + static #x = 1; + static #m = function() {}; + + static test() { + const o = { Foo: Foo }; + return [ + o?.Foo.#x, + o?.Foo.#x.toFixed, + o?.Foo.#x.toFixed(2), + o?.Foo.#m(), + ]; + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-object/options.json b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-object/options.json new file mode 100644 index 0000000000000..f26e916957c88 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-object/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classPrivateProperties"] +} diff --git a/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-object/output.json b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-object/output.json new file mode 100644 index 0000000000000..26ce1f65e3a9c --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-object/output.json @@ -0,0 +1,969 @@ +{ + "type": "File", + "start": 0, + "end": 219, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 14, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 219, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 14, + "column": 1 + } + }, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 219, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 14, + "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": 219, + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 14, + "column": 1 + } + }, + "body": [ + { + "type": "ClassPrivateProperty", + "start": 14, + "end": 28, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 16 + } + }, + "static": true, + "key": { + "type": "PrivateName", + "start": 21, + "end": 23, + "loc": { + "start": { + "line": 2, + "column": 9 + }, + "end": { + "line": 2, + "column": 11 + } + }, + "id": { + "type": "Identifier", + "start": 22, + "end": 23, + "loc": { + "start": { + "line": 2, + "column": 10 + }, + "end": { + "line": 2, + "column": 11 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "value": { + "type": "NumericLiteral", + "start": 26, + "end": 27, + "loc": { + "start": { + "line": 2, + "column": 14 + }, + "end": { + "line": 2, + "column": 15 + } + }, + "extra": { + "rawValue": 1, + "raw": "1" + }, + "value": 1 + } + }, + { + "type": "ClassPrivateProperty", + "start": 31, + "end": 57, + "loc": { + "start": { + "line": 3, + "column": 2 + }, + "end": { + "line": 3, + "column": 28 + } + }, + "static": true, + "key": { + "type": "PrivateName", + "start": 38, + "end": 40, + "loc": { + "start": { + "line": 3, + "column": 9 + }, + "end": { + "line": 3, + "column": 11 + } + }, + "id": { + "type": "Identifier", + "start": 39, + "end": 40, + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 11 + }, + "identifierName": "m" + }, + "name": "m" + } + }, + "value": { + "type": "FunctionExpression", + "start": 43, + "end": 56, + "loc": { + "start": { + "line": 3, + "column": 14 + }, + "end": { + "line": 3, + "column": 27 + } + }, + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 54, + "end": 56, + "loc": { + "start": { + "line": 3, + "column": 25 + }, + "end": { + "line": 3, + "column": 27 + } + }, + "body": [], + "directives": [] + } + } + }, + { + "type": "ClassMethod", + "start": 61, + "end": 217, + "loc": { + "start": { + "line": 5, + "column": 2 + }, + "end": { + "line": 13, + "column": 3 + } + }, + "static": true, + "key": { + "type": "Identifier", + "start": 68, + "end": 72, + "loc": { + "start": { + "line": 5, + "column": 9 + }, + "end": { + "line": 5, + "column": 13 + }, + "identifierName": "test" + }, + "name": "test" + }, + "computed": false, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 75, + "end": 217, + "loc": { + "start": { + "line": 5, + "column": 16 + }, + "end": { + "line": 13, + "column": 3 + } + }, + "body": [ + { + "type": "VariableDeclaration", + "start": 81, + "end": 104, + "loc": { + "start": { + "line": 6, + "column": 4 + }, + "end": { + "line": 6, + "column": 27 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 87, + "end": 103, + "loc": { + "start": { + "line": 6, + "column": 10 + }, + "end": { + "line": 6, + "column": 26 + } + }, + "id": { + "type": "Identifier", + "start": 87, + "end": 88, + "loc": { + "start": { + "line": 6, + "column": 10 + }, + "end": { + "line": 6, + "column": 11 + }, + "identifierName": "o" + }, + "name": "o" + }, + "init": { + "type": "ObjectExpression", + "start": 91, + "end": 103, + "loc": { + "start": { + "line": 6, + "column": 14 + }, + "end": { + "line": 6, + "column": 26 + } + }, + "properties": [ + { + "type": "ObjectProperty", + "start": 93, + "end": 101, + "loc": { + "start": { + "line": 6, + "column": 16 + }, + "end": { + "line": 6, + "column": 24 + } + }, + "method": false, + "key": { + "type": "Identifier", + "start": 93, + "end": 96, + "loc": { + "start": { + "line": 6, + "column": 16 + }, + "end": { + "line": 6, + "column": 19 + }, + "identifierName": "Foo" + }, + "name": "Foo" + }, + "computed": false, + "shorthand": false, + "value": { + "type": "Identifier", + "start": 98, + "end": 101, + "loc": { + "start": { + "line": 6, + "column": 21 + }, + "end": { + "line": 6, + "column": 24 + }, + "identifierName": "Foo" + }, + "name": "Foo" + } + } + ] + } + } + ], + "kind": "const" + }, + { + "type": "ReturnStatement", + "start": 109, + "end": 213, + "loc": { + "start": { + "line": 7, + "column": 4 + }, + "end": { + "line": 12, + "column": 6 + } + }, + "argument": { + "type": "ArrayExpression", + "start": 116, + "end": 212, + "loc": { + "start": { + "line": 7, + "column": 11 + }, + "end": { + "line": 12, + "column": 5 + } + }, + "extra": { + "trailingComma": 205 + }, + "elements": [ + { + "type": "OptionalMemberExpression", + "start": 124, + "end": 133, + "loc": { + "start": { + "line": 8, + "column": 6 + }, + "end": { + "line": 8, + "column": 15 + } + }, + "object": { + "type": "OptionalMemberExpression", + "start": 124, + "end": 130, + "loc": { + "start": { + "line": 8, + "column": 6 + }, + "end": { + "line": 8, + "column": 12 + } + }, + "object": { + "type": "Identifier", + "start": 124, + "end": 125, + "loc": { + "start": { + "line": 8, + "column": 6 + }, + "end": { + "line": 8, + "column": 7 + }, + "identifierName": "o" + }, + "name": "o" + }, + "property": { + "type": "Identifier", + "start": 127, + "end": 130, + "loc": { + "start": { + "line": 8, + "column": 9 + }, + "end": { + "line": 8, + "column": 12 + }, + "identifierName": "Foo" + }, + "name": "Foo" + }, + "computed": false, + "optional": true + }, + "property": { + "type": "PrivateName", + "start": 131, + "end": 133, + "loc": { + "start": { + "line": 8, + "column": 13 + }, + "end": { + "line": 8, + "column": 15 + } + }, + "id": { + "type": "Identifier", + "start": 132, + "end": 133, + "loc": { + "start": { + "line": 8, + "column": 14 + }, + "end": { + "line": 8, + "column": 15 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "computed": false, + "optional": false + }, + { + "type": "OptionalMemberExpression", + "start": 141, + "end": 158, + "loc": { + "start": { + "line": 9, + "column": 6 + }, + "end": { + "line": 9, + "column": 23 + } + }, + "object": { + "type": "OptionalMemberExpression", + "start": 141, + "end": 150, + "loc": { + "start": { + "line": 9, + "column": 6 + }, + "end": { + "line": 9, + "column": 15 + } + }, + "object": { + "type": "OptionalMemberExpression", + "start": 141, + "end": 147, + "loc": { + "start": { + "line": 9, + "column": 6 + }, + "end": { + "line": 9, + "column": 12 + } + }, + "object": { + "type": "Identifier", + "start": 141, + "end": 142, + "loc": { + "start": { + "line": 9, + "column": 6 + }, + "end": { + "line": 9, + "column": 7 + }, + "identifierName": "o" + }, + "name": "o" + }, + "property": { + "type": "Identifier", + "start": 144, + "end": 147, + "loc": { + "start": { + "line": 9, + "column": 9 + }, + "end": { + "line": 9, + "column": 12 + }, + "identifierName": "Foo" + }, + "name": "Foo" + }, + "computed": false, + "optional": true + }, + "property": { + "type": "PrivateName", + "start": 148, + "end": 150, + "loc": { + "start": { + "line": 9, + "column": 13 + }, + "end": { + "line": 9, + "column": 15 + } + }, + "id": { + "type": "Identifier", + "start": 149, + "end": 150, + "loc": { + "start": { + "line": 9, + "column": 14 + }, + "end": { + "line": 9, + "column": 15 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 151, + "end": 158, + "loc": { + "start": { + "line": 9, + "column": 16 + }, + "end": { + "line": 9, + "column": 23 + }, + "identifierName": "toFixed" + }, + "name": "toFixed" + }, + "computed": false, + "optional": false + }, + { + "type": "OptionalCallExpression", + "start": 166, + "end": 186, + "loc": { + "start": { + "line": 10, + "column": 6 + }, + "end": { + "line": 10, + "column": 26 + } + }, + "callee": { + "type": "OptionalMemberExpression", + "start": 166, + "end": 183, + "loc": { + "start": { + "line": 10, + "column": 6 + }, + "end": { + "line": 10, + "column": 23 + } + }, + "object": { + "type": "OptionalMemberExpression", + "start": 166, + "end": 175, + "loc": { + "start": { + "line": 10, + "column": 6 + }, + "end": { + "line": 10, + "column": 15 + } + }, + "object": { + "type": "OptionalMemberExpression", + "start": 166, + "end": 172, + "loc": { + "start": { + "line": 10, + "column": 6 + }, + "end": { + "line": 10, + "column": 12 + } + }, + "object": { + "type": "Identifier", + "start": 166, + "end": 167, + "loc": { + "start": { + "line": 10, + "column": 6 + }, + "end": { + "line": 10, + "column": 7 + }, + "identifierName": "o" + }, + "name": "o" + }, + "property": { + "type": "Identifier", + "start": 169, + "end": 172, + "loc": { + "start": { + "line": 10, + "column": 9 + }, + "end": { + "line": 10, + "column": 12 + }, + "identifierName": "Foo" + }, + "name": "Foo" + }, + "computed": false, + "optional": true + }, + "property": { + "type": "PrivateName", + "start": 173, + "end": 175, + "loc": { + "start": { + "line": 10, + "column": 13 + }, + "end": { + "line": 10, + "column": 15 + } + }, + "id": { + "type": "Identifier", + "start": 174, + "end": 175, + "loc": { + "start": { + "line": 10, + "column": 14 + }, + "end": { + "line": 10, + "column": 15 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "computed": false, + "optional": false + }, + "property": { + "type": "Identifier", + "start": 176, + "end": 183, + "loc": { + "start": { + "line": 10, + "column": 16 + }, + "end": { + "line": 10, + "column": 23 + }, + "identifierName": "toFixed" + }, + "name": "toFixed" + }, + "computed": false, + "optional": false + }, + "arguments": [ + { + "type": "NumericLiteral", + "start": 184, + "end": 185, + "loc": { + "start": { + "line": 10, + "column": 24 + }, + "end": { + "line": 10, + "column": 25 + } + }, + "extra": { + "rawValue": 2, + "raw": "2" + }, + "value": 2 + } + ] + }, + { + "type": "OptionalCallExpression", + "start": 194, + "end": 205, + "loc": { + "start": { + "line": 11, + "column": 6 + }, + "end": { + "line": 11, + "column": 17 + } + }, + "callee": { + "type": "OptionalMemberExpression", + "start": 194, + "end": 203, + "loc": { + "start": { + "line": 11, + "column": 6 + }, + "end": { + "line": 11, + "column": 15 + } + }, + "object": { + "type": "OptionalMemberExpression", + "start": 194, + "end": 200, + "loc": { + "start": { + "line": 11, + "column": 6 + }, + "end": { + "line": 11, + "column": 12 + } + }, + "object": { + "type": "Identifier", + "start": 194, + "end": 195, + "loc": { + "start": { + "line": 11, + "column": 6 + }, + "end": { + "line": 11, + "column": 7 + }, + "identifierName": "o" + }, + "name": "o" + }, + "property": { + "type": "Identifier", + "start": 197, + "end": 200, + "loc": { + "start": { + "line": 11, + "column": 9 + }, + "end": { + "line": 11, + "column": 12 + }, + "identifierName": "Foo" + }, + "name": "Foo" + }, + "computed": false, + "optional": true + }, + "property": { + "type": "PrivateName", + "start": 201, + "end": 203, + "loc": { + "start": { + "line": 11, + "column": 13 + }, + "end": { + "line": 11, + "column": 15 + } + }, + "id": { + "type": "Identifier", + "start": 202, + "end": 203, + "loc": { + "start": { + "line": 11, + "column": 14 + }, + "end": { + "line": 11, + "column": 15 + }, + "identifierName": "m" + }, + "name": "m" + } + }, + "computed": false, + "optional": false + }, + "arguments": [] + } + ] + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-call/input.js b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-call/input.js new file mode 100644 index 0000000000000..861a7c7211959 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-call/input.js @@ -0,0 +1,7 @@ +class Foo { + static #m = function() {}; + + static test() { + return Foo?.#m(); + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-call/options.json b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-call/options.json new file mode 100644 index 0000000000000..f26e916957c88 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-call/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classPrivateProperties"] +} diff --git a/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-call/output.json b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-call/output.json new file mode 100644 index 0000000000000..3497b7a02ac3b --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-call/output.json @@ -0,0 +1,326 @@ +{ + "type": "File", + "start": 0, + "end": 87, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 7, + "column": 1 + } + }, + "errors": [ + "SyntaxError: Private property access cannot immediately follow an optional chain's `?.` (5:16)" + ], + "program": { + "type": "Program", + "start": 0, + "end": 87, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 7, + "column": 1 + } + }, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 87, + "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": 87, + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 7, + "column": 1 + } + }, + "body": [ + { + "type": "ClassPrivateProperty", + "start": 14, + "end": 40, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 28 + } + }, + "static": true, + "key": { + "type": "PrivateName", + "start": 21, + "end": 23, + "loc": { + "start": { + "line": 2, + "column": 9 + }, + "end": { + "line": 2, + "column": 11 + } + }, + "id": { + "type": "Identifier", + "start": 22, + "end": 23, + "loc": { + "start": { + "line": 2, + "column": 10 + }, + "end": { + "line": 2, + "column": 11 + }, + "identifierName": "m" + }, + "name": "m" + } + }, + "value": { + "type": "FunctionExpression", + "start": 26, + "end": 39, + "loc": { + "start": { + "line": 2, + "column": 14 + }, + "end": { + "line": 2, + "column": 27 + } + }, + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 37, + "end": 39, + "loc": { + "start": { + "line": 2, + "column": 25 + }, + "end": { + "line": 2, + "column": 27 + } + }, + "body": [], + "directives": [] + } + } + }, + { + "type": "ClassMethod", + "start": 44, + "end": 85, + "loc": { + "start": { + "line": 4, + "column": 2 + }, + "end": { + "line": 6, + "column": 3 + } + }, + "static": true, + "key": { + "type": "Identifier", + "start": 51, + "end": 55, + "loc": { + "start": { + "line": 4, + "column": 9 + }, + "end": { + "line": 4, + "column": 13 + }, + "identifierName": "test" + }, + "name": "test" + }, + "computed": false, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 58, + "end": 85, + "loc": { + "start": { + "line": 4, + "column": 16 + }, + "end": { + "line": 6, + "column": 3 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 64, + "end": 81, + "loc": { + "start": { + "line": 5, + "column": 4 + }, + "end": { + "line": 5, + "column": 21 + } + }, + "argument": { + "type": "OptionalCallExpression", + "start": 71, + "end": 80, + "loc": { + "start": { + "line": 5, + "column": 11 + }, + "end": { + "line": 5, + "column": 20 + } + }, + "callee": { + "type": "OptionalMemberExpression", + "start": 71, + "end": 78, + "loc": { + "start": { + "line": 5, + "column": 11 + }, + "end": { + "line": 5, + "column": 18 + } + }, + "object": { + "type": "Identifier", + "start": 71, + "end": 74, + "loc": { + "start": { + "line": 5, + "column": 11 + }, + "end": { + "line": 5, + "column": 14 + }, + "identifierName": "Foo" + }, + "name": "Foo" + }, + "property": { + "type": "PrivateName", + "start": 76, + "end": 78, + "loc": { + "start": { + "line": 5, + "column": 16 + }, + "end": { + "line": 5, + "column": 18 + } + }, + "id": { + "type": "Identifier", + "start": 77, + "end": 78, + "loc": { + "start": { + "line": 5, + "column": 17 + }, + "end": { + "line": 5, + "column": 18 + }, + "identifierName": "m" + }, + "name": "m" + } + }, + "computed": false, + "optional": true + }, + "arguments": [] + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member-call/input.js b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member-call/input.js new file mode 100644 index 0000000000000..93e0a61c975b9 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member-call/input.js @@ -0,0 +1,7 @@ +class Foo { + static #x = 1; + + static test() { + return Foo?.#x.toFixed(2); + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member-call/options.json b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member-call/options.json new file mode 100644 index 0000000000000..f26e916957c88 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member-call/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classPrivateProperties"] +} diff --git a/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member-call/output.json b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member-call/output.json new file mode 100644 index 0000000000000..61c1f6485f5c7 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member-call/output.json @@ -0,0 +1,365 @@ +{ + "type": "File", + "start": 0, + "end": 84, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 7, + "column": 1 + } + }, + "errors": [ + "SyntaxError: Private property access cannot immediately follow an optional chain's `?.` (5:16)" + ], + "program": { + "type": "Program", + "start": 0, + "end": 84, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 7, + "column": 1 + } + }, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 84, + "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": 84, + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 7, + "column": 1 + } + }, + "body": [ + { + "type": "ClassPrivateProperty", + "start": 14, + "end": 28, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 16 + } + }, + "static": true, + "key": { + "type": "PrivateName", + "start": 21, + "end": 23, + "loc": { + "start": { + "line": 2, + "column": 9 + }, + "end": { + "line": 2, + "column": 11 + } + }, + "id": { + "type": "Identifier", + "start": 22, + "end": 23, + "loc": { + "start": { + "line": 2, + "column": 10 + }, + "end": { + "line": 2, + "column": 11 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "value": { + "type": "NumericLiteral", + "start": 26, + "end": 27, + "loc": { + "start": { + "line": 2, + "column": 14 + }, + "end": { + "line": 2, + "column": 15 + } + }, + "extra": { + "rawValue": 1, + "raw": "1" + }, + "value": 1 + } + }, + { + "type": "ClassMethod", + "start": 32, + "end": 82, + "loc": { + "start": { + "line": 4, + "column": 2 + }, + "end": { + "line": 6, + "column": 3 + } + }, + "static": true, + "key": { + "type": "Identifier", + "start": 39, + "end": 43, + "loc": { + "start": { + "line": 4, + "column": 9 + }, + "end": { + "line": 4, + "column": 13 + }, + "identifierName": "test" + }, + "name": "test" + }, + "computed": false, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 46, + "end": 82, + "loc": { + "start": { + "line": 4, + "column": 16 + }, + "end": { + "line": 6, + "column": 3 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 52, + "end": 78, + "loc": { + "start": { + "line": 5, + "column": 4 + }, + "end": { + "line": 5, + "column": 30 + } + }, + "argument": { + "type": "OptionalCallExpression", + "start": 59, + "end": 77, + "loc": { + "start": { + "line": 5, + "column": 11 + }, + "end": { + "line": 5, + "column": 29 + } + }, + "callee": { + "type": "OptionalMemberExpression", + "start": 59, + "end": 74, + "loc": { + "start": { + "line": 5, + "column": 11 + }, + "end": { + "line": 5, + "column": 26 + } + }, + "object": { + "type": "OptionalMemberExpression", + "start": 59, + "end": 66, + "loc": { + "start": { + "line": 5, + "column": 11 + }, + "end": { + "line": 5, + "column": 18 + } + }, + "object": { + "type": "Identifier", + "start": 59, + "end": 62, + "loc": { + "start": { + "line": 5, + "column": 11 + }, + "end": { + "line": 5, + "column": 14 + }, + "identifierName": "Foo" + }, + "name": "Foo" + }, + "property": { + "type": "PrivateName", + "start": 64, + "end": 66, + "loc": { + "start": { + "line": 5, + "column": 16 + }, + "end": { + "line": 5, + "column": 18 + } + }, + "id": { + "type": "Identifier", + "start": 65, + "end": 66, + "loc": { + "start": { + "line": 5, + "column": 17 + }, + "end": { + "line": 5, + "column": 18 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "computed": false, + "optional": true + }, + "property": { + "type": "Identifier", + "start": 67, + "end": 74, + "loc": { + "start": { + "line": 5, + "column": 19 + }, + "end": { + "line": 5, + "column": 26 + }, + "identifierName": "toFixed" + }, + "name": "toFixed" + }, + "computed": false, + "optional": false + }, + "arguments": [ + { + "type": "NumericLiteral", + "start": 75, + "end": 76, + "loc": { + "start": { + "line": 5, + "column": 27 + }, + "end": { + "line": 5, + "column": 28 + } + }, + "extra": { + "rawValue": 2, + "raw": "2" + }, + "value": 2 + } + ] + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member/input.js b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member/input.js new file mode 100644 index 0000000000000..48bc5c3a3ffd0 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member/input.js @@ -0,0 +1,7 @@ +class Foo { + static #x = 1; + + static test() { + return Foo?.#x.toFixed; + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member/options.json b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member/options.json new file mode 100644 index 0000000000000..f26e916957c88 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classPrivateProperties"] +} diff --git a/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member/output.json b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member/output.json new file mode 100644 index 0000000000000..61d54387aff6a --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-member/output.json @@ -0,0 +1,328 @@ +{ + "type": "File", + "start": 0, + "end": 81, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 7, + "column": 1 + } + }, + "errors": [ + "SyntaxError: Private property access cannot immediately follow an optional chain's `?.` (5:16)" + ], + "program": { + "type": "Program", + "start": 0, + "end": 81, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 7, + "column": 1 + } + }, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 81, + "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": 81, + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 7, + "column": 1 + } + }, + "body": [ + { + "type": "ClassPrivateProperty", + "start": 14, + "end": 28, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 16 + } + }, + "static": true, + "key": { + "type": "PrivateName", + "start": 21, + "end": 23, + "loc": { + "start": { + "line": 2, + "column": 9 + }, + "end": { + "line": 2, + "column": 11 + } + }, + "id": { + "type": "Identifier", + "start": 22, + "end": 23, + "loc": { + "start": { + "line": 2, + "column": 10 + }, + "end": { + "line": 2, + "column": 11 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "value": { + "type": "NumericLiteral", + "start": 26, + "end": 27, + "loc": { + "start": { + "line": 2, + "column": 14 + }, + "end": { + "line": 2, + "column": 15 + } + }, + "extra": { + "rawValue": 1, + "raw": "1" + }, + "value": 1 + } + }, + { + "type": "ClassMethod", + "start": 32, + "end": 79, + "loc": { + "start": { + "line": 4, + "column": 2 + }, + "end": { + "line": 6, + "column": 3 + } + }, + "static": true, + "key": { + "type": "Identifier", + "start": 39, + "end": 43, + "loc": { + "start": { + "line": 4, + "column": 9 + }, + "end": { + "line": 4, + "column": 13 + }, + "identifierName": "test" + }, + "name": "test" + }, + "computed": false, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 46, + "end": 79, + "loc": { + "start": { + "line": 4, + "column": 16 + }, + "end": { + "line": 6, + "column": 3 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 52, + "end": 75, + "loc": { + "start": { + "line": 5, + "column": 4 + }, + "end": { + "line": 5, + "column": 27 + } + }, + "argument": { + "type": "OptionalMemberExpression", + "start": 59, + "end": 74, + "loc": { + "start": { + "line": 5, + "column": 11 + }, + "end": { + "line": 5, + "column": 26 + } + }, + "object": { + "type": "OptionalMemberExpression", + "start": 59, + "end": 66, + "loc": { + "start": { + "line": 5, + "column": 11 + }, + "end": { + "line": 5, + "column": 18 + } + }, + "object": { + "type": "Identifier", + "start": 59, + "end": 62, + "loc": { + "start": { + "line": 5, + "column": 11 + }, + "end": { + "line": 5, + "column": 14 + }, + "identifierName": "Foo" + }, + "name": "Foo" + }, + "property": { + "type": "PrivateName", + "start": 64, + "end": 66, + "loc": { + "start": { + "line": 5, + "column": 16 + }, + "end": { + "line": 5, + "column": 18 + } + }, + "id": { + "type": "Identifier", + "start": 65, + "end": 66, + "loc": { + "start": { + "line": 5, + "column": 17 + }, + "end": { + "line": 5, + "column": 18 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "computed": false, + "optional": true + }, + "property": { + "type": "Identifier", + "start": 67, + "end": 74, + "loc": { + "start": { + "line": 5, + "column": 19 + }, + "end": { + "line": 5, + "column": 26 + }, + "identifierName": "toFixed" + }, + "name": "toFixed" + }, + "computed": false, + "optional": false + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-simple/input.js b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-simple/input.js new file mode 100644 index 0000000000000..4802298ea3792 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-simple/input.js @@ -0,0 +1,7 @@ +class Foo { + static #x = 1; + + static test() { + return Foo?.#x; + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-simple/options.json b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-simple/options.json new file mode 100644 index 0000000000000..f26e916957c88 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-simple/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classPrivateProperties"] +} diff --git a/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-simple/output.json b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-simple/output.json new file mode 100644 index 0000000000000..8f9da5de5c119 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/class-private-properties/optional-chain-start-simple/output.json @@ -0,0 +1,294 @@ +{ + "type": "File", + "start": 0, + "end": 73, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 7, + "column": 1 + } + }, + "errors": [ + "SyntaxError: Private property access cannot immediately follow an optional chain's `?.` (5:16)" + ], + "program": { + "type": "Program", + "start": 0, + "end": 73, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 7, + "column": 1 + } + }, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 73, + "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": 73, + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 7, + "column": 1 + } + }, + "body": [ + { + "type": "ClassPrivateProperty", + "start": 14, + "end": 28, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 16 + } + }, + "static": true, + "key": { + "type": "PrivateName", + "start": 21, + "end": 23, + "loc": { + "start": { + "line": 2, + "column": 9 + }, + "end": { + "line": 2, + "column": 11 + } + }, + "id": { + "type": "Identifier", + "start": 22, + "end": 23, + "loc": { + "start": { + "line": 2, + "column": 10 + }, + "end": { + "line": 2, + "column": 11 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "value": { + "type": "NumericLiteral", + "start": 26, + "end": 27, + "loc": { + "start": { + "line": 2, + "column": 14 + }, + "end": { + "line": 2, + "column": 15 + } + }, + "extra": { + "rawValue": 1, + "raw": "1" + }, + "value": 1 + } + }, + { + "type": "ClassMethod", + "start": 32, + "end": 71, + "loc": { + "start": { + "line": 4, + "column": 2 + }, + "end": { + "line": 6, + "column": 3 + } + }, + "static": true, + "key": { + "type": "Identifier", + "start": 39, + "end": 43, + "loc": { + "start": { + "line": 4, + "column": 9 + }, + "end": { + "line": 4, + "column": 13 + }, + "identifierName": "test" + }, + "name": "test" + }, + "computed": false, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 46, + "end": 71, + "loc": { + "start": { + "line": 4, + "column": 16 + }, + "end": { + "line": 6, + "column": 3 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 52, + "end": 67, + "loc": { + "start": { + "line": 5, + "column": 4 + }, + "end": { + "line": 5, + "column": 19 + } + }, + "argument": { + "type": "OptionalMemberExpression", + "start": 59, + "end": 66, + "loc": { + "start": { + "line": 5, + "column": 11 + }, + "end": { + "line": 5, + "column": 18 + } + }, + "object": { + "type": "Identifier", + "start": 59, + "end": 62, + "loc": { + "start": { + "line": 5, + "column": 11 + }, + "end": { + "line": 5, + "column": 14 + }, + "identifierName": "Foo" + }, + "name": "Foo" + }, + "property": { + "type": "PrivateName", + "start": 64, + "end": 66, + "loc": { + "start": { + "line": 5, + "column": 16 + }, + "end": { + "line": 5, + "column": 18 + } + }, + "id": { + "type": "Identifier", + "start": 65, + "end": 66, + "loc": { + "start": { + "line": 5, + "column": 17 + }, + "end": { + "line": 5, + "column": 18 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "computed": false, + "optional": true + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain-with-transform/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain-with-transform/exec.js new file mode 100644 index 0000000000000..215802ead54a1 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain-with-transform/exec.js @@ -0,0 +1,25 @@ +class Foo { + static #x = 1; + static #self = Foo; + static self = Foo; + + static test() { + const o = { Foo: Foo }; + const deep = { very: { o } }; + expect(o?.Foo.#x).toEqual(1); + expect(o?.Foo.#x.toString).toEqual(1..toString); + expect(o?.Foo.#x.toString()).toEqual('1'); + + expect(deep?.very.o?.Foo.#x).toEqual(1); + expect(deep?.very.o?.Foo.#x.toString).toEqual(1..toString); + expect(deep?.very.o?.Foo.#x.toString()).toEqual('1'); + + expect(o?.Foo.#self.#x).toEqual(1); + expect(o?.Foo.#self.self.#x).toEqual(1); + expect(o?.Foo.#self?.self.#x).toEqual(1); + expect(o?.Foo.#self.self?.self.#x).toEqual(1); + expect(o?.Foo.#self?.self?.self.#x).toEqual(1); + } +} + +Foo.test(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain-with-transform/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain-with-transform/input.js new file mode 100644 index 0000000000000..e8f18bd86f692 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain-with-transform/input.js @@ -0,0 +1,25 @@ +class Foo { + static #x = 1; + static #self = Foo; + static self = Foo; + + static test() { + const o = { Foo: Foo }; + const deep = { very: { o } }; + o?.Foo.#x; + o?.Foo.#x.toString; + o?.Foo.#x.toString(); + + deep?.very.o?.Foo.#x; + deep?.very.o?.Foo.#x.toString; + deep?.very.o?.Foo.#x.toString(); + + o?.Foo.#self.#x; + o?.Foo.#self.self.#x; + o?.Foo.#self?.self.#x; + o?.Foo.#self.self?.self.#x; + o?.Foo.#self?.self?.self.#x; + } +} + +Foo.test(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain-with-transform/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain-with-transform/options.json new file mode 100644 index 0000000000000..9a7eaaa890b36 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain-with-transform/options.json @@ -0,0 +1,6 @@ +{ + "plugins": [ + "proposal-optional-chaining", + ["proposal-class-properties", { "loose": true }] + ] +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain-with-transform/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain-with-transform/output.js new file mode 100644 index 0000000000000..458ddc1685e5c --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain-with-transform/output.js @@ -0,0 +1,47 @@ +function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } + +var id = 0; + +function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; } + +class Foo { + static test() { + var _o, _ref, _o2, _ref2, _o3, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9, _o4, _ref10, _o5, _ref11, _o6, _ref12, _ref13, _ref14, _o7, _ref15, _ref16, _ref17, _o8, _ref18, _ref19, _ref20, _o9, _o10, _o11, _ref21, _ref22, _ref23, _o12, _o13, _ref24, _o14, _ref25, _o15, _ref26, _ref27, _o16; + + const o = { + Foo: Foo + }; + const deep = { + very: { + o + } + }; + (_ref = (_o9 = _o = o) === null || _o9 === void 0 ? void 0 : _o9.Foo, _o === void 0 || _o === null) ? void 0 : _classPrivateFieldLooseBase(_ref, _x)[_x]; + (_ref2 = (_o10 = _o2 = o) === null || _o10 === void 0 ? void 0 : _o10.Foo, _o2 === void 0 || _o2 === null) ? void 0 : _classPrivateFieldLooseBase(_ref2, _x)[_x].toString; + (_ref3 = (_o11 = _o3 = o) === null || _o11 === void 0 ? void 0 : _o11.Foo, _o3 === void 0 || _o3 === null) ? void 0 : _classPrivateFieldLooseBase(_ref3, _x)[_x].toString(); + (_ref5 = (_ref21 = _ref4 = deep === null || deep === void 0 ? void 0 : deep.very.o) === null || _ref21 === void 0 ? void 0 : _ref21.Foo, _ref4 === void 0 || _ref4 === null) ? void 0 : _classPrivateFieldLooseBase(_ref5, _x)[_x]; + (_ref7 = (_ref22 = _ref6 = deep === null || deep === void 0 ? void 0 : deep.very.o) === null || _ref22 === void 0 ? void 0 : _ref22.Foo, _ref6 === void 0 || _ref6 === null) ? void 0 : _classPrivateFieldLooseBase(_ref7, _x)[_x].toString; + (_ref9 = (_ref23 = _ref8 = deep === null || deep === void 0 ? void 0 : deep.very.o) === null || _ref23 === void 0 ? void 0 : _ref23.Foo, _ref8 === void 0 || _ref8 === null) ? void 0 : _classPrivateFieldLooseBase(_ref9, _x)[_x].toString(); + (_ref10 = (_o12 = _o4 = o) === null || _o12 === void 0 ? void 0 : _o12.Foo, _o4 === void 0 || _o4 === null) ? void 0 : _classPrivateFieldLooseBase(_classPrivateFieldLooseBase(_ref10, _self)[_self], _x)[_x]; + (_ref11 = (_o13 = _o5 = o) === null || _o13 === void 0 ? void 0 : _o13.Foo, _o5 === void 0 || _o5 === null) ? void 0 : _classPrivateFieldLooseBase(_classPrivateFieldLooseBase(_ref11, _self)[_self].self, _x)[_x]; + (_ref14 = (_ref24 = _ref13 = (_ref12 = (_o14 = _o6 = o) === null || _o14 === void 0 ? void 0 : _o14.Foo, _o6 === void 0 || _o6 === null) ? void 0 : _classPrivateFieldLooseBase(_ref12, _self)[_self]) === null || _ref24 === void 0 ? void 0 : _ref24.self, _ref13 === void 0 || _ref13 === null) ? void 0 : _classPrivateFieldLooseBase(_ref14, _x)[_x]; + (_ref17 = (_ref25 = _ref16 = (_ref15 = (_o15 = _o7 = o) === null || _o15 === void 0 ? void 0 : _o15.Foo, _o7 === void 0 || _o7 === null) ? void 0 : _classPrivateFieldLooseBase(_ref15, _self)[_self].self) === null || _ref25 === void 0 ? void 0 : _ref25.self, _ref16 === void 0 || _ref16 === null) ? void 0 : _classPrivateFieldLooseBase(_ref17, _x)[_x]; + (_ref20 = (_ref26 = _ref19 = (_ref27 = (_ref18 = (_o16 = _o8 = o) === null || _o16 === void 0 ? void 0 : _o16.Foo, _o8 === void 0 || _o8 === null) ? void 0 : _classPrivateFieldLooseBase(_ref18, _self)[_self]) === null || _ref27 === void 0 ? void 0 : _ref27.self) === null || _ref26 === void 0 ? void 0 : _ref26.self, _ref19 === void 0 || _ref19 === null) ? void 0 : _classPrivateFieldLooseBase(_ref20, _x)[_x]; + } + +} + +var _x = _classPrivateFieldLooseKey("x"); + +var _self = _classPrivateFieldLooseKey("self"); + +Object.defineProperty(Foo, _x, { + writable: true, + value: 1 +}); +Object.defineProperty(Foo, _self, { + writable: true, + value: Foo +}); +Foo.self = Foo; +Foo.test(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain/input.js new file mode 100644 index 0000000000000..e8f18bd86f692 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain/input.js @@ -0,0 +1,25 @@ +class Foo { + static #x = 1; + static #self = Foo; + static self = Foo; + + static test() { + const o = { Foo: Foo }; + const deep = { very: { o } }; + o?.Foo.#x; + o?.Foo.#x.toString; + o?.Foo.#x.toString(); + + deep?.very.o?.Foo.#x; + deep?.very.o?.Foo.#x.toString; + deep?.very.o?.Foo.#x.toString(); + + o?.Foo.#self.#x; + o?.Foo.#self.self.#x; + o?.Foo.#self?.self.#x; + o?.Foo.#self.self?.self.#x; + o?.Foo.#self?.self?.self.#x; + } +} + +Foo.test(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain/options.json new file mode 100644 index 0000000000000..693db86a79a07 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-class-properties", { "loose": true }]] +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain/output.js new file mode 100644 index 0000000000000..5d6339cd6a2fa --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/optional-chain/output.js @@ -0,0 +1,47 @@ +function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } + +var id = 0; + +function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; } + +class Foo { + static test() { + var _o, _ref, _o2, _ref2, _o3, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9, _o4, _ref10, _o5, _ref11, _o6, _ref12, _ref13, _ref14, _o7, _ref15, _ref16, _ref17, _o8, _ref18, _ref19, _ref20; + + const o = { + Foo: Foo + }; + const deep = { + very: { + o + } + }; + (_ref = (_o = o)?.Foo, _o === void 0 || _o === null) ? void 0 : _classPrivateFieldLooseBase(_ref, _x)[_x]; + (_ref2 = (_o2 = o)?.Foo, _o2 === void 0 || _o2 === null) ? void 0 : _classPrivateFieldLooseBase(_ref2, _x)[_x].toString; + (_ref3 = (_o3 = o)?.Foo, _o3 === void 0 || _o3 === null) ? void 0 : _classPrivateFieldLooseBase(_ref3, _x)[_x].toString(); + (_ref5 = (_ref4 = deep?.very.o)?.Foo, _ref4 === void 0 || _ref4 === null) ? void 0 : _classPrivateFieldLooseBase(_ref5, _x)[_x]; + (_ref7 = (_ref6 = deep?.very.o)?.Foo, _ref6 === void 0 || _ref6 === null) ? void 0 : _classPrivateFieldLooseBase(_ref7, _x)[_x].toString; + (_ref9 = (_ref8 = deep?.very.o)?.Foo, _ref8 === void 0 || _ref8 === null) ? void 0 : _classPrivateFieldLooseBase(_ref9, _x)[_x].toString(); + (_ref10 = (_o4 = o)?.Foo, _o4 === void 0 || _o4 === null) ? void 0 : _classPrivateFieldLooseBase(_classPrivateFieldLooseBase(_ref10, _self)[_self], _x)[_x]; + (_ref11 = (_o5 = o)?.Foo, _o5 === void 0 || _o5 === null) ? void 0 : _classPrivateFieldLooseBase(_classPrivateFieldLooseBase(_ref11, _self)[_self].self, _x)[_x]; + (_ref14 = (_ref13 = (_ref12 = (_o6 = o)?.Foo, _o6 === void 0 || _o6 === null) ? void 0 : _classPrivateFieldLooseBase(_ref12, _self)[_self])?.self, _ref13 === void 0 || _ref13 === null) ? void 0 : _classPrivateFieldLooseBase(_ref14, _x)[_x]; + (_ref17 = (_ref16 = (_ref15 = (_o7 = o)?.Foo, _o7 === void 0 || _o7 === null) ? void 0 : _classPrivateFieldLooseBase(_ref15, _self)[_self].self)?.self, _ref16 === void 0 || _ref16 === null) ? void 0 : _classPrivateFieldLooseBase(_ref17, _x)[_x]; + (_ref20 = (_ref19 = ((_ref18 = (_o8 = o)?.Foo, _o8 === void 0 || _o8 === null) ? void 0 : _classPrivateFieldLooseBase(_ref18, _self)[_self])?.self)?.self, _ref19 === void 0 || _ref19 === null) ? void 0 : _classPrivateFieldLooseBase(_ref20, _x)[_x]; + } + +} + +var _x = _classPrivateFieldLooseKey("x"); + +var _self = _classPrivateFieldLooseKey("self"); + +Object.defineProperty(Foo, _x, { + writable: true, + value: 1 +}); +Object.defineProperty(Foo, _self, { + writable: true, + value: Foo +}); +Foo.self = Foo; +Foo.test(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain-with-transform/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain-with-transform/exec.js new file mode 100644 index 0000000000000..215802ead54a1 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain-with-transform/exec.js @@ -0,0 +1,25 @@ +class Foo { + static #x = 1; + static #self = Foo; + static self = Foo; + + static test() { + const o = { Foo: Foo }; + const deep = { very: { o } }; + expect(o?.Foo.#x).toEqual(1); + expect(o?.Foo.#x.toString).toEqual(1..toString); + expect(o?.Foo.#x.toString()).toEqual('1'); + + expect(deep?.very.o?.Foo.#x).toEqual(1); + expect(deep?.very.o?.Foo.#x.toString).toEqual(1..toString); + expect(deep?.very.o?.Foo.#x.toString()).toEqual('1'); + + expect(o?.Foo.#self.#x).toEqual(1); + expect(o?.Foo.#self.self.#x).toEqual(1); + expect(o?.Foo.#self?.self.#x).toEqual(1); + expect(o?.Foo.#self.self?.self.#x).toEqual(1); + expect(o?.Foo.#self?.self?.self.#x).toEqual(1); + } +} + +Foo.test(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain-with-transform/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain-with-transform/input.js new file mode 100644 index 0000000000000..e8f18bd86f692 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain-with-transform/input.js @@ -0,0 +1,25 @@ +class Foo { + static #x = 1; + static #self = Foo; + static self = Foo; + + static test() { + const o = { Foo: Foo }; + const deep = { very: { o } }; + o?.Foo.#x; + o?.Foo.#x.toString; + o?.Foo.#x.toString(); + + deep?.very.o?.Foo.#x; + deep?.very.o?.Foo.#x.toString; + deep?.very.o?.Foo.#x.toString(); + + o?.Foo.#self.#x; + o?.Foo.#self.self.#x; + o?.Foo.#self?.self.#x; + o?.Foo.#self.self?.self.#x; + o?.Foo.#self?.self?.self.#x; + } +} + +Foo.test(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain-with-transform/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain-with-transform/options.json new file mode 100644 index 0000000000000..63b4c77cc8e8f --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain-with-transform/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["proposal-optional-chaining", "proposal-class-properties"] +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain-with-transform/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain-with-transform/output.js new file mode 100644 index 0000000000000..845068af6faa9 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain-with-transform/output.js @@ -0,0 +1,43 @@ +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _classStaticPrivateFieldSpecGet(receiver, classConstructor, descriptor) { if (receiver !== classConstructor) { throw new TypeError("Private static access of wrong provenance"); } if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; } + +class Foo { + static test() { + var _o, _ref, _o2, _ref2, _o3, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9, _o4, _ref10, _o5, _ref11, _o6, _ref12, _ref13, _ref14, _o7, _ref15, _ref16, _ref17, _o8, _ref18, _ref19, _ref20, _o9, _o10, _o11, _ref21, _ref22, _ref23, _o12, _o13, _ref24, _o14, _ref25, _o15, _ref26, _ref27, _o16; + + const o = { + Foo: Foo + }; + const deep = { + very: { + o + } + }; + (_ref = (_o9 = _o = o) === null || _o9 === void 0 ? void 0 : _o9.Foo, _o === void 0 || _o === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref, Foo, _x); + (_ref2 = (_o10 = _o2 = o) === null || _o10 === void 0 ? void 0 : _o10.Foo, _o2 === void 0 || _o2 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref2, Foo, _x).toString; + (_ref3 = (_o11 = _o3 = o) === null || _o11 === void 0 ? void 0 : _o11.Foo, _o3 === void 0 || _o3 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref3, Foo, _x).toString(); + (_ref5 = (_ref21 = _ref4 = deep === null || deep === void 0 ? void 0 : deep.very.o) === null || _ref21 === void 0 ? void 0 : _ref21.Foo, _ref4 === void 0 || _ref4 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref5, Foo, _x); + (_ref7 = (_ref22 = _ref6 = deep === null || deep === void 0 ? void 0 : deep.very.o) === null || _ref22 === void 0 ? void 0 : _ref22.Foo, _ref6 === void 0 || _ref6 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref7, Foo, _x).toString; + (_ref9 = (_ref23 = _ref8 = deep === null || deep === void 0 ? void 0 : deep.very.o) === null || _ref23 === void 0 ? void 0 : _ref23.Foo, _ref8 === void 0 || _ref8 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref9, Foo, _x).toString(); + (_ref10 = (_o12 = _o4 = o) === null || _o12 === void 0 ? void 0 : _o12.Foo, _o4 === void 0 || _o4 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_classStaticPrivateFieldSpecGet(_ref10, Foo, _self), Foo, _x); + (_ref11 = (_o13 = _o5 = o) === null || _o13 === void 0 ? void 0 : _o13.Foo, _o5 === void 0 || _o5 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_classStaticPrivateFieldSpecGet(_ref11, Foo, _self).self, Foo, _x); + (_ref14 = (_ref24 = _ref13 = (_ref12 = (_o14 = _o6 = o) === null || _o14 === void 0 ? void 0 : _o14.Foo, _o6 === void 0 || _o6 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref12, Foo, _self)) === null || _ref24 === void 0 ? void 0 : _ref24.self, _ref13 === void 0 || _ref13 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref14, Foo, _x); + (_ref17 = (_ref25 = _ref16 = (_ref15 = (_o15 = _o7 = o) === null || _o15 === void 0 ? void 0 : _o15.Foo, _o7 === void 0 || _o7 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref15, Foo, _self).self) === null || _ref25 === void 0 ? void 0 : _ref25.self, _ref16 === void 0 || _ref16 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref17, Foo, _x); + (_ref20 = (_ref26 = _ref19 = (_ref27 = (_ref18 = (_o16 = _o8 = o) === null || _o16 === void 0 ? void 0 : _o16.Foo, _o8 === void 0 || _o8 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref18, Foo, _self)) === null || _ref27 === void 0 ? void 0 : _ref27.self) === null || _ref26 === void 0 ? void 0 : _ref26.self, _ref19 === void 0 || _ref19 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref20, Foo, _x); + } + +} + +var _x = { + writable: true, + value: 1 +}; +var _self = { + writable: true, + value: Foo +}; + +_defineProperty(Foo, "self", Foo); + +Foo.test(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain/input.js new file mode 100644 index 0000000000000..e8f18bd86f692 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain/input.js @@ -0,0 +1,25 @@ +class Foo { + static #x = 1; + static #self = Foo; + static self = Foo; + + static test() { + const o = { Foo: Foo }; + const deep = { very: { o } }; + o?.Foo.#x; + o?.Foo.#x.toString; + o?.Foo.#x.toString(); + + deep?.very.o?.Foo.#x; + deep?.very.o?.Foo.#x.toString; + deep?.very.o?.Foo.#x.toString(); + + o?.Foo.#self.#x; + o?.Foo.#self.self.#x; + o?.Foo.#self?.self.#x; + o?.Foo.#self.self?.self.#x; + o?.Foo.#self?.self?.self.#x; + } +} + +Foo.test(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain/options.json new file mode 100644 index 0000000000000..19ed5174f5453 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["proposal-class-properties"] +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain/output.js new file mode 100644 index 0000000000000..908d2cf6a3f33 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/optional-chain/output.js @@ -0,0 +1,43 @@ +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _classStaticPrivateFieldSpecGet(receiver, classConstructor, descriptor) { if (receiver !== classConstructor) { throw new TypeError("Private static access of wrong provenance"); } if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; } + +class Foo { + static test() { + var _o, _ref, _o2, _ref2, _o3, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9, _o4, _ref10, _o5, _ref11, _o6, _ref12, _ref13, _ref14, _o7, _ref15, _ref16, _ref17, _o8, _ref18, _ref19, _ref20; + + const o = { + Foo: Foo + }; + const deep = { + very: { + o + } + }; + (_ref = (_o = o)?.Foo, _o === void 0 || _o === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref, Foo, _x); + (_ref2 = (_o2 = o)?.Foo, _o2 === void 0 || _o2 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref2, Foo, _x).toString; + (_ref3 = (_o3 = o)?.Foo, _o3 === void 0 || _o3 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref3, Foo, _x).toString(); + (_ref5 = (_ref4 = deep?.very.o)?.Foo, _ref4 === void 0 || _ref4 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref5, Foo, _x); + (_ref7 = (_ref6 = deep?.very.o)?.Foo, _ref6 === void 0 || _ref6 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref7, Foo, _x).toString; + (_ref9 = (_ref8 = deep?.very.o)?.Foo, _ref8 === void 0 || _ref8 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref9, Foo, _x).toString(); + (_ref10 = (_o4 = o)?.Foo, _o4 === void 0 || _o4 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_classStaticPrivateFieldSpecGet(_ref10, Foo, _self), Foo, _x); + (_ref11 = (_o5 = o)?.Foo, _o5 === void 0 || _o5 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_classStaticPrivateFieldSpecGet(_ref11, Foo, _self).self, Foo, _x); + (_ref14 = (_ref13 = (_ref12 = (_o6 = o)?.Foo, _o6 === void 0 || _o6 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref12, Foo, _self))?.self, _ref13 === void 0 || _ref13 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref14, Foo, _x); + (_ref17 = (_ref16 = (_ref15 = (_o7 = o)?.Foo, _o7 === void 0 || _o7 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref15, Foo, _self).self)?.self, _ref16 === void 0 || _ref16 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref17, Foo, _x); + (_ref20 = (_ref19 = ((_ref18 = (_o8 = o)?.Foo, _o8 === void 0 || _o8 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref18, Foo, _self))?.self)?.self, _ref19 === void 0 || _ref19 === null) ? void 0 : _classStaticPrivateFieldSpecGet(_ref20, Foo, _x); + } + +} + +var _x = { + writable: true, + value: 1 +}; +var _self = { + writable: true, + value: Foo +}; + +_defineProperty(Foo, "self", Foo); + +Foo.test();