or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.mdsearch-functions.mdwalker-utilities.mdwalking-functions.md
tile.json

walking-functions.mddocs/

AST Walking Functions

Core traversal algorithms for walking JavaScript ASTs with different callback patterns and state management approaches. These functions provide the foundation for analyzing and transforming Abstract Syntax Trees.

Capabilities

Simple Walk

Performs a simple walk over an AST, calling visitor functions for matching node types. The walker traverses the entire tree and calls the appropriate visitor for each node.

/**
 * Performs a simple walk over AST calling visitor functions for matching node types
 * @param node - AST node to walk
 * @param visitors - Object mapping node types to visitor functions
 * @param baseVisitor - Optional custom recursive walker (defaults to base)
 * @param state - Optional initial state
 * @param override - Optional node type override
 */
function simple<TState>(
  node: Node,
  visitors: SimpleVisitors<TState>,
  baseVisitor?: RecursiveVisitors<TState>,
  state?: TState,
  override?: string
): void;

Usage Example:

import * as acorn from "acorn";
import { simple } from "acorn-walk";

const ast = acorn.parse("let x = 10; function test() { return x + 5; }");

simple(ast, {
  Literal(node) {
    console.log(`Found literal: ${node.value}`);
  },
  Identifier(node) {
    console.log(`Found identifier: ${node.name}`);
  },
  FunctionDeclaration(node) {
    console.log(`Found function: ${node.id.name}`);
  }
});

Ancestor Walk

Walks the AST while building up an array of ancestor nodes, passing the ancestor array to callbacks as the third parameter. Useful for context-aware analysis.

/**
 * Walk with ancestor array passed to callbacks as third parameter
 * @param node - AST node to walk
 * @param visitors - Object mapping node types to visitor functions
 * @param baseVisitor - Optional custom recursive walker (defaults to base)
 * @param state - Optional initial state
 * @param override - Optional node type override
 */
function ancestor<TState>(
  node: Node,
  visitors: AncestorVisitors<TState>,
  baseVisitor?: RecursiveVisitors<TState>,
  state?: TState,
  override?: string
): void;

Usage Example:

import * as acorn from "acorn";
import { ancestor } from "acorn-walk";

const ast = acorn.parse("function outer() { function inner() { return 42; } }");

ancestor(ast, {
  FunctionDeclaration(node, state, ancestors) {
    console.log(`Function ${node.id.name} has ${ancestors.length - 1} ancestors`);
    console.log("Ancestor types:", ancestors.map(n => n.type));
  }
});

Recursive Walk

A recursive walk where visitor functions control their own traversal. Functions can modify state and decide how to walk child nodes by calling the continuation function.

/**
 * Recursive walk where functions control their own traversal
 * @param node - AST node to walk
 * @param state - Initial state
 * @param functions - Object mapping node types to recursive walker functions
 * @param baseVisitor - Optional fallback walker (defaults to base)
 * @param override - Optional node type override
 */
function recursive<TState>(
  node: Node,
  state: TState,
  functions: RecursiveVisitors<TState>,
  baseVisitor?: RecursiveVisitors<TState>,
  override?: string
): void;

Usage Example:

import * as acorn from "acorn";
import { recursive } from "acorn-walk";

const ast = acorn.parse("let a = 1; let b = a + 2;");

recursive(ast, { depth: 0 }, {
  VariableDeclaration(node, state, c) {
    console.log(`Variable declaration at depth ${state.depth}`);
    for (let decl of node.declarations) {
      c(decl, { ...state, depth: state.depth + 1 });
    }
  },
  Identifier(node, state, c) {
    console.log(`Identifier '${node.name}' at depth ${state.depth}`);
  }
});

Full Walk

Triggers a callback on every single node in the AST. The callback receives the node, state, and node type.

/**
 * Full walk triggering callback on each node
 * @param node - AST node to walk
 * @param callback - Function called for each node with (node, state, type)
 * @param baseVisitor - Optional custom walker (defaults to base)
 * @param state - Optional initial state
 * @param override - Optional node type override
 */
function full<TState>(
  node: Node,
  callback: FullWalkerCallback<TState>,
  baseVisitor?: RecursiveVisitors<TState>,
  state?: TState,
  override?: string
): void;

Usage Example:

import * as acorn from "acorn";
import { full } from "acorn-walk";

const ast = acorn.parse("let x = 10;");

full(ast, (node, state, type) => {
  console.log(`Node: ${type} at ${node.start}-${node.end}`);
});

Full Ancestor Walk

Combines full walk with ancestor tracking, calling the callback for every node while maintaining the ancestor array.

/**
 * Full walk with ancestor array passed to callback
 * @param node - AST node to walk
 * @param callback - Function called for each node with (node, state, ancestors, type)
 * @param baseVisitor - Optional custom walker (defaults to base)
 * @param state - Optional initial state
 */
function fullAncestor<TState>(
  node: Node,
  callback: FullAncestorWalkerCallback<TState>,
  baseVisitor?: RecursiveVisitors<TState>,
  state?: TState
): void;

Usage Example:

import * as acorn from "acorn";
import { fullAncestor } from "acorn-walk";

const ast = acorn.parse("function test() { let x = 1; }");

fullAncestor(ast, (node, state, ancestors, type) => {
  console.log(`${type} node has ${ancestors.length - 1} ancestors`);
  if (ancestors.length > 1) {
    console.log(`Parent: ${ancestors[ancestors.length - 2].type}`);
  }
});

Walker Function Types

type SimpleWalkerFn<TState> = (node: Node, state: TState) => void;

type AncestorWalkerFn<TState> = (
  node: Node,
  state: TState | Node[],
  ancestors: Node[]
) => void;

type RecursiveWalkerFn<TState> = (
  node: Node,
  state: TState,
  callback: WalkerCallback<TState>
) => void;

type FullWalkerCallback<TState> = (
  node: Node,
  state: TState,
  type: string
) => void;

type FullAncestorWalkerCallback<TState> = (
  node: Node,
  state: TState | Node[],
  ancestors: Node[],
  type: string
) => void;

type SimpleVisitors<TState> = {
  [type: string]: SimpleWalkerFn<TState>;
};

type AncestorVisitors<TState> = {
  [type: string]: AncestorWalkerFn<TState>;
};

type RecursiveVisitors<TState> = {
  [type: string]: RecursiveWalkerFn<TState>;
};

type WalkerCallback<TState> = (node: Node, state: TState) => void;