Searches for AST patterns in Elixir source files.
Usage
mix ex_ast.search 'IO.inspect(_)' [path ...]Options
--count— only print the number of matches--inside 'pattern'— only match inside ancestors matching this pattern--not-inside 'pattern'— reject matches inside ancestors matching this pattern--parent 'pattern'/--not-parent 'pattern'— filter by direct semantic parent--ancestor 'pattern'/--not-ancestor 'pattern'— filter by semantic ancestor--has-child 'pattern'/--not-has-child 'pattern'— filter by direct semantic child--has-descendant 'pattern'/--not-has-descendant 'pattern'— filter by semantic descendant--has 'pattern'/--not-has 'pattern'— aliases for descendant filters
Pattern syntax
Patterns are valid Elixir expressions:
- Variables (
name,expr) — capture any node _or_name— wildcard (match, don't capture)- Structs/maps — partial match (only listed keys must be present)
- Pipes are normalized —
data |> Enum.map(f)matchesEnum.map(data, f) - Everything else — literal match
Examples
mix ex_ast.search 'IO.inspect(_)'
mix ex_ast.search '%Step{id: "subject"}' lib/documents/
mix ex_ast.search '{:error, reason}' lib/ test/
mix ex_ast.search --count 'dbg(_)'
mix ex_ast.search --inside 'def handle_call(_, _, _) do _ end' 'Repo.get!(_)'
mix ex_ast.search --not-inside 'test _ do _ end' 'IO.inspect(_)'
mix ex_ast.search 'IO.inspect(_)' --parent 'def _ do ... end'
mix ex_ast.search 'def name do ... end' --has 'Repo.transaction(_)' --not-has 'IO.inspect(_)'