UNPKG

6.38 kBTypeScriptView Raw
1import type { ASTNode } from './ast';
2import { Kind } from './kinds';
3/**
4 * A visitor is provided to visit, it contains the collection of
5 * relevant functions to be called during the visitor's traversal.
6 */
7export declare type ASTVisitor = EnterLeaveVisitor<ASTNode> | KindVisitor;
8declare type KindVisitor = {
9 readonly [NodeT in ASTNode as NodeT['kind']]?:
10 | ASTVisitFn<NodeT>
11 | EnterLeaveVisitor<NodeT>;
12};
13interface EnterLeaveVisitor<TVisitedNode extends ASTNode> {
14 readonly enter?: ASTVisitFn<TVisitedNode>;
15 readonly leave?: ASTVisitFn<TVisitedNode>;
16}
17/**
18 * A visitor is comprised of visit functions, which are called on each node
19 * during the visitor's traversal.
20 */
21export declare type ASTVisitFn<TVisitedNode extends ASTNode> = (
22 /** The current node being visiting. */
23 node: TVisitedNode,
24 /** The index or key to this node from the parent node or Array. */
25 key: string | number | undefined,
26 /** The parent immediately above this node, which may be an Array. */
27 parent: ASTNode | ReadonlyArray<ASTNode> | undefined,
28 /** The key path to get to this node from the root node. */
29 path: ReadonlyArray<string | number>,
30 /**
31 * All nodes and Arrays visited before reaching parent of this node.
32 * These correspond to array indices in `path`.
33 * Note: ancestors includes arrays which contain the parent of visited node.
34 */
35 ancestors: ReadonlyArray<ASTNode | ReadonlyArray<ASTNode>>,
36) => any;
37/**
38 * A reducer is comprised of reducer functions which convert AST nodes into
39 * another form.
40 */
41export declare type ASTReducer<R> = {
42 readonly [NodeT in ASTNode as NodeT['kind']]?: {
43 readonly enter?: ASTVisitFn<NodeT>;
44 readonly leave: ASTReducerFn<NodeT, R>;
45 };
46};
47declare type ASTReducerFn<TReducedNode extends ASTNode, R> = (
48 /** The current node being visiting. */
49 node: {
50 [K in keyof TReducedNode]: ReducedField<TReducedNode[K], R>;
51 },
52 /** The index or key to this node from the parent node or Array. */
53 key: string | number | undefined,
54 /** The parent immediately above this node, which may be an Array. */
55 parent: ASTNode | ReadonlyArray<ASTNode> | undefined,
56 /** The key path to get to this node from the root node. */
57 path: ReadonlyArray<string | number>,
58 /**
59 * All nodes and Arrays visited before reaching parent of this node.
60 * These correspond to array indices in `path`.
61 * Note: ancestors includes arrays which contain the parent of visited node.
62 */
63 ancestors: ReadonlyArray<ASTNode | ReadonlyArray<ASTNode>>,
64) => R;
65declare type ReducedField<T, R> = T extends null | undefined
66 ? T
67 : T extends ReadonlyArray<any>
68 ? ReadonlyArray<R>
69 : R;
70/**
71 * A KeyMap describes each the traversable properties of each kind of node.
72 *
73 * @deprecated Please inline it. Will be removed in v17
74 */
75export declare type ASTVisitorKeyMap = {
76 [NodeT in ASTNode as NodeT['kind']]?: ReadonlyArray<keyof NodeT>;
77};
78export declare const BREAK: unknown;
79/**
80 * visit() will walk through an AST using a depth-first traversal, calling
81 * the visitor's enter function at each node in the traversal, and calling the
82 * leave function after visiting that node and all of its child nodes.
83 *
84 * By returning different values from the enter and leave functions, the
85 * behavior of the visitor can be altered, including skipping over a sub-tree of
86 * the AST (by returning false), editing the AST by returning a value or null
87 * to remove the value, or to stop the whole traversal by returning BREAK.
88 *
89 * When using visit() to edit an AST, the original AST will not be modified, and
90 * a new version of the AST with the changes applied will be returned from the
91 * visit function.
92 *
93 * ```ts
94 * const editedAST = visit(ast, {
95 * enter(node, key, parent, path, ancestors) {
96 * // @return
97 * // undefined: no action
98 * // false: skip visiting this node
99 * // visitor.BREAK: stop visiting altogether
100 * // null: delete this node
101 * // any value: replace this node with the returned value
102 * },
103 * leave(node, key, parent, path, ancestors) {
104 * // @return
105 * // undefined: no action
106 * // false: no action
107 * // visitor.BREAK: stop visiting altogether
108 * // null: delete this node
109 * // any value: replace this node with the returned value
110 * }
111 * });
112 * ```
113 *
114 * Alternatively to providing enter() and leave() functions, a visitor can
115 * instead provide functions named the same as the kinds of AST nodes, or
116 * enter/leave visitors at a named key, leading to three permutations of the
117 * visitor API:
118 *
119 * 1) Named visitors triggered when entering a node of a specific kind.
120 *
121 * ```ts
122 * visit(ast, {
123 * Kind(node) {
124 * // enter the "Kind" node
125 * }
126 * })
127 * ```
128 *
129 * 2) Named visitors that trigger upon entering and leaving a node of a specific kind.
130 *
131 * ```ts
132 * visit(ast, {
133 * Kind: {
134 * enter(node) {
135 * // enter the "Kind" node
136 * }
137 * leave(node) {
138 * // leave the "Kind" node
139 * }
140 * }
141 * })
142 * ```
143 *
144 * 3) Generic visitors that trigger upon entering and leaving any node.
145 *
146 * ```ts
147 * visit(ast, {
148 * enter(node) {
149 * // enter any node
150 * },
151 * leave(node) {
152 * // leave any node
153 * }
154 * })
155 * ```
156 */
157export declare function visit<N extends ASTNode>(
158 root: N,
159 visitor: ASTVisitor,
160 visitorKeys?: ASTVisitorKeyMap,
161): N;
162export declare function visit<R>(
163 root: ASTNode,
164 visitor: ASTReducer<R>,
165 visitorKeys?: ASTVisitorKeyMap,
166): R;
167/**
168 * Creates a new visitor instance which delegates to many visitors to run in
169 * parallel. Each visitor will be visited for each node before moving on.
170 *
171 * If a prior visitor edits a node, no following visitors will see that node.
172 */
173export declare function visitInParallel(
174 visitors: ReadonlyArray<ASTVisitor>,
175): ASTVisitor;
176/**
177 * Given a visitor instance and a node kind, return EnterLeaveVisitor for that kind.
178 */
179export declare function getEnterLeaveForKind(
180 visitor: ASTVisitor,
181 kind: Kind,
182): EnterLeaveVisitor<ASTNode>;
183/**
184 * Given a visitor instance, if it is leaving or not, and a node kind, return
185 * the function the visitor runtime should call.
186 *
187 * @deprecated Please use `getEnterLeaveForKind` instead. Will be removed in v17
188 */
189export declare function getVisitFn(
190 visitor: ASTVisitor,
191 kind: Kind,
192 isLeaving: boolean,
193): ASTVisitFn<ASTNode> | undefined;
194export {};