From 99a3fefede7c57cbd40da5145786d82c597f8389 Mon Sep 17 00:00:00 2001 From: Mickey Rose Date: Thu, 28 Oct 2021 20:16:22 +0200 Subject: [PATCH] add `skipTransparentExprWrapperNodes` helper (#13687) * overload `skipTransparentExprWrappers` * fixes isSimpleMemberExpression in @babel/plugin-proposal-optional-chaining * use skipTransparentExprWrappers instead of the NodePath overload where possible in @babel/plugin-proposal-optional-chaining * Revert "overload `skipTransparentExprWrappers`" This reverts commit fad47596a64a8d33aadacb7695dbf1aa60a528ae. * add helper `skipTransparentExprWrapperNodes` * avoids constructing NodePaths when only the Node is needed * fixes isSimpleMemberExpression in @babel/plugin-proposal-optional-chaining * use this new helper instead of skipTransparentExprWrappers where possible in @babel/plugin-proposal-optional-chaining --- .../src/index.ts | 9 +++++++++ .../src/transform.js | 14 ++++---------- .../ts-as-function-call-loose/output.js | 4 +--- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/babel-helper-skip-transparent-expression-wrappers/src/index.ts b/packages/babel-helper-skip-transparent-expression-wrappers/src/index.ts index edc336543dda..e3da1587a8fe 100644 --- a/packages/babel-helper-skip-transparent-expression-wrappers/src/index.ts +++ b/packages/babel-helper-skip-transparent-expression-wrappers/src/index.ts @@ -41,3 +41,12 @@ export function skipTransparentExprWrappers( } return path; } + +export function skipTransparentExprWrapperNodes( + node: t.Expression, +): t.Expression { + while (isTransparentExprWrapper(node)) { + node = node.expression; + } + return node; +} diff --git a/packages/babel-plugin-proposal-optional-chaining/src/transform.js b/packages/babel-plugin-proposal-optional-chaining/src/transform.js index 656b4ea09e6c..05ae81bdb433 100644 --- a/packages/babel-plugin-proposal-optional-chaining/src/transform.js +++ b/packages/babel-plugin-proposal-optional-chaining/src/transform.js @@ -1,6 +1,6 @@ import { types as t, template } from "@babel/core"; import { - isTransparentExprWrapper, + skipTransparentExprWrapperNodes, skipTransparentExprWrappers, } from "@babel/helper-skip-transparent-expression-wrappers"; import { willPathCastToBoolean, findOutermostTransparentParent } from "./util"; @@ -8,7 +8,7 @@ import { willPathCastToBoolean, findOutermostTransparentParent } from "./util"; const { ast } = template.expression; function isSimpleMemberExpression(expression) { - expression = skipTransparentExprWrappers(expression); + expression = skipTransparentExprWrapperNodes(expression); return ( t.isIdentifier(expression) || t.isSuper(expression) || @@ -103,11 +103,7 @@ export function transform( const replaceKey = isCall ? "callee" : "object"; const chainWithTypes = node[replaceKey]; - let chain = chainWithTypes; - - while (isTransparentExprWrapper(chain)) { - chain = chain.expression; - } + const chain = skipTransparentExprWrapperNodes(chainWithTypes); let ref; let check; @@ -169,9 +165,7 @@ export function transform( // i.e. `?.b` in `(a?.b.c)()` if (i === 0 && parentIsCall) { // `(a?.b)()` to `(a == null ? undefined : a.b.bind(a))()` - const object = skipTransparentExprWrappers( - replacementPath.get("object"), - ).node; + const object = skipTransparentExprWrapperNodes(replacement.object); let baseRef; if (!pureGetters || !isSimpleMemberExpression(object)) { // memoize the context object when getters are not always pure diff --git a/packages/babel-plugin-proposal-optional-chaining/test/fixtures/transparent-expr-wrappers/ts-as-function-call-loose/output.js b/packages/babel-plugin-proposal-optional-chaining/test/fixtures/transparent-expr-wrappers/ts-as-function-call-loose/output.js index 93a8b5c45d88..6638d5a0908e 100644 --- a/packages/babel-plugin-proposal-optional-chaining/test/fixtures/transparent-expr-wrappers/ts-as-function-call-loose/output.js +++ b/packages/babel-plugin-proposal-optional-chaining/test/fixtures/transparent-expr-wrappers/ts-as-function-call-loose/output.js @@ -1,3 +1 @@ -var _bar, _ref; - -(_bar = ((_ref = (foo as A)).bar as B)) == null ? void 0 : _bar.call(_ref, foo.bar, false); +((foo as A).bar as B) == null ? void 0 : ((foo as A).bar as B)(foo.bar, false);