// node_modules/.pnpm/estree-walker@3.0.3/node_modules/estree-walker/src/walker.js var WalkerBase = class { constructor() { this.should_skip = false; this.should_remove = false; this.replacement = null; this.context = { skip: () => this.should_skip = true, remove: () => this.should_remove = true, replace: (node) => this.replacement = node }; } replace(parent, prop, index, node) { if (parent && prop) { if (index != null) { parent[prop][index] = node; } else { parent[prop] = node; } } } remove(parent, prop, index) { if (parent && prop) { if (index !== null && index !== void 0) { parent[prop].splice(index, 1); } else { delete parent[prop]; } } } }; // node_modules/.pnpm/estree-walker@3.0.3/node_modules/estree-walker/src/sync.js var SyncWalker = class extends WalkerBase { constructor(enter, leave) { super(); this.should_skip = false; this.should_remove = false; this.replacement = null; this.context = { skip: () => this.should_skip = true, remove: () => this.should_remove = true, replace: (node) => this.replacement = node }; this.enter = enter; this.leave = leave; } visit(node, parent, prop, index) { if (node) { if (this.enter) { const _should_skip = this.should_skip; const _should_remove = this.should_remove; const _replacement = this.replacement; this.should_skip = false; this.should_remove = false; this.replacement = null; this.enter.call(this.context, node, parent, prop, index); if (this.replacement) { node = this.replacement; this.replace(parent, prop, index, node); } if (this.should_remove) { this.remove(parent, prop, index); } const skipped = this.should_skip; const removed = this.should_remove; this.should_skip = _should_skip; this.should_remove = _should_remove; this.replacement = _replacement; if (skipped) return node; if (removed) return null; } let key; for (key in node) { const value = node[key]; if (value && typeof value === "object") { if (Array.isArray(value)) { const nodes = value; for (let i = 0; i < nodes.length; i += 1) { const item = nodes[i]; if (isNode(item)) { if (!this.visit(item, node, key, i)) { i--; } } } } else if (isNode(value)) { this.visit(value, node, key, null); } } } if (this.leave) { const _replacement = this.replacement; const _should_remove = this.should_remove; this.replacement = null; this.should_remove = false; this.leave.call(this.context, node, parent, prop, index); if (this.replacement) { node = this.replacement; this.replace(parent, prop, index, node); } if (this.should_remove) { this.remove(parent, prop, index); } const removed = this.should_remove; this.replacement = _replacement; this.should_remove = _should_remove; if (removed) return null; } } return node; } }; function isNode(value) { return value !== null && typeof value === "object" && "type" in value && typeof value.type === "string"; } // node_modules/.pnpm/estree-walker@3.0.3/node_modules/estree-walker/src/index.js function walk(ast, { enter, leave }) { const instance = new SyncWalker(enter, leave); return instance.visit(ast, null); } // src/index.ts import { isFunction as isFunction2 } from "@babel/types"; // src/utils/babel.ts import { isFunction } from "@babel/types"; import { parse } from "@babel/parser"; var NEW_SCOPE = [ "CatchClause", "ForInStatement", "ForOfStatement" ]; var isNewScope = (node) => NEW_SCOPE.includes(node.type) || isFunction(node); function walkFunctionParams(node, onIdent) { for (const p of node.params) { for (const id of extractIdentifiers(p)) { onIdent(id); } } } function extractIdentifiers(param, nodes = []) { switch (param.type) { case "Identifier": nodes.push(param); break; case "MemberExpression": { let object = param; while (object.type === "MemberExpression") { object = object.object; } nodes.push(object); break; } case "ObjectPattern": for (const prop of param.properties) { if (prop.type === "RestElement") { extractIdentifiers(prop.argument, nodes); } else { extractIdentifiers(prop.value, nodes); } } break; case "ArrayPattern": param.elements.forEach((element) => { if (element) extractIdentifiers(element, nodes); }); break; case "RestElement": extractIdentifiers(param.argument, nodes); break; case "AssignmentPattern": extractIdentifiers(param.left, nodes); break; } return nodes; } function babelParse(code, filename, parserPlugins = []) { const plugins = parserPlugins || []; if (filename) { if (/\.tsx?$/.test(filename)) plugins.push("typescript"); if (filename.endsWith("x")) plugins.push("jsx"); } const ast = parse(code, { sourceType: "module", plugins }); return ast; } function walkVariableDeclaration(stmt, register) { if (stmt.declare) return; for (const decl of stmt.declarations) { for (const id of extractIdentifiers(decl.id)) { register(id); } } } function walkNewIdentifier(node, register) { if (node.type === "ExportNamedDeclaration" && node.declaration) { node = node.declaration; } if (node.type === "VariableDeclaration") { walkVariableDeclaration(node, register); } else if (node.type === "FunctionDeclaration" || node.type === "ClassDeclaration") { if (node.declare || !node.id) return; register(node.id); } else if (node.type === "ExportNamedDeclaration" && node.declaration && node.declaration.type === "VariableDeclaration") { walkVariableDeclaration(node.declaration, register); } } // src/index.ts var walk2 = (code, walkHooks, { filename, parserPlugins } = {}) => { const ast = babelParse(code, filename, parserPlugins); walkAST(ast.program, walkHooks); return ast; }; var walkAST = (node, { enter, leave, enterAfter, leaveAfter }) => { let currentScope = {}; const scopeStack = [currentScope]; const ast = Array.isArray(node) ? { type: "Program", body: node } : node; walk(ast, { enter(node2, parent, ...args) { const { scopeCtx, walkerCtx, isSkip, isRemoved, getNode } = getHookContext(this, node2, [parent, ...args]); enter == null ? void 0 : enter.call({ ...scopeCtx(), ...walkerCtx }, node2); node2 = getNode(); if (!isSkip() && !isRemoved()) { enterNode(node2, parent); enterAfter == null ? void 0 : enterAfter.call(scopeCtx(), node2); } }, leave(node2, parent, ...args) { const { scopeCtx, walkerCtx, isSkip, isRemoved, getNode } = getHookContext(this, node2, [parent, ...args]); leave == null ? void 0 : leave.call({ ...scopeCtx(), ...walkerCtx }, node2); node2 = getNode(); if (!isSkip() && !isRemoved()) { leaveNode(node2, parent); leaveAfter == null ? void 0 : leaveAfter.call(scopeCtx(), node2); } } }); function getHookContext(ctx, node2, [parent, key, index]) { const scopeCtx = () => ({ parent, key, index, scope: scopeStack.reduce((prev, curr) => ({ ...prev, ...curr }), {}), scopes: scopeStack, level: scopeStack.length }); let isSkip = false; let isRemoved = false; let newNode = node2; const walkerCtx = { skip() { isSkip = true; ctx.skip(); }, replace(node3) { newNode = node3; }, remove() { isRemoved = true; } }; return { scopeCtx, walkerCtx, isSkip: () => isSkip, isRemoved: () => isRemoved, getNode: () => newNode }; } function enterNode(node2, parent) { if (isNewScope(node2) || node2.type === "BlockStatement" && !isNewScope(parent)) scopeStack.push(currentScope = {}); if (isFunction2(node2)) { walkFunctionParams(node2, registerBinding); } else if (node2.type === "CatchClause" && node2.param && node2.param.type === "Identifier") registerBinding(node2.param); if (node2.type === "BlockStatement" || node2.type === "Program") { for (const stmt of node2.body) { if (stmt.type === "VariableDeclaration" && stmt.kind === "var") { walkVariableDeclaration(stmt, registerBinding); } else if (stmt.type === "FunctionDeclaration" && stmt.id) { registerBinding(stmt.id); } } } } function leaveNode(node2, parent) { if (isNewScope(node2) || node2.type === "BlockStatement" && !isNewScope(parent)) { scopeStack.pop(); currentScope = scopeStack[scopeStack.length - 1]; } walkNewIdentifier(node2, registerBinding); } function registerBinding(id) { if (currentScope) { currentScope[id.name] = id; } else { error( "registerBinding called without active scope, something is wrong.", id ); } } function error(msg, node2) { const e = new Error(msg); e.node = node2; throw e; } }; var getRootScope = (nodes) => { const scope = {}; for (const node of nodes) { walkNewIdentifier(node, (id) => { scope[id.name] = id; }); } return scope; }; export { babelParse, extractIdentifiers, getRootScope, isNewScope, walk2 as walk, walkAST, walkFunctionParams, walkNewIdentifier, walkVariableDeclaration };