visitor.d.ts 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. import type { ASTNode } from './ast';
  2. import { 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. */
  7. export declare type ASTVisitor = EnterLeaveVisitor<ASTNode> | KindVisitor;
  8. declare type KindVisitor = {
  9. readonly [NodeT in ASTNode as NodeT['kind']]?:
  10. | ASTVisitFn<NodeT>
  11. | EnterLeaveVisitor<NodeT>;
  12. };
  13. interface 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. */
  21. export 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. */
  41. export 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. };
  47. declare 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;
  65. declare 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. */
  75. export declare type ASTVisitorKeyMap = {
  76. [NodeT in ASTNode as NodeT['kind']]?: ReadonlyArray<keyof NodeT>;
  77. };
  78. export 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. */
  157. export declare function visit<N extends ASTNode>(
  158. root: N,
  159. visitor: ASTVisitor,
  160. visitorKeys?: ASTVisitorKeyMap,
  161. ): N;
  162. export 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. */
  173. export 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. */
  179. export 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. */
  189. export declare function getVisitFn(
  190. visitor: ASTVisitor,
  191. kind: Kind,
  192. isLeaving: boolean,
  193. ): ASTVisitFn<ASTNode> | undefined;
  194. export {};