From 7d9f061003e5577ae013bcf66530d1a92a6fbf8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Fri, 5 Feb 2021 14:27:54 -0500 Subject: [PATCH] =?UTF-8?q?optim=C4=81s:=20respect=20noDocumentAll=20when?= =?UTF-8?q?=20transforming=20`obj=3F.#p`=20(#12762)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/fields.js | 7 +- .../src/index.js | 6 +- .../src/index.js | 82 ++++++------ .../optional-chain-before-member-call/exec.js | 122 ++++++++++++++++++ .../input.js | 66 ++++++++++ .../options.json | 4 + .../output.js | 89 +++++++++++++ .../optional-chain-cast-to-boolean/exec.js | 119 +++++++++++++++++ .../optional-chain-cast-to-boolean/input.js | 82 ++++++++++++ .../options.json | 4 + .../optional-chain-cast-to-boolean/output.js | 115 +++++++++++++++++ .../assumption-noDocumentAll/options.json | 5 + 12 files changed, 659 insertions(+), 42 deletions(-) create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-before-member-call/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-before-member-call/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-before-member-call/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-before-member-call/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-cast-to-boolean/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-cast-to-boolean/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-cast-to-boolean/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-cast-to-boolean/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/options.json 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 f3fefa5089da..81cfcb6e2efc 100644 --- a/packages/babel-helper-create-class-features-plugin/src/fields.js +++ b/packages/babel-helper-create-class-features-plugin/src/fields.js @@ -130,7 +130,7 @@ function privateNameVisitorFactory(visitor) { } const privateNameVisitor = privateNameVisitorFactory({ - PrivateName(path) { + PrivateName(path, { noDocumentAll }) { const { privateNamesMap, redeclared } = this; const { node, parentPath } = path; @@ -144,7 +144,7 @@ const privateNameVisitor = privateNameVisitorFactory({ if (!privateNamesMap.has(name)) return; if (redeclared && redeclared.includes(name)) return; - this.handle(parentPath); + this.handle(parentPath, noDocumentAll); }, }); @@ -376,7 +376,7 @@ export function transformPrivateNamesUsage( ref, path, privateNamesMap, - { privateFieldsAsProperties }, + { privateFieldsAsProperties, noDocumentAll }, state, ) { if (!privateNamesMap.size) return; @@ -391,6 +391,7 @@ export function transformPrivateNamesUsage( classRef: ref, file: state, ...handler, + noDocumentAll, }); body.traverse(privateInVisitor, { privateNamesMap, diff --git a/packages/babel-helper-create-class-features-plugin/src/index.js b/packages/babel-helper-create-class-features-plugin/src/index.js index 08afb3cc37c0..45d353c35b88 100644 --- a/packages/babel-helper-create-class-features-plugin/src/index.js +++ b/packages/babel-helper-create-class-features-plugin/src/index.js @@ -41,6 +41,7 @@ export function createClassFeaturePlugin({ }) { const setPublicClassFields = api.assumption("setPublicClassFields"); const privateFieldsAsProperties = api.assumption("privateFieldsAsProperties"); + const noDocumentAll = api.assumption("noDocumentAll"); if (loose) { const explicit = []; @@ -189,7 +190,10 @@ export function createClassFeaturePlugin({ ref, path, privateNamesMap, - { privateFieldsAsProperties: privateFieldsAsProperties ?? loose }, + { + privateFieldsAsProperties: privateFieldsAsProperties ?? loose, + noDocumentAll, + }, state, ); 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 71c81bb02410..bdea18523ed1 100644 --- a/packages/babel-helper-member-expression-to-functions/src/index.js +++ b/packages/babel-helper-member-expression-to-functions/src/index.js @@ -84,7 +84,7 @@ const handle = { // noop. }, - handle(member) { + handle(member: t.NodePath, noDocumentAll: boolean) { const { node, parent, parentPath, scope } = member; if (member.isOptionalMemberExpression()) { @@ -241,50 +241,56 @@ const handle = { regular = endParentPath.node; } + const baseMemoised = baseNeedsMemoised + ? t.assignmentExpression( + "=", + t.cloneNode(baseRef), + t.cloneNode(startingNode), + ) + : t.cloneNode(baseRef); + if (willEndPathCastToBoolean) { - const nonNullishCheck = t.logicalExpression( - "&&", - t.binaryExpression( - "!==", - baseNeedsMemoised - ? t.assignmentExpression( - "=", - t.cloneNode(baseRef), - t.cloneNode(startingNode), - ) - : t.cloneNode(baseRef), + let nonNullishCheck; + if (noDocumentAll) { + nonNullishCheck = t.binaryExpression( + "!=", + baseMemoised, t.nullLiteral(), - ), - t.binaryExpression( - "!==", - t.cloneNode(baseRef), - scope.buildUndefinedNode(), - ), - ); + ); + } else { + nonNullishCheck = t.logicalExpression( + "&&", + t.binaryExpression("!==", baseMemoised, t.nullLiteral()), + t.binaryExpression( + "!==", + t.cloneNode(baseRef), + scope.buildUndefinedNode(), + ), + ); + } replacementPath.replaceWith( t.logicalExpression("&&", nonNullishCheck, regular), ); } else { - // todo: respect assumptions.noDocumentAll when assumptions are implemented - const nullishCheck = t.logicalExpression( - "||", - t.binaryExpression( - "===", - baseNeedsMemoised - ? t.assignmentExpression( - "=", - t.cloneNode(baseRef), - t.cloneNode(startingNode), - ) - : t.cloneNode(baseRef), + let nullishCheck; + if (noDocumentAll) { + nullishCheck = t.binaryExpression( + "==", + baseMemoised, t.nullLiteral(), - ), - t.binaryExpression( - "===", - t.cloneNode(baseRef), - scope.buildUndefinedNode(), - ), - ); + ); + } else { + nullishCheck = t.logicalExpression( + "||", + t.binaryExpression("===", baseMemoised, t.nullLiteral()), + t.binaryExpression( + "===", + t.cloneNode(baseRef), + scope.buildUndefinedNode(), + ), + ); + } + replacementPath.replaceWith( t.conditionalExpression( nullishCheck, diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-before-member-call/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-before-member-call/exec.js new file mode 100644 index 000000000000..13cc95662d95 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-before-member-call/exec.js @@ -0,0 +1,122 @@ +class Foo { + static #x = 1; + static #m = function() { return this.#x; }; + static #self = Foo; + static self = Foo; + static getSelf() { return this } + + static test() { + const o = { Foo: Foo }; + const deep = { very: { o } }; + function fn() { + return o; + } + function fnDeep() { + return deep; + } + + expect(o?.Foo.#m()).toEqual(1); + expect(o?.Foo.#m().toString).toEqual(1..toString); + expect(o?.Foo.#m().toString()).toEqual('1'); + + expect(deep?.very.o?.Foo.#m()).toEqual(1); + expect(deep?.very.o?.Foo.#m().toString).toEqual(1..toString); + expect(deep?.very.o?.Foo.#m().toString()).toEqual('1'); + + expect(o?.Foo.#self.#m()).toEqual(1); + expect(o?.Foo.#self.self.#m()).toEqual(1); + expect(o?.Foo.#self?.self.#m()).toEqual(1); + expect(o?.Foo.#self.self?.self.#m()).toEqual(1); + expect(o?.Foo.#self?.self?.self.#m()).toEqual(1); + + expect(o?.Foo.#self.getSelf().#m()).toEqual(1); + expect(o?.Foo.#self.getSelf?.().#m()).toEqual(1); + expect(o?.Foo.#self?.getSelf().#m()).toEqual(1); + expect(o?.Foo.#self?.getSelf?.().#m()).toEqual(1); + expect(o?.Foo.#self.getSelf()?.self.#m()).toEqual(1); + expect(o?.Foo.#self.getSelf?.()?.self.#m()).toEqual(1); + expect(o?.Foo.#self?.getSelf()?.self.#m()).toEqual(1); + expect(o?.Foo.#self?.getSelf?.()?.self.#m()).toEqual(1); + + expect(fn?.().Foo.#m()).toEqual(1); + expect(fn?.().Foo.#m().toString).toEqual(1..toString); + expect(fn?.().Foo.#m().toString()).toEqual('1'); + + expect(fnDeep?.().very.o?.Foo.#m()).toEqual(1); + expect(fnDeep?.().very.o?.Foo.#m().toString).toEqual(1..toString); + expect(fnDeep?.().very.o?.Foo.#m().toString()).toEqual('1'); + + expect(fn?.().Foo.#self.#m()).toEqual(1); + expect(fn?.().Foo.#self.self.#m()).toEqual(1); + expect(fn?.().Foo.#self?.self.#m()).toEqual(1); + expect(fn?.().Foo.#self.self?.self.#m()).toEqual(1); + expect(fn?.().Foo.#self?.self?.self.#m()).toEqual(1); + + expect(fn?.().Foo.#self.getSelf().#m()).toEqual(1); + expect(fn?.().Foo.#self.getSelf?.().#m()).toEqual(1); + expect(fn?.().Foo.#self?.getSelf().#m()).toEqual(1); + expect(fn?.().Foo.#self?.getSelf?.().#m()).toEqual(1); + expect(fn?.().Foo.#self.getSelf()?.self.#m()).toEqual(1); + expect(fn?.().Foo.#self.getSelf?.()?.self.#m()).toEqual(1); + expect(fn?.().Foo.#self?.getSelf()?.self.#m()).toEqual(1); + expect(fn?.().Foo.#self?.getSelf?.()?.self.#m()).toEqual(1); + } + + static testNull() { + const o = null;; + const deep = { very: { o } }; + const fn = null; + function fnDeep() { + return deep; + } + + expect(o?.Foo.#m()).toEqual(undefined); + expect(o?.Foo.#m().toString).toEqual(undefined); + expect(o?.Foo.#m().toString()).toEqual(undefined); + + expect(deep?.very.o?.Foo.#m()).toEqual(undefined); + expect(deep?.very.o?.Foo.#m().toString).toEqual(undefined); + expect(deep?.very.o?.Foo.#m().toString()).toEqual(undefined); + + expect(o?.Foo.#self.#m()).toEqual(undefined); + expect(o?.Foo.#self.self.#m()).toEqual(undefined); + expect(o?.Foo.#self?.self.#m()).toEqual(undefined); + expect(o?.Foo.#self.self?.self.#m()).toEqual(undefined); + expect(o?.Foo.#self?.self?.self.#m()).toEqual(undefined); + + expect(o?.Foo.#self.getSelf().#m()).toEqual(undefined); + expect(o?.Foo.#self.getSelf?.().#m()).toEqual(undefined); + expect(o?.Foo.#self?.getSelf().#m()).toEqual(undefined); + expect(o?.Foo.#self?.getSelf?.().#m()).toEqual(undefined); + expect(o?.Foo.#self.getSelf()?.self.#m()).toEqual(undefined); + expect(o?.Foo.#self.getSelf?.()?.self.#m()).toEqual(undefined); + expect(o?.Foo.#self?.getSelf()?.self.#m()).toEqual(undefined); + expect(o?.Foo.#self?.getSelf?.()?.self.#m()).toEqual(undefined); + + expect(fn?.().Foo.#m()).toEqual(undefined); + expect(fn?.().Foo.#m().toString).toEqual(undefined); + expect(fn?.().Foo.#m().toString()).toEqual(undefined); + + expect(fnDeep?.().very.o?.Foo.#m()).toEqual(undefined); + expect(fnDeep?.().very.o?.Foo.#m().toString).toEqual(undefined); + expect(fnDeep?.().very.o?.Foo.#m().toString()).toEqual(undefined); + + expect(fn?.().Foo.#self.#m()).toEqual(undefined); + expect(fn?.().Foo.#self.self.#m()).toEqual(undefined); + expect(fn?.().Foo.#self?.self.#m()).toEqual(undefined); + expect(fn?.().Foo.#self.self?.self.#m()).toEqual(undefined); + expect(fn?.().Foo.#self?.self?.self.#m()).toEqual(undefined); + + expect(fn?.().Foo.#self.getSelf().#m()).toEqual(undefined); + expect(fn?.().Foo.#self.getSelf?.().#m()).toEqual(undefined); + expect(fn?.().Foo.#self?.getSelf().#m()).toEqual(undefined); + expect(fn?.().Foo.#self?.getSelf?.().#m()).toEqual(undefined); + expect(fn?.().Foo.#self.getSelf()?.self.#m()).toEqual(undefined); + expect(fn?.().Foo.#self.getSelf?.()?.self.#m()).toEqual(undefined); + expect(fn?.().Foo.#self?.getSelf()?.self.#m()).toEqual(undefined); + expect(fn?.().Foo.#self?.getSelf?.()?.self.#m()).toEqual(undefined); + } +} + +Foo.test(); +Foo.testNull(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-before-member-call/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-before-member-call/input.js new file mode 100644 index 000000000000..d29585b51d60 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-before-member-call/input.js @@ -0,0 +1,66 @@ +class Foo { + static #x = 1; + static #m = function() { return this.#x; }; + static #self = Foo; + static self = Foo; + static getSelf() { return this } + + static test() { + const o = { Foo: Foo }; + const deep = { very: { o } }; + function fn() { + return o; + } + function fnDeep() { + return deep; + } + + o?.Foo.#m(); + o?.Foo.#m().toString; + o?.Foo.#m().toString(); + + deep?.very.o?.Foo.#m(); + deep?.very.o?.Foo.#m().toString; + deep?.very.o?.Foo.#m().toString(); + + o?.Foo.#self.#m(); + o?.Foo.#self.self.#m(); + o?.Foo.#self?.self.#m(); + o?.Foo.#self.self?.self.#m(); + o?.Foo.#self?.self?.self.#m(); + + o?.Foo.#self.getSelf().#m(); + o?.Foo.#self.getSelf?.().#m(); + o?.Foo.#self?.getSelf().#m(); + o?.Foo.#self?.getSelf?.().#m(); + o?.Foo.#self.getSelf()?.self.#m(); + o?.Foo.#self.getSelf?.()?.self.#m(); + o?.Foo.#self?.getSelf()?.self.#m(); + o?.Foo.#self?.getSelf?.()?.self.#m(); + + fn?.().Foo.#m(); + fn?.().Foo.#m().toString; + fn?.().Foo.#m().toString(); + + fnDeep?.().very.o?.Foo.#m(); + fnDeep?.().very.o?.Foo.#m().toString; + fnDeep?.().very.o?.Foo.#m().toString(); + + fn?.().Foo.#self.#m(); + fn?.().Foo.#self.self.#m(); + fn?.().Foo.#self?.self.#m(); + fn?.().Foo.#self.self?.self.#m(); + fn?.().Foo.#self?.self?.self.#m(); + + fn?.().Foo.#self.getSelf().#m(); + fn?.().Foo.#self.getSelf?.().#m(); + fn?.().Foo.#self?.getSelf().#m(); + fn?.().Foo.#self?.getSelf?.().#m(); + fn?.().Foo.#self.getSelf()?.self.#m(); + fn?.().Foo.#self.getSelf?.()?.self.#m(); + fn?.().Foo.#self?.getSelf()?.self.#m(); + fn?.().Foo.#self?.getSelf?.()?.self.#m(); + } +} + +Foo.test(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-before-member-call/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-before-member-call/options.json new file mode 100644 index 000000000000..3b59e1bbfcc8 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-before-member-call/options.json @@ -0,0 +1,4 @@ +{ + "plugins": ["proposal-class-properties"], + "minNodeVersion": "14.0.0" +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-before-member-call/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-before-member-call/output.js new file mode 100644 index 000000000000..71a4277d0032 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-before-member-call/output.js @@ -0,0 +1,89 @@ +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 getSelf() { + return this; + } + + static test() { + var _o$Foo, _o$Foo2, _o$Foo3, _deep$very$o, _deep$very$o$Foo, _deep$very$o2, _deep$very$o2$Foo, _deep$very$o3, _deep$very$o3$Foo, _classStaticPrivateFi, _classStaticPrivateFi2, _ref, _ref$self, _ref2, _ref2$self, _self2, _self2$self, _classStaticPrivateFi3, _classStaticPrivateFi4, _ref3, _ref3$call, _ref4, _ref4$getSelf, _getSelf, _ref5, _getSelf$call, _ref6, _ref6$self, _classStaticPrivateFi5, _call, _call$self, _getSelf2, _getSelf2$self, _getSelf3, _getSelf3$self, _fn$Foo, _fn$Foo2, _fn$Foo3, _fnDeep$very$o, _fnDeep$very$o$Foo, _fnDeep$very$o2, _fnDeep$very$o2$Foo, _fnDeep$very$o3, _fnDeep$very$o3$Foo, _classStaticPrivateFi6, _classStaticPrivateFi7, _ref7, _ref7$self, _ref8, _ref8$self, _self3, _self3$self, _classStaticPrivateFi8, _classStaticPrivateFi9, _ref9, _ref9$call, _ref10, _ref10$getSelf, _getSelf4, _ref11, _getSelf4$call, _ref12, _ref12$self, _classStaticPrivateFi10, _call2, _call2$self, _getSelf5, _getSelf5$self, _getSelf6, _getSelf6$self; + + const o = { + Foo: Foo + }; + const deep = { + very: { + o + } + }; + + function fn() { + return o; + } + + function fnDeep() { + return deep; + } + + o == null ? void 0 : _classStaticPrivateFieldSpecGet(_o$Foo = o.Foo, Foo, _m).call(_o$Foo); + o == null ? void 0 : _classStaticPrivateFieldSpecGet(_o$Foo2 = o.Foo, Foo, _m).call(_o$Foo2).toString; + o == null ? void 0 : _classStaticPrivateFieldSpecGet(_o$Foo3 = o.Foo, Foo, _m).call(_o$Foo3).toString(); + (_deep$very$o = deep?.very.o) == null ? void 0 : _classStaticPrivateFieldSpecGet(_deep$very$o$Foo = _deep$very$o.Foo, Foo, _m).call(_deep$very$o$Foo); + (_deep$very$o2 = deep?.very.o) == null ? void 0 : _classStaticPrivateFieldSpecGet(_deep$very$o2$Foo = _deep$very$o2.Foo, Foo, _m).call(_deep$very$o2$Foo).toString; + (_deep$very$o3 = deep?.very.o) == null ? void 0 : _classStaticPrivateFieldSpecGet(_deep$very$o3$Foo = _deep$very$o3.Foo, Foo, _m).call(_deep$very$o3$Foo).toString(); + o == null ? void 0 : _classStaticPrivateFieldSpecGet(_classStaticPrivateFi = _classStaticPrivateFieldSpecGet(o.Foo, Foo, _self), Foo, _m).call(_classStaticPrivateFi); + o == null ? void 0 : _classStaticPrivateFieldSpecGet(_classStaticPrivateFi2 = _classStaticPrivateFieldSpecGet(o.Foo, Foo, _self).self, Foo, _m).call(_classStaticPrivateFi2); + (_ref = o == null ? void 0 : _classStaticPrivateFieldSpecGet(o.Foo, Foo, _self)) == null ? void 0 : _classStaticPrivateFieldSpecGet(_ref$self = _ref.self, Foo, _m).call(_ref$self); + (_ref2 = o == null ? void 0 : _classStaticPrivateFieldSpecGet(o.Foo, Foo, _self).self) == null ? void 0 : _classStaticPrivateFieldSpecGet(_ref2$self = _ref2.self, Foo, _m).call(_ref2$self); + (_self2 = (o == null ? void 0 : _classStaticPrivateFieldSpecGet(o.Foo, Foo, _self))?.self) == null ? void 0 : _classStaticPrivateFieldSpecGet(_self2$self = _self2.self, Foo, _m).call(_self2$self); + o == null ? void 0 : _classStaticPrivateFieldSpecGet(_classStaticPrivateFi3 = _classStaticPrivateFieldSpecGet(o.Foo, Foo, _self).getSelf(), Foo, _m).call(_classStaticPrivateFi3); + (_ref3 = o == null ? void 0 : (_classStaticPrivateFi4 = _classStaticPrivateFieldSpecGet(o.Foo, Foo, _self)).getSelf) == null ? void 0 : _classStaticPrivateFieldSpecGet(_ref3$call = _ref3.call(_classStaticPrivateFi4), Foo, _m).call(_ref3$call); + (_ref4 = o == null ? void 0 : _classStaticPrivateFieldSpecGet(o.Foo, Foo, _self)) == null ? void 0 : _classStaticPrivateFieldSpecGet(_ref4$getSelf = _ref4.getSelf(), Foo, _m).call(_ref4$getSelf); + (_getSelf = (_ref5 = o == null ? void 0 : _classStaticPrivateFieldSpecGet(o.Foo, Foo, _self))?.getSelf) == null ? void 0 : _classStaticPrivateFieldSpecGet(_getSelf$call = _getSelf.call(_ref5), Foo, _m).call(_getSelf$call); + (_ref6 = o == null ? void 0 : _classStaticPrivateFieldSpecGet(o.Foo, Foo, _self).getSelf()) == null ? void 0 : _classStaticPrivateFieldSpecGet(_ref6$self = _ref6.self, Foo, _m).call(_ref6$self); + (_call = (o == null ? void 0 : (_classStaticPrivateFi5 = _classStaticPrivateFieldSpecGet(o.Foo, Foo, _self)).getSelf)?.call(_classStaticPrivateFi5)) == null ? void 0 : _classStaticPrivateFieldSpecGet(_call$self = _call.self, Foo, _m).call(_call$self); + (_getSelf2 = (o == null ? void 0 : _classStaticPrivateFieldSpecGet(o.Foo, Foo, _self))?.getSelf()) == null ? void 0 : _classStaticPrivateFieldSpecGet(_getSelf2$self = _getSelf2.self, Foo, _m).call(_getSelf2$self); + (_getSelf3 = (o == null ? void 0 : _classStaticPrivateFieldSpecGet(o.Foo, Foo, _self))?.getSelf?.()) == null ? void 0 : _classStaticPrivateFieldSpecGet(_getSelf3$self = _getSelf3.self, Foo, _m).call(_getSelf3$self); + fn == null ? void 0 : _classStaticPrivateFieldSpecGet(_fn$Foo = fn().Foo, Foo, _m).call(_fn$Foo); + fn == null ? void 0 : _classStaticPrivateFieldSpecGet(_fn$Foo2 = fn().Foo, Foo, _m).call(_fn$Foo2).toString; + fn == null ? void 0 : _classStaticPrivateFieldSpecGet(_fn$Foo3 = fn().Foo, Foo, _m).call(_fn$Foo3).toString(); + (_fnDeep$very$o = fnDeep?.().very.o) == null ? void 0 : _classStaticPrivateFieldSpecGet(_fnDeep$very$o$Foo = _fnDeep$very$o.Foo, Foo, _m).call(_fnDeep$very$o$Foo); + (_fnDeep$very$o2 = fnDeep?.().very.o) == null ? void 0 : _classStaticPrivateFieldSpecGet(_fnDeep$very$o2$Foo = _fnDeep$very$o2.Foo, Foo, _m).call(_fnDeep$very$o2$Foo).toString; + (_fnDeep$very$o3 = fnDeep?.().very.o) == null ? void 0 : _classStaticPrivateFieldSpecGet(_fnDeep$very$o3$Foo = _fnDeep$very$o3.Foo, Foo, _m).call(_fnDeep$very$o3$Foo).toString(); + fn == null ? void 0 : _classStaticPrivateFieldSpecGet(_classStaticPrivateFi6 = _classStaticPrivateFieldSpecGet(fn().Foo, Foo, _self), Foo, _m).call(_classStaticPrivateFi6); + fn == null ? void 0 : _classStaticPrivateFieldSpecGet(_classStaticPrivateFi7 = _classStaticPrivateFieldSpecGet(fn().Foo, Foo, _self).self, Foo, _m).call(_classStaticPrivateFi7); + (_ref7 = fn == null ? void 0 : _classStaticPrivateFieldSpecGet(fn().Foo, Foo, _self)) == null ? void 0 : _classStaticPrivateFieldSpecGet(_ref7$self = _ref7.self, Foo, _m).call(_ref7$self); + (_ref8 = fn == null ? void 0 : _classStaticPrivateFieldSpecGet(fn().Foo, Foo, _self).self) == null ? void 0 : _classStaticPrivateFieldSpecGet(_ref8$self = _ref8.self, Foo, _m).call(_ref8$self); + (_self3 = (fn == null ? void 0 : _classStaticPrivateFieldSpecGet(fn().Foo, Foo, _self))?.self) == null ? void 0 : _classStaticPrivateFieldSpecGet(_self3$self = _self3.self, Foo, _m).call(_self3$self); + fn == null ? void 0 : _classStaticPrivateFieldSpecGet(_classStaticPrivateFi8 = _classStaticPrivateFieldSpecGet(fn().Foo, Foo, _self).getSelf(), Foo, _m).call(_classStaticPrivateFi8); + (_ref9 = fn == null ? void 0 : (_classStaticPrivateFi9 = _classStaticPrivateFieldSpecGet(fn().Foo, Foo, _self)).getSelf) == null ? void 0 : _classStaticPrivateFieldSpecGet(_ref9$call = _ref9.call(_classStaticPrivateFi9), Foo, _m).call(_ref9$call); + (_ref10 = fn == null ? void 0 : _classStaticPrivateFieldSpecGet(fn().Foo, Foo, _self)) == null ? void 0 : _classStaticPrivateFieldSpecGet(_ref10$getSelf = _ref10.getSelf(), Foo, _m).call(_ref10$getSelf); + (_getSelf4 = (_ref11 = fn == null ? void 0 : _classStaticPrivateFieldSpecGet(fn().Foo, Foo, _self))?.getSelf) == null ? void 0 : _classStaticPrivateFieldSpecGet(_getSelf4$call = _getSelf4.call(_ref11), Foo, _m).call(_getSelf4$call); + (_ref12 = fn == null ? void 0 : _classStaticPrivateFieldSpecGet(fn().Foo, Foo, _self).getSelf()) == null ? void 0 : _classStaticPrivateFieldSpecGet(_ref12$self = _ref12.self, Foo, _m).call(_ref12$self); + (_call2 = (fn == null ? void 0 : (_classStaticPrivateFi10 = _classStaticPrivateFieldSpecGet(fn().Foo, Foo, _self)).getSelf)?.call(_classStaticPrivateFi10)) == null ? void 0 : _classStaticPrivateFieldSpecGet(_call2$self = _call2.self, Foo, _m).call(_call2$self); + (_getSelf5 = (fn == null ? void 0 : _classStaticPrivateFieldSpecGet(fn().Foo, Foo, _self))?.getSelf()) == null ? void 0 : _classStaticPrivateFieldSpecGet(_getSelf5$self = _getSelf5.self, Foo, _m).call(_getSelf5$self); + (_getSelf6 = (fn == null ? void 0 : _classStaticPrivateFieldSpecGet(fn().Foo, Foo, _self))?.getSelf?.()) == null ? void 0 : _classStaticPrivateFieldSpecGet(_getSelf6$self = _getSelf6.self, Foo, _m).call(_getSelf6$self); + } + +} + +var _x = { + writable: true, + value: 1 +}; +var _m = { + writable: true, + value: function () { + return _classStaticPrivateFieldSpecGet(this, Foo, _x); + } +}; +var _self = { + writable: true, + value: Foo +}; + +_defineProperty(Foo, "self", Foo); + +Foo.test(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-cast-to-boolean/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-cast-to-boolean/exec.js new file mode 100644 index 000000000000..c035e0eb1ddd --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-cast-to-boolean/exec.js @@ -0,0 +1,119 @@ +class C { + static #a = { + b: { + c: { + d: 2, + }, + }, + }; + static testIf(o) { + if (o?.#a.b.c.d) { + return true; + } + return false; + } + static testConditional(o) { + return o?.#a.b?.c.d ? true : false; + } + static testLoop(o) { + while (o?.#a.b.c.d) { + for (; o?.#a.b.c?.d; ) { + let i = 0; + do { + i++; + if (i === 2) { + return true; + } + } while (o?.#a.b?.c.d); + } + } + return false; + } + static testNegate(o) { + return !!o?.#a.b?.c.d; + } + static testIfDeep(o) { + if (o.obj?.#a.b?.c.d) { + return true; + } + return false; + } + static testConditionalDeep(o) { + return o.obj?.#a.b?.c.d ? true : false; + } + static testLoopDeep(o) { + while (o.obj?.#a.b.c.d) { + for (; o.obj?.#a.b.c?.d; ) { + let i = 0; + do { + i++; + if (i === 2) { + return true; + } + } while (o.obj?.#a.b?.c.d); + } + } + return false; + } + static testNegateDeep(o) { + return !!o.obj?.#a.b?.c.d; + } + + static testLogicalInIf(o) { + if (o?.#a.b?.c.d && o?.#a?.b.c.d) { + return true; + } + return false; + } + + static testLogicalInReturn(o) { + return o?.#a.b?.c.d && o?.#a?.b.c.d; + } + + static testNullishCoalescing(o) { + if (o?.#a.b?.c.non_existent ?? o?.#a.b?.c.d) { + return o?.#a.b?.c.non_existent ?? o?.#a.b?.c.d; + } + return o?.#a.b?.c.non_existent ?? o; + } + + static test() { + const c = C; + expect(C.testIf(c)).toBe(true); + expect(C.testConditional(c)).toBe(true); + expect(C.testLoop(c)).toBe(true); + expect(C.testNegate(c)).toBe(true); + + expect(C.testIfDeep({ obj: c })).toBe(true); + expect(C.testConditionalDeep({ obj: c })).toBe(true); + expect(C.testLoopDeep({ obj: c })).toBe(true); + expect(C.testNegateDeep({ obj: c })).toBe(true); + + expect(C.testLogicalInIf(c)).toBe(true); + expect(C.testLogicalInReturn(c)).toBe(2); + + expect(C.testNullishCoalescing(c)).toBe(2); + } + + static testNullish() { + for (const n of [null, undefined]) { + expect(C.testIf(n)).toBe(false); + expect(C.testConditional(n)).toBe(false); + expect(C.testLoop(n)).toBe(false); + expect(C.testNegate(n)).toBe(false); + + expect(C.testIfDeep({ obj: n })).toBe(false); + expect(C.testConditionalDeep({ obj: n })).toBe(false); + expect(C.testLoopDeep({ obj: n })).toBe(false); + expect(C.testNegateDeep({ obj: n })).toBe(false); + + expect(C.testLogicalInIf(n)).toBe(false); + expect(C.testLogicalInReturn(n)).toBe(undefined); + + expect(C.testNullishCoalescing(n)).toBe(n); + } + } +} + +C.test(); +C.testNullish(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-cast-to-boolean/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-cast-to-boolean/input.js new file mode 100644 index 000000000000..f80f89dd7a89 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-cast-to-boolean/input.js @@ -0,0 +1,82 @@ +class C { + static #a = { + b: { + c: { + d: 2, + }, + }, + }; + static testIf(o) { + if (o?.#a.b.c.d) { + return true; + } + return false; + } + static testConditional(o) { + return o?.#a.b?.c.d ? true : false; + } + static testLoop(o) { + while (o?.#a.b.c.d) { + for (; o?.#a.b.c?.d; ) { + let i = 0; + do { + i++; + if (i === 2) { + return true; + } + } while (o?.#a.b?.c.d); + } + } + return false; + } + static testNegate(o) { + return !!o?.#a.b?.c.d; + } + static testIfDeep(o) { + if (o.obj?.#a.b?.c.d) { + return true; + } + return false; + } + static testConditionalDeep(o) { + return o.obj?.#a.b?.c.d ? true : false; + } + static testLoopDeep(o) { + while (o.obj?.#a.b.c.d) { + for (; o.obj?.#a.b.c?.d; ) { + let i = 0; + do { + i++; + if (i === 2) { + return true; + } + } while (o.obj?.#a.b?.c.d); + } + } + return false; + } + static testNegateDeep(o) { + return !!o.obj?.#a.b?.c.d; + } + + static testLogicalInIf(o) { + if (o?.#a.b?.c.d && o?.#a?.b.c.d) { + return true; + } + return false; + } + + static testLogicalInReturn(o) { + return o?.#a.b?.c.d && o?.#a?.b.c.d; + } + + static testNullishCoalescing(o) { + if (o?.#a.b?.c.non_existent ?? o?.#a.b?.c.d) { + return o?.#a.b?.c.non_existent ?? o?.#a.b?.c.d; + } + return o?.#a.b?.c.non_existent ?? o; + } +} + +C.test(); +C.testNullish(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-cast-to-boolean/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-cast-to-boolean/options.json new file mode 100644 index 000000000000..e7e7eecfe816 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-cast-to-boolean/options.json @@ -0,0 +1,4 @@ +{ + "plugins": [["external-helpers", { "helperVersion": "7.100.0" }], "proposal-class-properties"], + "minNodeVersion": "14.0.0" +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-cast-to-boolean/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-cast-to-boolean/output.js new file mode 100644 index 000000000000..b0c0e6bc3061 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/optional-chain-cast-to-boolean/output.js @@ -0,0 +1,115 @@ +class C { + static testIf(o) { + if (o != null && babelHelpers.classStaticPrivateFieldSpecGet(o, C, _a).b.c.d) { + return true; + } + + return false; + } + + static testConditional(o) { + return (o == null ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(o, C, _a).b)?.c.d ? true : false; + } + + static testLoop(o) { + while (o != null && babelHelpers.classStaticPrivateFieldSpecGet(o, C, _a).b.c.d) { + for (; (o == null ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(o, C, _a).b.c)?.d;) { + let i = 0; + + do { + i++; + + if (i === 2) { + return true; + } + } while ((o == null ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(o, C, _a).b)?.c.d); + } + } + + return false; + } + + static testNegate(o) { + return !!(o == null ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(o, C, _a).b)?.c.d; + } + + static testIfDeep(o) { + var _o$obj; + + if (((_o$obj = o.obj) == null ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$obj, C, _a).b)?.c.d) { + return true; + } + + return false; + } + + static testConditionalDeep(o) { + var _o$obj2; + + return ((_o$obj2 = o.obj) == null ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$obj2, C, _a).b)?.c.d ? true : false; + } + + static testLoopDeep(o) { + while ((_o$obj3 = o.obj) != null && babelHelpers.classStaticPrivateFieldSpecGet(_o$obj3, C, _a).b.c.d) { + var _o$obj3; + + for (; ((_o$obj4 = o.obj) == null ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$obj4, C, _a).b.c)?.d;) { + var _o$obj4; + + let i = 0; + + do { + var _o$obj5; + + i++; + + if (i === 2) { + return true; + } + } while (((_o$obj5 = o.obj) == null ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$obj5, C, _a).b)?.c.d); + } + } + + return false; + } + + static testNegateDeep(o) { + var _o$obj6; + + return !!((_o$obj6 = o.obj) == null ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(_o$obj6, C, _a).b)?.c.d; + } + + static testLogicalInIf(o) { + if ((o == null ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(o, C, _a).b)?.c.d && (o == null ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(o, C, _a))?.b.c.d) { + return true; + } + + return false; + } + + static testLogicalInReturn(o) { + return (o == null ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(o, C, _a).b)?.c.d && (o == null ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(o, C, _a))?.b.c.d; + } + + static testNullishCoalescing(o) { + if ((o == null ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(o, C, _a).b)?.c.non_existent ?? (o == null ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(o, C, _a).b)?.c.d) { + return (o == null ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(o, C, _a).b)?.c.non_existent ?? (o == null ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(o, C, _a).b)?.c.d; + } + + return (o == null ? void 0 : babelHelpers.classStaticPrivateFieldSpecGet(o, C, _a).b)?.c.non_existent ?? o; + } + +} + +var _a = { + writable: true, + value: { + b: { + c: { + d: 2 + } + } + } +}; +C.test(); +C.testNullish(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/options.json new file mode 100644 index 000000000000..070c7fc1cc25 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/assumption-noDocumentAll/options.json @@ -0,0 +1,5 @@ +{ + "assumptions": { + "noDocumentAll": true + } +}