Finds and replaces AST patterns in source code.
Accepts source strings, AST nodes, or Sourceror zippers as input. Patterns and replacements can be strings or quoted expressions.
Source-string input preserves formatting via Sourceror.patch_string/2.
AST/zipper input returns modified AST trees.
# All equivalent
Patcher.find_all(source, "IO.inspect(_)")
Patcher.find_all(ast, quote(do: IO.inspect(_)))
Patcher.find_all(zipper, quote(do: IO.inspect(_)))
import ExAST.Selector
Patcher.find_all(source, pattern("defmodule _ do ... end") |> descendant("IO.inspect(_)"))
Summary
Types
@type match() :: %{ node: Macro.t(), range: Sourceror.Range.t() | nil, captures: ExAST.Pattern.captures(), source: String.t() | nil }
Functions
@spec find_all( String.t() | Sourceror.Zipper.t() | Macro.t(), ExAST.Pattern.pattern() | ExAST.Selector.t(), keyword() ) :: [match()]
Finds all occurrences of pattern.
The first argument can be a source string, a Sourceror.Zipper, or a raw AST.
The pattern can be a string or a quoted expression.
Returns a list of match maps with:
:node— the matched AST node:range— aSourceror.Range.t()with line/column positions, ornil:captures— a map of captured names to AST nodes:source— the matched source text, ornilfor AST/zipper input
Range fields are accessed as keyword lists:
match.range.start[:line] #=> line number (1-based)
match.range.start[:column] #=> column number (1-based)
match.range.end[:line]
match.range.end[:column]Options
:inside— only match nodes nested within an ancestor matching this pattern:not_inside— reject nodes nested within an ancestor matching this pattern
@spec replace_all( String.t(), ExAST.Pattern.pattern() | ExAST.Selector.t(), ExAST.Pattern.pattern(), keyword() ) :: String.t()
@spec replace_all( Sourceror.Zipper.t() | Macro.t(), ExAST.Pattern.pattern() | ExAST.Selector.t(), ExAST.Pattern.pattern(), keyword() ) :: Macro.t()
Replaces all occurrences of pattern with replacement.
When given a source string, returns a modified source string with formatting preserved. When given a zipper or AST, returns modified AST.
Pattern and replacement can be strings or quoted expressions.
Captures from the pattern are substituted into the replacement template.
Accepts the same :inside / :not_inside options as find_all/3.