estree-toolkit
Version:
Traverser, scope tracker, and more tools for working with ESTree AST
65 lines (64 loc) • 2.55 kB
TypeScript
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 {};