Dllb.MetaAST.QueryHelpers (Dllb v0.8.2)

Copy Markdown View Source

High-level AST query utilities for common code intelligence operations on MetaAST trees (Elixir 3-tuples).

These functions provide structural queries: parent/sibling/ancestor lookups, type and name searches, scope resolution, call target extraction, and complexity estimation.

Mirrors the Rust dllb-code-intel::query_helpers module, enabling client-side tree navigation without a dllb server round-trip.

Usage

tree = Metastatic.parse!(source)

# Find all function definitions
fns = Dllb.MetaAST.QueryHelpers.find_by_type(tree, :function_def)

# Get complexity of a function
complexity = Dllb.MetaAST.QueryHelpers.complexity_estimate(fn_node)

# What's at line 42?
scopes = Dllb.MetaAST.QueryHelpers.scope_at(tree, 42)

Summary

Functions

Return the ancestor path from root to target's parent (outermost first).

Extract all function call target names within a subtree.

Estimate cyclomatic complexity of a function body by counting branch points.

Find the nearest :container ancestor (module/class) of the target node.

Find the nearest :function_def ancestor of the target node.

Find all nodes whose :name metadata matches the given string.

Find all nodes of a given type in the tree (depth-first).

Find the immediate parent of a target node in the tree.

Find all sibling nodes (same parent, excluding the target itself).

Find all nodes whose line range contains the given line number.

Functions

ancestors(root, target)

@spec ancestors(tuple(), tuple()) :: [tuple()]

Return the ancestor path from root to target's parent (outermost first).

Returns an empty list if the target is the root or not found.

call_targets(tree)

@spec call_targets(tuple()) :: [String.t()]

Extract all function call target names within a subtree.

complexity_estimate(tree)

@spec complexity_estimate(tuple()) :: non_neg_integer()

Estimate cyclomatic complexity of a function body by counting branch points.

Counts: :conditional, :loop, :pattern_match, :match_arm, :exception_handling nodes. Base complexity is 1.

containing_container(root, target)

@spec containing_container(tuple(), tuple()) :: tuple() | nil

Find the nearest :container ancestor (module/class) of the target node.

containing_function(root, target)

@spec containing_function(tuple(), tuple()) :: tuple() | nil

Find the nearest :function_def ancestor of the target node.

find_by_name(tree, name)

@spec find_by_name(tuple(), String.t() | atom()) :: [tuple()]

Find all nodes whose :name metadata matches the given string.

find_by_type(tree, node_type)

@spec find_by_type(tuple(), atom()) :: [tuple()]

Find all nodes of a given type in the tree (depth-first).

find_parent(root, target)

@spec find_parent(tuple(), tuple()) :: tuple() | nil

Find the immediate parent of a target node in the tree.

Uses structural equality to locate the target. Returns nil if the target is the root or not found.

find_siblings(root, target)

@spec find_siblings(tuple(), tuple()) :: [tuple()]

Find all sibling nodes (same parent, excluding the target itself).

scope_at(tree, line)

@spec scope_at(tuple(), non_neg_integer()) :: [tuple()]

Find all nodes whose line range contains the given line number.

Looks for :line (single line) or :line/:end_line in metadata. Returns nodes from outermost to innermost.