# `ExAST.Query`
[🔗](https://github.com/elixir-vibe/ex_ast/blob/v0.11.0/lib/ex_ast/query.ex#L1)

SQL-like query API for AST search.

This module builds on `ExAST.Selector` with names that read like query
predicates:

    import ExAST.Query

    from("def _ do ... end")
    |> where(contains("Repo.transaction(_)"))
    |> where(not contains("IO.inspect(_)"))

`where/2` also supports capture guards using `^` to pin captured values,
similar to Ecto's parameter syntax:

    from("Enum.take(_, count)")
    |> where(match?({:-, _, [_]}, ^count))

    from("left == right")
    |> where(^left == ^right)

The resulting query can be passed to `ExAST.search/3` or
`ExAST.Patcher.find_all/3` anywhere a selector is accepted.

# `t`

```elixir
@type t() :: ExAST.Selector.t()
```

# `all`

Matches when all nested predicates match.

# `any`

Matches when any nested predicate matches.

# `comment`

Matches comments associated with the selected node.

# `comment_after`

Matches comments immediately after the selected node.

# `comment_before`

Matches comments immediately before the selected node.

# `comment_inline`

Matches inline comments on the selected node start line.

# `comment_inside`

Matches comments inside the selected node range.

# `contains`

Matches when the selected node contains a descendant matching `pattern`.

# `exact`

Builds an exact comment matcher.

# `exact`

# `find`

Finds matching descendants of the current selection.

# `find_child`

Finds matching direct children of the current selection.

# `first`

Matches the first semantic child in its parent.

# `follows`

Matches when a previous sibling matches `pattern`.

# `from`

Starts a query from one pattern or a list of alternative patterns.

# `has_child`

Matches when the selected node has a direct child matching `pattern`.

# `immediately_follows`

Matches when the immediately previous sibling matches `pattern`.

# `immediately_precedes`

Matches when the immediately following sibling matches `pattern`.

# `inside`

Matches when the selected node is inside an ancestor matching `pattern`.

# `last`

Matches the last semantic child in its parent.

# `nth`

Matches the nth semantic child in its parent, using 1-based indexing.

# `parent`

Matches when the selected node has a direct parent matching `pattern`.

# `precedes`

Matches when a following sibling matches `pattern`.

# `prefix`

Builds a comment prefix matcher.

# `prefix`

# `suffix`

Builds a comment suffix matcher.

# `suffix`

# `text`

Builds a substring comment matcher.

# `text`

# `where`
*macro* 

Adds a predicate filter without changing the selected node.

Accepts structural predicates (`contains/1`, `inside/1`, etc.),
boolean expressions (`not`, `and`, `or`), and capture guards.

## Capture guards

Use `^name` to reference a captured value from the pattern. The expression
is evaluated against the captures map at match time:

    from("Enum.take(_, count)")
    |> where(match?({:-, _, [_]}, ^count))

    from("def handle_event(event, _, _) do ... end")
    |> where(^event == :click or ^event == :keydown)

    from("left == right")
    |> where(^left == ^right)

---

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