# `Dllb.MetaAST.QueryHelpers`
[🔗](https://github.com/Oeditus/dllb_ex/blob/v0.9.0/lib/dllb/meta_ast/query_helpers.ex#L1)

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)

# `ancestors`

```elixir
@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`

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

Extract all function call target names within a subtree.

# `complexity_estimate`

```elixir
@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`

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

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

# `containing_function`

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

Find the nearest `:function_def` ancestor of the target node.

# `find_by_name`

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

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

# `find_by_type`

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

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

# `find_parent`

```elixir
@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`

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

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

# `scope_at`

```elixir
@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.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
