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);