Walking

Tree-walking functions enable efficient traversal of the syntax tree.

When dealing with a large number of nodes, working with node objects creates a huge pressure on the garbage collector. For better performance, it’s advisable to extract and work with individual node properties. The constant tsc-valid-node-props holds the list of all available property names:

'(:type
  :field ;node's field name within the parent node
  :depth ;node's depth, relative to the iterator's start
  :named-p :extra-p :error-p :missing-p :has-error-p
  :start-byte :end-byte
  :start-point :end-point
  :range :byte-range)

Functions that accept a vector of property names can also accept a single property name, in which case only that property is returned/yielded, instead of a vector of properties.

Traversing All Descendant Nodes

These functions are high-level APIs that allow traversing the syntax tree in depth-first pre-order.

tsc-traverse-do (vars tree-or-node) body
Evaluate body with vars bound to corresponding properties of each traversed node.
(tsc-traverse-do ([type depth named-p] tree)
  (when named-p                         ;AST
    (insert (make-string depth \? )     ;indentation
	    (format "%S" type) "\n")))
tsc-traverse-mapc func tree-or-node [props]
Call func for each traversed node, passing the node as the argument. If props is a vector of property names, func receives a vector containing the node’s properties instead. Do not keep a reference to the vector, as it is reused across invocations. Use pcase-let to extract the properties instead.
(tsc-traverse-mapc
 (lambda (props)
   (pcase-let ((`[,type ,depth ,named-p] props))
     (when named-p                          ;AST
       (insert (make-string depth \? )      ;indentation
	       (format "%S" type) "\n"))))
 tree
 [:type :depth :named-p])
tsc-traverse-iter tree-or-node [props]
Create an iterator that yields traversed nodes. If props is a vector of property names, the iterator yields a vector containing the node’s properties instead. Do not keep a reference to the vector, as it is reused across iterations. Use pcase-let to extract the properties instead.
(iter-do (props (tsc-traverse-iter
		 tree [:type :depth :named-p]))
  (pcase-let ((`[,type ,depth ,named-p] props))
    (when named-p                       ;AST
      (insert (make-string depth \? )   ;indentation
	      (format "%S" type) "\n"))))

Walking Step-by-step

These functions are the low-level APIs that allow walking through the syntax tree one node at a time, with the help of a stateful cursor object.

tsc-make-cursor tree-or-node
Create a new cursor on a node. The cursor cannot move out of this node. If called on a tree, the cursor is created on the tree’s root node.
tsc-goto-parent cursor
tsc-goto-first-child cursor
tsc-goto-next-sibling cursor
Attempt to move the cursor to the parent node, the first child node, or the next sibling node. This function returns t if the move was successful, nil if the move is invalid.
tsc-goto-first-child-for-position cursor pos
Attempt to move the cursor to the first child node that extends beyond the given position. This function returns the index of the child node found, nil otherwise.
tsc-reset-cursor cursor node
Re-initialize the cursor to start on a different node.
tsc-current-node cursor [props] [output]
Get the node that the cursor is currently on. If props is a vector of property names, return a vector containing the node’s corresponding properties. If output is also non-nil, it must be a vector of the same length, where the properties will be written into.
tsc-current-field cursor
Get the field name (as a keyword) associated with the current node. This is equivalent to:
(tsc-current-node cursor :field)