1 line
16 KiB
Plaintext
1 line
16 KiB
Plaintext
{"version":3,"names":["_core","require","_helperSkipTransparentExpressionWrappers","_util","ast","template","expression","isSimpleMemberExpression","skipTransparentExprWrapperNodes","t","isIdentifier","isSuper","isMemberExpression","computed","object","needsMemoize","path","optionalPath","scope","isOptionalMemberExpression","isOptionalCallExpression","node","childPath","skipTransparentExprWrappers","get","optional","isStatic","transform","pureGetters","noDocumentAll","maybeWrapped","findOutermostTransparentParent","parentPath","willReplacementCastToBoolean","willPathCastToBoolean","isDeleteOperation","parentIsCall","isCallExpression","callee","optionals","isPattern","replaceWith","push","type","replacementPath","isUnaryExpression","operator","i","length","isCall","chainWithTypes","chain","ref","check","name","sequenceExpression","numericLiteral","maybeGenerateMemoised","assignmentExpression","cloneNode","context","thisExpression","memoized","arguments","unshift","memberExpression","identifier","replacement","_baseRef","baseRef","callExpression","nonNullishCheck","logicalExpression","nullishCheck","returnValue","conditionalExpression"],"sources":["../src/transform.ts"],"sourcesContent":["import { types as t, template } from \"@babel/core\";\nimport type { NodePath } from \"@babel/traverse\";\nimport {\n skipTransparentExprWrapperNodes,\n skipTransparentExprWrappers,\n} from \"@babel/helper-skip-transparent-expression-wrappers\";\nimport { willPathCastToBoolean, findOutermostTransparentParent } from \"./util\";\n\nconst { ast } = template.expression;\n\nfunction isSimpleMemberExpression(\n expression: t.Expression | t.Super,\n): expression is t.Identifier | t.Super | t.MemberExpression {\n expression = skipTransparentExprWrapperNodes(expression);\n return (\n t.isIdentifier(expression) ||\n t.isSuper(expression) ||\n (t.isMemberExpression(expression) &&\n !expression.computed &&\n isSimpleMemberExpression(expression.object))\n );\n}\n\n/**\n * Test if a given optional chain `path` needs to be memoized\n * @param {NodePath} path\n * @returns {boolean}\n */\nfunction needsMemoize(\n path: NodePath<t.OptionalCallExpression | t.OptionalMemberExpression>,\n) {\n let optionalPath: NodePath = path;\n const { scope } = path;\n while (\n optionalPath.isOptionalMemberExpression() ||\n optionalPath.isOptionalCallExpression()\n ) {\n const { node } = optionalPath;\n const childPath = skipTransparentExprWrappers(\n // @ts-expect-error isOptionalMemberExpression does not work with NodePath union\n optionalPath.isOptionalMemberExpression()\n ? optionalPath.get(\"object\")\n : optionalPath.get(\"callee\"),\n );\n if (node.optional) {\n return !scope.isStatic(childPath.node);\n }\n\n optionalPath = childPath;\n }\n}\n\nexport function transform(\n path: NodePath<t.OptionalCallExpression | t.OptionalMemberExpression>,\n {\n pureGetters,\n noDocumentAll,\n }: { pureGetters: boolean; noDocumentAll: boolean },\n) {\n const { scope } = path;\n // maybeWrapped points to the outermost transparent expression wrapper\n // or the path itself\n const maybeWrapped = findOutermostTransparentParent(path);\n const { parentPath } = maybeWrapped;\n const willReplacementCastToBoolean = willPathCastToBoolean(maybeWrapped);\n let isDeleteOperation = false;\n const parentIsCall =\n parentPath.isCallExpression({ callee: maybeWrapped.node }) &&\n // note that the first condition must implies that `path.optional` is `true`,\n // otherwise the parentPath should be an OptionalCallExpression\n path.isOptionalMemberExpression();\n\n const optionals = [];\n\n let optionalPath = path;\n // Replace `function (a, x = a.b?.c) {}` to `function (a, x = (() => a.b?.c)() ){}`\n // so the temporary variable can be injected in correct scope\n if (scope.path.isPattern() && needsMemoize(optionalPath)) {\n path.replaceWith(template.ast`(() => ${path.node})()` as t.Statement);\n // The injected optional chain will be queued and eventually transformed when visited\n return;\n }\n while (\n optionalPath.isOptionalMemberExpression() ||\n optionalPath.isOptionalCallExpression()\n ) {\n const { node } = optionalPath;\n if (node.optional) {\n optionals.push(node);\n }\n // @ts-expect-error isOptionalMemberExpression does not work with NodePath union\n if (optionalPath.isOptionalMemberExpression()) {\n // @ts-expect-error todo(flow->ts) avoid changing more type\n optionalPath.node.type = \"MemberExpression\";\n // @ts-expect-error todo(flow->ts)\n optionalPath = skipTransparentExprWrappers(optionalPath.get(\"object\"));\n } else if (optionalPath.isOptionalCallExpression()) {\n // @ts-expect-error todo(flow->ts) avoid changing more type\n optionalPath.node.type = \"CallExpression\";\n // @ts-expect-error todo(flow->ts)\n optionalPath = skipTransparentExprWrappers(optionalPath.get(\"callee\"));\n }\n }\n\n // todo: Improve replacementPath typings\n let replacementPath: NodePath<any> = path;\n if (parentPath.isUnaryExpression({ operator: \"delete\" })) {\n replacementPath = parentPath;\n isDeleteOperation = true;\n }\n for (let i = optionals.length - 1; i >= 0; i--) {\n const node = optionals[i] as unknown as\n | t.MemberExpression\n | t.CallExpression;\n\n const isCall = t.isCallExpression(node);\n\n const chainWithTypes = isCall\n ? // V8 intrinsics must not be an optional call\n (node.callee as t.Expression)\n : node.object;\n const chain = skipTransparentExprWrapperNodes(chainWithTypes);\n\n let ref;\n let check;\n if (isCall && t.isIdentifier(chain, { name: \"eval\" })) {\n check = ref = chain;\n // `eval?.()` is an indirect eval call transformed to `(0,eval)()`\n node.callee = t.sequenceExpression([t.numericLiteral(0), ref]);\n } else if (pureGetters && isCall && isSimpleMemberExpression(chain)) {\n // If we assume getters are pure (avoiding a Function#call) and we are at the call,\n // we can avoid a needless memoize. We only do this if the callee is a simple member\n // expression, to avoid multiple calls to nested call expressions.\n check = ref = node.callee;\n } else {\n ref = scope.maybeGenerateMemoised(chain);\n if (ref) {\n check = t.assignmentExpression(\n \"=\",\n t.cloneNode(ref),\n // Here `chainWithTypes` MUST NOT be cloned because it could be\n // updated when generating the memoised context of a call\n // expression. It must be an Expression when `ref` is an identifier\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n chainWithTypes as t.Expression,\n );\n\n isCall ? (node.callee = ref) : (node.object = ref);\n } else {\n check = ref = chainWithTypes;\n }\n }\n\n // Ensure call expressions have the proper `this`\n // `foo.bar()` has context `foo`.\n if (isCall && t.isMemberExpression(chain)) {\n if (pureGetters && isSimpleMemberExpression(chain)) {\n // To avoid a Function#call, we can instead re-grab the property from the context object.\n // `a.?b.?()` translates roughly to `_a.b != null && _a.b()`\n node.callee = chainWithTypes;\n } else {\n // Otherwise, we need to memoize the context object, and change the call into a Function#call.\n // `a.?b.?()` translates roughly to `(_b = _a.b) != null && _b.call(_a)`\n const { object } = chain;\n let context: t.Expression;\n if (t.isSuper(object)) {\n context = t.thisExpression();\n } else {\n const memoized = scope.maybeGenerateMemoised(object);\n if (memoized) {\n context = memoized;\n chain.object = t.assignmentExpression(\"=\", memoized, object);\n } else {\n context = object;\n }\n }\n\n node.arguments.unshift(t.cloneNode(context));\n // @ts-expect-error node.callee can not be an V8IntrinsicIdentifier: V8 intrinsic is disallowed in optional chain\n node.callee = t.memberExpression(node.callee, t.identifier(\"call\"));\n }\n }\n let replacement = replacementPath.node;\n // Ensure (a?.b)() has proper `this`\n // The `parentIsCall` is constant within loop, we should check i === 0\n // to ensure that it is only applied to the first optional chain element\n // i.e. `?.b` in `(a?.b.c)()`\n if (i === 0 && parentIsCall) {\n // `(a?.b)()` to `(a == null ? undefined : a.b.bind(a))()`\n // object must not be Super as super?.foo is invalid\n const object = skipTransparentExprWrapperNodes(\n replacement.object,\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n ) as any as t.Expression;\n let baseRef;\n if (!pureGetters || !isSimpleMemberExpression(object)) {\n // memoize the context object when getters are not always pure\n // or the object is not a simple member expression\n // `(a?.b.c)()` to `(a == null ? undefined : (_a$b = a.b).c.bind(_a$b))()`\n baseRef = scope.maybeGenerateMemoised(object);\n if (baseRef) {\n replacement.object = t.assignmentExpression(\"=\", baseRef, object);\n }\n }\n replacement = t.callExpression(\n t.memberExpression(replacement, t.identifier(\"bind\")),\n [t.cloneNode(baseRef ?? object)],\n );\n }\n\n if (willReplacementCastToBoolean) {\n // `if (a?.b) {}` transformed to `if (a != null && a.b) {}`\n // we don't need to return `void 0` because the returned value will\n // eventually cast to boolean.\n const nonNullishCheck = noDocumentAll\n ? ast`${t.cloneNode(check)} != null`\n : ast`\n ${t.cloneNode(check)} !== null && ${t.cloneNode(ref)} !== void 0`;\n replacementPath.replaceWith(\n t.logicalExpression(\"&&\", nonNullishCheck, replacement),\n );\n replacementPath = skipTransparentExprWrappers(\n // @ts-expect-error todo(flow->ts)\n replacementPath.get(\"right\"),\n );\n } else {\n const nullishCheck = noDocumentAll\n ? ast`${t.cloneNode(check)} == null`\n : ast`\n ${t.cloneNode(check)} === null || ${t.cloneNode(ref)} === void 0`;\n\n const returnValue = isDeleteOperation ? ast`true` : ast`void 0`;\n replacementPath.replaceWith(\n t.conditionalExpression(nullishCheck, returnValue, replacement),\n );\n replacementPath = skipTransparentExprWrappers(\n // @ts-expect-error todo(flow->ts)\n replacementPath.get(\"alternate\"),\n );\n }\n }\n}\n"],"mappings":"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"} |