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
9.1 KiB

1 month ago
{"version":3,"names":["_t","require","_helpersGenerated","cloneNode","identifier","deep","obj","path","value","parts","split","last","shift","length","arguments","e","message","permuteHelperAST","ast","metadata","bindingName","localBindings","getDependency","adjustAst","locals","dependencies","exportBindingAssignments","exportName","bindings","Set","add","name","paths","Object","entries","o","keys","map","k","newName","has","ref","forEach","p","helperData","create","loadHelper","helper","helpers","assign","ReferenceError","code","minVersion","build","nodes","body","globals","getDependencies","get","id","type","undefined","exports","ensure","list","replace","_default","default"],"sources":["../src/index.ts"],"sourcesContent":["import { cloneNode, identifier } from \"@babel/types\";\nimport type * as t from \"@babel/types\";\nimport helpers from \"./helpers-generated.ts\";\nimport type { HelperMetadata } from \"./helpers-generated.ts\";\n\ntype GetDependency = (name: string) => t.Expression;\n\nfunction deep(obj: any, path: string, value?: unknown) {\n try {\n const parts = path.split(\".\");\n let last = parts.shift();\n while (parts.length > 0) {\n obj = obj[last];\n last = parts.shift();\n }\n if (arguments.length > 2) {\n obj[last] = value;\n } else {\n return obj[last];\n }\n } catch (e) {\n e.message += ` (when accessing ${path})`;\n throw e;\n }\n}\n\ntype AdjustAst = (\n ast: t.Program,\n exportName: string,\n mapExportBindingAssignments: (\n map: (node: t.Expression) => t.Expression,\n ) => void,\n) => void;\n\n/**\n * Given a helper AST and information about how it will be used, update the AST to match the usage.\n */\nfunction permuteHelperAST(\n ast: t.Program,\n metadata: HelperMetadata,\n bindingName: string | undefined,\n localBindings: string[] | undefined,\n getDependency: GetDependency | undefined,\n adjustAst: AdjustAst | undefined,\n) {\n const { locals, dependencies, exportBindingAssignments, exportName } =\n metadata;\n\n const bindings = new Set(localBindings || []);\n if (bindingName) bindings.add(bindingName);\n for (const [name, paths] of Object.entries(locals)) {\n let newName = name;\n if (bindingName && name === exportName) {\n newName = bindingName;\n } else {\n while (bindings.has(newName)) newName = \"_\" + newName;\n }\n\n if (newName !== name) {\n for (const path of paths) {\n deep(ast, path, identifier(newName));\n }\n }\n }\n\n for (const [name, paths] of Object.entries(dependencies)) {\n const ref =\n (typeof getDependency === \"function\" && getDependency(name)) ||\n identifier(name);\n for (const path of paths) {\n deep(ast, path, cloneNode(ref));\n }\n }\n\n adjustAst?.(ast, exportName, map => {\n exportBindingAssignments.forEach(p => deep(ast, p, map(deep(ast, p))));\n });\n}\n\ninterface HelperData {\n build: (\n getDependency: GetDependency | undefined,\n bindingName: string | undefined,\n localBindings: string[] | undefined,\n adjustAst: AdjustAst | undefined,\n ) => {\n nodes: t.Program[\"body\"];\n globals: string[];\n };\n minVersion: string;\n getDependencies: () => string[];\n}\n\nconst helperData: Record<string, HelperData> = Object.create(null);\nfunction loadHelper(name: string) {\n if (!helperData[name]) {\n const helper = helpers[name];\n if (!helper) {\n throw Object.assign(new ReferenceError(`Unknown helper ${name}`), {\n code: \"BABEL_HELPER_UNKNOWN\",\n helper: name,\n });\n }\n\n helperData[name] = {\n minVersion: helper.minVersion,\n build(getDependency, bindingName, localBindings, adjustAst) {\n const ast = helper.ast();\n permuteHelperAST(\n ast,\n helper.metadata,\n bindingName,\n localBindings,\n getDependency,\n adjustAst,\n );\n\n return {\n nodes: ast.body,\n globals: helper.metadata.globals,\n };\n },\n getDependencies() {\n