1 line
6.7 KiB
Plaintext
1 line
6.7 KiB
Plaintext
|
{"version":3,"names":["_helperPluginUtils","require","_helperEnvironmentVisitor","_default","exports","default","declare","types","t","traverse","assertVersion","containsClassExpressionVisitor","ClassExpression","path","state","found","stop","Function","skip","containsYieldOrAwaitVisitor","visitors","merge","YieldExpression","yield","await","AwaitExpression","environmentVisitor","containsClassExpression","isClassExpression","node","isFunction","wrap","context","isYieldExpression","isAwaitExpression","replacement","fn","functionExpression","blockStatement","returnStatement","yieldExpression","callExpression","memberExpression","identifier","thisExpression","arrowFunctionExpression","awaitExpression","replaceWith","name","visitor","Class","hasPrivateElement","body","some","isPrivate","elem","get","computed"],"sources":["../src/index.ts"],"sourcesContent":["import type { NodePath, Visitor } from \"@babel/traverse\";\nimport type { types as t } from \"@babel/core\";\nimport { declare } from \"@babel/helper-plugin-utils\";\nimport environmentVisitor from \"@babel/helper-environment-visitor\";\n\nexport default declare(({ types: t, traverse, assertVersion }) => {\n assertVersion(REQUIRED_VERSION(7));\n\n const containsClassExpressionVisitor: Visitor<{ found: boolean }> = {\n ClassExpression(path, state) {\n state.found = true;\n path.stop();\n },\n Function(path) {\n path.skip();\n },\n };\n\n const containsYieldOrAwaitVisitor = traverse.visitors.merge([\n {\n YieldExpression(path, state) {\n state.yield = true;\n if (state.await) path.stop();\n },\n AwaitExpression(path, state) {\n state.await = true;\n if (state.yield) path.stop();\n },\n } satisfies Visitor<{ yield: boolean; await: boolean }>,\n environmentVisitor,\n ]);\n\n function containsClassExpression(path: NodePath<t.Node>) {\n if (t.isClassExpression(path.node)) return true;\n if (t.isFunction(path.node)) return false;\n const state = { found: false };\n path.traverse(containsClassExpressionVisitor, state);\n return state.found;\n }\n\n function wrap(path: NodePath<t.Expression>) {\n const context = {\n yield: t.isYieldExpression(path.node),\n await: t.isAwaitExpression(path.node),\n };\n path.traverse(containsYieldOrAwaitVisitor, context);\n\n let replacement;\n\n if (context.yield) {\n const fn = t.functionExpression(\n null,\n [],\n t.blockStatement([t.returnStatement(path.node)]),\n /* generator */ true,\n /* async */ context.await,\n );\n\n replacement = t.yieldExpression(\n t.callExpression(t.memberExpression(fn, t.identifier(\"call\")), [\n t.thisExpression(),\n // NOTE: In some context arguments is invalid (it might not be defined\n // in the top-level scope, or it's a syntax error in static class blocks).\n // However, `yield` is also invalid in those contexts, so we can safely\n // inject a reference to arguments.\n t.identifier(\"arguments\"),\n ]),\n true,\n );\n } else {\n const fn = t.arrowFunctionExpression([], path.node, context.await);\n\n replacement = t.callExpression(fn, []);\n if (context.await) replacement = t.awaitExpression(replacement);\n }\n\n path.replaceWith(replacement);\n }\n\n return {\n name: \"bugfix-firefox-class-in-computed-class-key\",\n\n visitor: {\n Class(path) {\n const hasPrivateElement = path.node.body.body.some(node =>\n t.isPrivate(node),\n );\n if (!hasPrivateElement) return;\n\n for (const elem of path.get(\"body.body\")) {\n if (\n \"computed\" in elem.node &&\n elem.node.computed &&\n containsClassExpression(elem.get(\"key\"))\n ) {\n wrap(\n // @ts-expect-error .key also includes t.PrivateName\n elem.get(\"key\") satisfies NodePath<t.Expression>,\n );\n }\n }\n },\n
|