1 line
15 KiB
Plaintext
1 line
15 KiB
Plaintext
|
{"version":3,"names":["_helperPluginUtils","require","_core","_default","exports","default","declare","api","options","assertVersion","allowMutablePropsOnTags","Array","isArray","Error","HOISTED","WeakMap","declares","node","scope","t","isJSXIdentifier","name","path","isFunctionParent","isArrowFunctionExpression","hasOwnBinding","isHoistingScope","isLoop","isProgram","getHoistingScope","parent","targetScopeVisitor","ReferencedIdentifier","state","jsxScope","targetScope","immutabilityVisitor","enter","_expressionResult$deo","stop","isImmutable","skip","isJSXClosingElement","parentPath","isJSXAttribute","isJSXMemberExpression","isJSXNamespacedName","isIdentifier","binding","getBinding","constant","mutablePropsAllowed","isFunction","traverse","isPure","expressionResult","evaluate","confident","value","deopt","hoistingVisitor","Object","assign","visitor","JSXElement|JSXFragment","_jsxScope","has","isJSXElement","openingElement","lastSegment","property","elementName","includes","current","isJSX","get","set","visitorState","getProgramParent","currentScope","id","generateUidBasedOnNode","push","identifier","replacement","template","expression","ast","isJSXFragment","jsxExpressionContainer","replaceWith"],"sources":["../src/index.ts"],"sourcesContent":["import { declare } from \"@babel/helper-plugin-utils\";\nimport { types as t, template } from \"@babel/core\";\nimport type { Visitor, Scope, NodePath } from \"@babel/core\";\n\nexport interface Options {\n allowMutablePropsOnTags?: null | string[];\n}\n\ninterface VisitorState {\n isImmutable: boolean;\n mutablePropsAllowed: boolean;\n jsxScope: Scope;\n targetScope: Scope;\n}\nexport default declare((api, options: Options) => {\n api.assertVersion(REQUIRED_VERSION(7));\n\n const { allowMutablePropsOnTags } = options;\n\n if (\n allowMutablePropsOnTags != null &&\n !Array.isArray(allowMutablePropsOnTags)\n ) {\n throw new Error(\n \".allowMutablePropsOnTags must be an array, null, or undefined.\",\n );\n }\n\n // Element -> Target scope\n const HOISTED = new WeakMap();\n\n function declares(node: t.Identifier | t.JSXIdentifier, scope: Scope) {\n if (\n t.isJSXIdentifier(node, { name: \"this\" }) ||\n t.isJSXIdentifier(node, { name: \"arguments\" }) ||\n t.isJSXIdentifier(node, { name: \"super\" }) ||\n t.isJSXIdentifier(node, { name: \"new\" })\n ) {\n const { path } = scope;\n return path.isFunctionParent() && !path.isArrowFunctionExpression();\n }\n\n return scope.hasOwnBinding(node.name);\n }\n\n function isHoistingScope({ path }: Scope) {\n return path.isFunctionParent() || path.isLoop() || path.isProgram();\n }\n\n function getHoistingScope(scope: Scope) {\n while (!isHoistingScope(scope)) scope = scope.parent;\n return scope;\n }\n\n const targetScopeVisitor: Visitor<VisitorState> = {\n ReferencedIdentifier(path, state) {\n const { node } = path;\n let { scope } = path;\n\n while (scope !== state.jsxScope) {\n // If a binding is declared in an inner function, it doesn't affect hoisting.\n if (declares(node, scope)) return;\n\n scope = scope.parent;\n }\n\n while (scope) {\n // We cannot hoist outside of the previous hoisting target\n // scope, so we return early and we don't update it.\n if (scope === state.targetScope) return;\n\n // If the scope declares this identifier (or we're at the function\n // providing the lexical env binding), we can't hoist the var any\n // higher.\n if (declares(node, scope)) break;\n\n scope = scope.parent;\n }\n\n state.targetScope = getHoistingScope(scope);\n },\n };\n\n const immutabilityVisitor: Visitor<VisitorState> = {\n enter(path, state) {\n const stop = () => {\n state.isImmutable = false;\n path.stop();\n };\n\n const skip = () => {\n path.skip();\n };\n\n if (path.isJSXClosingElement()) {\n skip();\n return;\n }\n\n // Elements with refs are not safe to ho
|