You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1 line
13 KiB

{"version":3,"names":["_core","require","validateUsage","path","state","tdzEnabled","dynamicTDZNames","name","Object","keys","getBindingIdentifiers","binding","scope","getBinding","injectTDZChecks","push","node","kind","disallowConstantViolations","violation","constantViolations","readOnlyError","addHelper","throwNode","t","callExpression","stringLiteral","isAssignmentExpression","operator","left","right","exprs","replaceWith","sequenceExpression","includes","logicalExpression","slice","binaryExpression","isUpdateExpression","unaryExpression","get","isForXStatement","ensureBlock","variableDeclaration","variableDeclarator","generateUidIdentifier","body","unshift","expressionStatement","getTDZStatus","refPath","bindingPath","executionStatus","_guessExecutionStatusRelativeTo","skipTDZChecks","WeakSet","buildTDZAssert","status","clone","cloneNode","add","getTDZReplacement","id","_path$scope$getBindin","has","isFunctionDeclaration","parent","_tdzThis","allUsages","Set","referencePaths","forEach","dynamicTdz","arg","replacement","insertBefore","nodes","ids","length","parentPath","isFor"],"sources":["../src/validation.ts"],"sourcesContent":["import { types as t } from \"@babel/core\";\nimport type { Scope, NodePath, PluginPass } from \"@babel/core\";\n\nexport function validateUsage(\n path: NodePath<t.VariableDeclaration>,\n state: PluginPass,\n tdzEnabled: boolean,\n) {\n const dynamicTDZNames = [];\n\n for (const name of Object.keys(path.getBindingIdentifiers())) {\n const binding = path.scope.getBinding(name);\n // binding may be null. ref: https://github.com/babel/babel/issues/15300\n if (!binding) continue;\n if (tdzEnabled) {\n if (injectTDZChecks(binding, state)) dynamicTDZNames.push(name);\n }\n if (path.node.kind === \"const\") {\n disallowConstantViolations(name, binding, state);\n }\n }\n\n return dynamicTDZNames;\n}\n\nfunction disallowConstantViolations(\n name: string,\n binding: Scope.Binding,\n state: PluginPass,\n) {\n for (const violation of binding.constantViolations) {\n const readOnlyError = state.addHelper(\"readOnlyError\");\n const throwNode = t.callExpression(readOnlyError, [t.stringLiteral(name)]);\n\n if (violation.isAssignmentExpression()) {\n const { operator, left, right } = violation.node;\n if (operator === \"=\") {\n const exprs = [right];\n exprs.push(throwNode);\n violation.replaceWith(t.sequenceExpression(exprs));\n } else if ([\"&&=\", \"||=\", \"??=\"].includes(operator)) {\n violation.replaceWith(\n t.logicalExpression(\n // @ts-expect-error todo: give a better type to operator\n operator.slice(0, -1),\n left,\n t.sequenceExpression([right, throwNode]),\n ),\n );\n } else {\n violation.replaceWith(\n t.sequenceExpression([\n t.binaryExpression(\n // @ts-expect-error todo: give a better type to operator\n operator.slice(0, -1),\n left,\n right,\n ),\n throwNode,\n ]),\n );\n }\n } else if (violation.isUpdateExpression()) {\n violation.replaceWith(\n t.sequenceExpression([\n t.unaryExpression(\"+\", violation.get(\"argument\").node),\n throwNode,\n ]),\n );\n } else if (violation.isForXStatement()) {\n violation.ensureBlock();\n violation\n .get(\"left\")\n .replaceWith(\n t.variableDeclaration(\"var\", [\n t.variableDeclarator(violation.scope.generateUidIdentifier(name)),\n ]),\n );\n (violation.node.body as t.BlockStatement).body.unshift(\n t.expressionStatement(throwNode),\n );\n }\n }\n}\n\nfunction getTDZStatus(refPath: NodePath, bindingPath: NodePath) {\n const executionStatus = bindingPath._guessExecutionStatusRelativeTo(refPath);\n\n if (executionStatus === \"before\") {\n return \"outside\";\n } else if (executionStatus === \"after\") {\n return \"inside\";\n } else {\n return \"maybe\";\n }\n}\n\nconst skipTDZChecks = new WeakSet();\n\nfunction buildTDZAssert(\n status: \"maybe\" | \"inside\",\n node: t.Identifier | t.JSXIdentifier,\n state: PluginPass,\n) {\n if (status === \"maybe\") {\n const clone = t.cloneNode(node);\n skipTDZChecks.add(clone);\n return t.callExpression(state.addHelper(\"temporalRef\"), [\n // @ts-expect-error Fixme: we may need to handle JSXIdentifier\n clone,\n t.stringLiteral(node.name),\n ]);\n } else {\n return t.callExpression(state.addHelper(\"tdz\"), [\n t.stringLiteral(node.name),\n ]);\n }\n}\n\ntype TDZReplacement = { status: \"maybe\" | \"inside\"; node: t.Expression };\nfunction getTDZReplacement(\n path: NodePath<t.Identifier | t.JSXIdentifier>,\n state: PluginPass,\n): TDZReplacement | undefined;\nfunction getTDZReplacement(\n path: NodePath,\n state: PluginPass,\n id: t.Identifier | t.JSXIdentifier,\n): TDZReplacement | undefined;\nfunction getTDZReplacement(\n path: NodePath,\n state: PluginPass,\n id: t.Identifier | t.JSXIdentifier = path.node as any,\n): TDZReplacement | undefined {\n if (skipTDZChecks.has(id)) return;\n skipTDZChecks.add(id);\n\n const bindingPath = path.scope.getBinding(id.name)?.path;\n\n if (!bindingPath || bindingPath.isFunctionDeclaration()) return;\n\n const status = getTDZStatus(path, bindingPath);\n if (status === \"outside\") return;\n\n if (status === \"maybe\") {\n // add tdzThis to parent variable declarator so it's exploded\n // @ts-expect-error todo(flow->ts): avoid mutations\n bindingPath.parent._tdzThis = true;\n }\n\n return { status, node: buildTDZAssert(status, id, state) };\n}\n\nfunction injectTDZChecks(binding: Scope.Binding, state: PluginPass) {\n const allUsages = new Set(binding.referencePaths);\n binding.constantViolations.forEach(allUsages.add, allUsages);\n\n let dynamicTdz = false;\n\n for (const path of binding.constantViolations) {\n const { node } = path;\n if (skipTDZChecks.has(node)) continue;\n skipTDZChecks.add(node);\n\n if (path.isUpdateExpression()) {\n // arg is an identifier referencing the current binding\n const arg = path.get(\"argument\") as NodePath<t.Identifier>;\n\n const replacement = getTDZReplacement(path, state, arg.node);\n if (!replacement) continue;\n\n if (replacement.status === \"maybe\") {\n dynamicTdz = true;\n path.insertBefore(replacement.node);\n } else {\n path.replaceWith(replacement.node);\n }\n } else if (path.isAssignmentExpression()) {\n const nodes = [];\n const ids = process.env.BABEL_8_BREAKING\n ? path.getAssignmentIdentifiers()\n : path.getBindingIdentifiers();\n\n for (const name of Object.keys(ids)) {\n const replacement = getTDZReplacement(path, state, ids[name]);\n if (replacement) {\n nodes.push(t.expressionStatement(replacement.node));\n if (replacement.status === \"inside\") break;\n if (replacement.status === \"maybe\") dynamicTdz = true;\n }\n }\n\n if (nodes.length > 0) path.insertBefore(nodes);\n }\n }\n\n for (const path of binding.referencePaths as NodePath<t.Identifier>[]) {\n if (path.parentPath.isUpdateExpression()) continue;\n // It will be handled after transforming the loop\n if (path.parentPath.isFor({ left: path.node })) continue;\n\n const replacement = getTDZReplacement(path, state);\n if (!replacement) continue;\n if (replacement.status === \"maybe\") dynamicTdz = true;\n\n path.replaceWith(replacement.node);\n }\n\n return dynamicTdz;\n}\n"],"mappings":"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","ignoreList":[]}