UNPKG

estree-toolkit

Version:

Traverser, scope tracker, and more tools for working with ESTree AST

65 lines (64 loc) 2.55 kB
import { Node, NodeMap } from './helpers'; import { Context, NodePath } from './nodepath'; import { AliasMap } from './aliases'; export type VisitorContext = { stopped: boolean; stop(): void; }; export type VisitorFn<T extends Node = Node, S = unknown> = (this: VisitorContext, path: NodePath<T>, state: S) => void; export type ExpandedVisitor<T extends Node, S> = { enter?: VisitorFn<T, S>; leave?: VisitorFn<T, S>; }; export type Visitor<T extends Node = Node, S = unknown> = VisitorFn<T, S> | ExpandedVisitor<T, S>; type VisitorMap = AliasMap & NodeMap & { [type: string]: never; }; type NodesFromUnion<K extends string> = K extends `${infer Head}|${infer Rest}` ? VisitorMap[Head] extends never ? never : NodesFromUnion<Rest> extends never ? never : VisitorMap[Head] | NodesFromUnion<Rest> : VisitorMap[K]; type ComputedVisitors<Keys extends string, S> = { [K in Keys]?: NodesFromUnion<K> extends never ? never : Visitor<NodesFromUnion<K>, S>; }; export type Visitors<S, CompT extends string = ''> = { [K in Node as `${K['type']}`]?: Visitor<K, S>; } & { [K in keyof AliasMap]?: Visitor<AliasMap[K], S>; } & { comp?: ComputedVisitors<CompT, S>; }; export type ExpandedVisitors<S = unknown> = { [type: string]: ExpandedVisitor<Node, S> | undefined; }; export type TraverseOptions = { /** Enable/disable scope information tracking */ scope?: boolean; /** Enable/disable validation in `Node` builders */ validateNodes?: boolean; /** Function to use when cloning node using `NodePath.cloneNode()` */ cloneFunction?: (node: any) => any; }; export declare class Traverser { private readonly visitors; constructor(visitors: ExpandedVisitors<any>); visitPath<S>(visitorCtx: VisitorContext, path: NodePath, state: S, visitedPaths: WeakSet<NodePath>, visitOnlyChildren?: boolean): { new: NodePath[]; unSkipped: NodePath[]; } | undefined; static expandVisitors<S = unknown>(visitors: Visitors<S>): ExpandedVisitors<S>; static traverseNode<S = unknown>(data: { node: Node; parentPath: NodePath | null; state: S | undefined; ctx: Context; visitOnlyChildren?: boolean; } & ({ expand: true; visitors: Visitors<S>; } | { expand: false; visitors: ExpandedVisitors<S>; })): void; } export declare const traverse: <NodeT, StateT, CompT extends string = never>(node: NodeT, visitors: Visitors<StateT, CompT> & { $?: TraverseOptions; }, state?: StateT) => void; export {};