@eryx/luau/query Module

Chainable AST query and traversal utilities for Luau parse results.

query.query walks a parse result or any AST node recursively and collects matching nodes into a Query<T> value. The returned object supports chainable operations — filter, map, flatMap, findAll, forEach, and toArray — for transforming and extracting data.

query.children returns the direct child nodes of a single node without recursing further.

local query = require("@eryx/luau/query")
local parse = require("@eryx/luau/parse")

local result = parse.parse(source)

-- Collect all function call expressions
local calls = query.query(result, function(node)
    if node.type == "ExprCall" then
        return node
    end
end)

for _, call in calls:toArray() do
    print(call.location.beginline)
end

Summary

Classes

nodes: { T }
Query:filter<T>(pred: ((T) → boolean))Query<T>
Query:map<T, U>(fn: ((T) → U?))Query<U>
Query:flatMap<T, U>(fn: ((T) → { U }))Query<U>
Query:forEach<T>(callback: ((T) → ()))Query<T>
Query:findAll<T, U>(fn: ((ast.AstNode) → U?))Query<U>
Query:toArray<T>(){ T }

Functions

query.children(node: ast.AstNode){ ast.AstNode }
query.query<T>(astOrNode: ParseResult | any, fn: ((ast.AstNode) → T?))Query<T>

API Reference

Classes

Query<T>

Properties

nodes: { T }

Query:filter

Returns a new Query containing only the nodes for which pred returns true.

Query:filter<T>(pred: ((T) → boolean))Query<T>

Parameters

pred: ((T) → boolean)

Predicate function called with each node.

Returns

A new query with the filtered nodes.

Query:map

Transforms each node by calling fn and collects non-nil results into a new Query.

Query:map<T, U>(fn: ((T) → U?))Query<U>

Parameters

fn: ((T) → U?)

Mapping function. Return nil to exclude a node from the result.

Returns

A new query with the mapped values.

Query:flatMap

Transforms each node into an array via fn and flattens all results into a new Query.

Query:flatMap<T, U>(fn: ((T) → { U }))Query<U>

Parameters

fn: ((T) → { U })

Mapping function that returns an array of values for each node.

Returns

A new query with all flattened values.

Query:forEach

Calls callback for each node in the query. Returns self to allow chaining.

Query:forEach<T>(callback: ((T) → ()))Query<T>

Parameters

callback: ((T) → ())

Function called with each node.

Returns

The same query, for chaining.

Query:findAll

Recursively walks every node in the query and collects non-nil results of fn into a new Query. Unlike map, this descends into all descendants of each node, not just the top-level nodes.

Query:findAll<T, U>(fn: ((ast.AstNode) → U?))Query<U>

Parameters

fn: ((ast.AstNode) → U?)

Selector function. Return a non-nil value to include a descendant node.

Returns

A new query with all matched descendants.

Query:toArray

Returns a shallow copy of the underlying nodes as a plain array.

Query:toArray<T>(){ T }

Returns

{ T }

Array of all nodes in the query.

Functions

query.children

Returns the direct child nodes of node without recursing further. Location spans and dense arrays are unwrapped but not themselves returned as children.

query.children(node: ast.AstNode){ ast.AstNode }

Parameters

node: ast.AstNode

The AST node whose direct children to collect.

Returns

{ ast.AstNode }

Array of direct child nodes.

query.query

Recursively walks all nodes in a parse result or AST node and collects non-nil results of fn into a chainable Query<T>.

Pass a ParseResult to start from the root block, or any AstNode to start from that node directly.

local calls = query.query(result, function(node)
    if node.type == "ExprCall" then
        return node
    end
end)
for _, call in calls:toArray() do
    print(call.location.beginline)
end
query.query<T>(astOrNode: ParseResult | any, fn: ((ast.AstNode) → T?))Query<T>

Parameters

astOrNode: ParseResult | any

A ParseResult or any AST node to traverse.

fn: ((ast.AstNode) → T?)

Selector function. Return a non-nil value to include a node.

Returns

A chainable query containing all matched nodes.