CSS-like AST selector builder.
Selectors are built from a starting pattern and relationship steps:
import ExAST.Selector
pattern("defmodule _ do ... end")
|> descendant("def _ do ... end")
|> child("IO.inspect(_)")The final step is the selected node. Use where/2 with predicates such as
has_child/1, has_descendant/1, parent/1, and ancestor/1 to filter the
selected node without changing it.
pattern("def _ do ... end")
|> where(has_descendant("Repo.transaction(_)"))
|> where(not(has_descendant("IO.inspect(_)")))where/2 also accepts quoted boolean predicate expressions, so you can use
Kernel.not/1 without excluding it from imports:
pattern("def _ do ... end")
|> where(not has_descendant("IO.inspect(_)"))where/2 supports capture guards using ^ to pin captured values,
allowing runtime checks on matched nodes:
pattern("Enum.take(_, count)")
|> where(match?({:-, _, [_]}, ^count))
Summary
Functions
Matches when all nested predicates match.
Builds or applies a semantic ancestor predicate.
Matches when any nested predicate matches.
Selects direct semantic children matching pattern.
Matches comments associated with the selected node.
Matches comments immediately after the selected node.
Matches comments immediately before the selected node.
Matches inline comments on the selected node start line.
Matches comments inside the selected node range.
SQL-like alias for has_descendant/1 and has_descendant/2.
Selects semantic descendants matching pattern.
Builds an exact comment matcher.
SQL-like alias for descendant/2.
Finds selector matches in source text, AST, or a Sourceror zipper.
SQL-like alias for child/2.
Matches the first semantic child in its parent.
Matches when a previous sibling matches pattern.
SQL-like alias for pattern/1.
Alias for has_descendant/1 and has_descendant/2.
Builds or applies a direct semantic child predicate.
Builds or applies a semantic descendant predicate.
Matches when the immediately previous sibling matches pattern.
Matches when the immediately following sibling matches pattern.
SQL-like alias for ancestor/1 and ancestor/2.
Matches the last semantic child in its parent.
Returns true when the selector matches at least once.
Negates a predicate for use with where/2.
Matches the nth semantic child in its parent, using 1-based indexing.
Builds or applies a direct semantic parent predicate.
Starts a selector at pattern.
Matches when a following sibling matches pattern.
Builds a comment prefix matcher.
Returns true when matching this selector depends on comments.
Returns true when matching this selector requires source text.
Alias for pattern/1.
Builds a comment suffix matcher.
Builds a substring comment matcher.
Adds a predicate filter without changing the selected node.
Types
@type relation() :: :self | :child | :descendant
@type step() :: {relation(), ExAST.Pattern.pattern() | [ExAST.Pattern.pattern()]}
@type t() :: %ExAST.Selector{filters: [ExAST.Selector.Predicate.t()], steps: [step()]}
Functions
@spec all([ExAST.Selector.Predicate.t()]) :: ExAST.Selector.Predicate.t()
Matches when all nested predicates match.
@spec ancestor(ExAST.Pattern.pattern()) :: ExAST.Selector.Predicate.t()
Builds or applies a semantic ancestor predicate.
@spec ancestor(t(), ExAST.Pattern.pattern()) :: t()
@spec any([ExAST.Selector.Predicate.t()]) :: ExAST.Selector.Predicate.t()
Matches when any nested predicate matches.
@spec child(t(), ExAST.Pattern.pattern() | [ExAST.Pattern.pattern()]) :: t()
Selects direct semantic children matching pattern.
@spec comment(String.t() | Regex.t() | ExAST.Selector.CommentMatcher.t()) :: ExAST.Selector.Predicate.t()
Matches comments associated with the selected node.
@spec comment_after(String.t() | Regex.t() | ExAST.Selector.CommentMatcher.t()) :: ExAST.Selector.Predicate.t()
Matches comments immediately after the selected node.
@spec comment_before(String.t() | Regex.t() | ExAST.Selector.CommentMatcher.t()) :: ExAST.Selector.Predicate.t()
Matches comments immediately before the selected node.
@spec comment_inline(String.t() | Regex.t() | ExAST.Selector.CommentMatcher.t()) :: ExAST.Selector.Predicate.t()
Matches inline comments on the selected node start line.
@spec comment_inside(String.t() | Regex.t() | ExAST.Selector.CommentMatcher.t()) :: ExAST.Selector.Predicate.t()
Matches comments inside the selected node range.
@spec contains(ExAST.Pattern.pattern()) :: ExAST.Selector.Predicate.t()
SQL-like alias for has_descendant/1 and has_descendant/2.
@spec contains(t(), ExAST.Pattern.pattern()) :: t()
@spec descendant(t(), ExAST.Pattern.pattern() | [ExAST.Pattern.pattern()]) :: t()
Selects semantic descendants matching pattern.
@spec exact( String.t(), keyword() ) :: ExAST.Selector.CommentMatcher.t()
Builds an exact comment matcher.
@spec find(t(), ExAST.Pattern.pattern() | [ExAST.Pattern.pattern()]) :: t()
SQL-like alias for descendant/2.
Finds selector matches in source text, AST, or a Sourceror zipper.
@spec find_child(t(), ExAST.Pattern.pattern() | [ExAST.Pattern.pattern()]) :: t()
SQL-like alias for child/2.
@spec first() :: ExAST.Selector.Predicate.t()
Matches the first semantic child in its parent.
@spec follows(ExAST.Pattern.pattern()) :: ExAST.Selector.Predicate.t()
Matches when a previous sibling matches pattern.
@spec from(ExAST.Pattern.pattern() | [ExAST.Pattern.pattern()]) :: t()
SQL-like alias for pattern/1.
@spec has(ExAST.Pattern.pattern()) :: ExAST.Selector.Predicate.t()
Alias for has_descendant/1 and has_descendant/2.
@spec has(t(), ExAST.Pattern.pattern()) :: t()
@spec has_child(ExAST.Pattern.pattern()) :: ExAST.Selector.Predicate.t()
Builds or applies a direct semantic child predicate.
@spec has_child(t(), ExAST.Pattern.pattern()) :: t()
@spec has_descendant(ExAST.Pattern.pattern()) :: ExAST.Selector.Predicate.t()
Builds or applies a semantic descendant predicate.
@spec has_descendant(t(), ExAST.Pattern.pattern()) :: t()
@spec immediately_follows(ExAST.Pattern.pattern()) :: ExAST.Selector.Predicate.t()
Matches when the immediately previous sibling matches pattern.
@spec immediately_precedes(ExAST.Pattern.pattern()) :: ExAST.Selector.Predicate.t()
Matches when the immediately following sibling matches pattern.
@spec inside(ExAST.Pattern.pattern()) :: ExAST.Selector.Predicate.t()
SQL-like alias for ancestor/1 and ancestor/2.
@spec inside(t(), ExAST.Pattern.pattern()) :: t()
@spec last() :: ExAST.Selector.Predicate.t()
Matches the last semantic child in its parent.
Returns true when the selector matches at least once.
@spec not ExAST.Selector.Predicate.t() :: ExAST.Selector.Predicate.t()
Negates a predicate for use with where/2.
@spec nth(pos_integer()) :: ExAST.Selector.Predicate.t()
Matches the nth semantic child in its parent, using 1-based indexing.
@spec parent(ExAST.Pattern.pattern()) :: ExAST.Selector.Predicate.t()
Builds or applies a direct semantic parent predicate.
@spec parent(t(), ExAST.Pattern.pattern()) :: t()
@spec pattern(ExAST.Pattern.pattern() | [ExAST.Pattern.pattern()]) :: t()
Starts a selector at pattern.
@spec precedes(ExAST.Pattern.pattern()) :: ExAST.Selector.Predicate.t()
Matches when a following sibling matches pattern.
@spec prefix( String.t(), keyword() ) :: ExAST.Selector.CommentMatcher.t()
Builds a comment prefix matcher.
Returns true when matching this selector depends on comments.
Returns true when matching this selector requires source text.
@spec selector(ExAST.Pattern.pattern() | [ExAST.Pattern.pattern()]) :: t()
Alias for pattern/1.
@spec suffix( String.t(), keyword() ) :: ExAST.Selector.CommentMatcher.t()
Builds a comment suffix matcher.
@spec text( String.t(), keyword() ) :: ExAST.Selector.CommentMatcher.t()
Builds a substring comment matcher.
Adds a predicate filter without changing the selected node.