ExAST (ExAST v0.3.0)

Copy Markdown View Source

Search and replace Elixir code by AST pattern.

Patterns are valid Elixir syntax:

  • Variables (name, expr) capture matched nodes
  • _ and _name are wildcards
  • Structs/maps match partially
  • Pipes are normalized (data |> Enum.map(f) matches Enum.map(data, f))
  • Everything else matches literally

Options

  • :inside — only match nodes inside an ancestor matching this pattern
  • :not_inside — reject nodes inside an ancestor matching this pattern

Examples

# Find all IO.inspect calls
ExAST.search("lib/**/*.ex", "IO.inspect(_)")

# Find IO.inspect only inside test blocks
ExAST.search("test/", "IO.inspect(_)", inside: "test _ do _ end")

# Replace dbg with the expression itself
ExAST.replace("lib/**/*.ex", "dbg(expr)", "expr")

# Match piped and direct calls interchangeably
ExAST.search("lib/", "Enum.map(_, _)")  # also finds `data |> Enum.map(f)`

Summary

Functions

Replaces AST pattern matches in files.

Searches files for AST pattern matches.

Types

match()

@type match() :: %{
  file: String.t(),
  line: pos_integer(),
  source: String.t(),
  captures: ExAST.Pattern.captures()
}

Functions

replace(paths, pattern, replacement, opts \\ [])

@spec replace(String.t() | [String.t()], String.t(), String.t(), keyword()) :: [
  {String.t(), pos_integer()}
]

Replaces AST pattern matches in files.

Options:

  • :dry_run — return changes without writing (default: false)
  • :inside — only replace inside ancestors matching this pattern
  • :not_inside — skip replacements inside ancestors matching this pattern

Returns a list of {file, count} tuples for modified files.

search(paths, pattern, opts \\ [])

@spec search(String.t() | [String.t()], String.t(), keyword()) :: [match()]

Searches files for AST pattern matches.

Returns a list of match maps with :file, :line, :source, and :captures. Accepts :inside and :not_inside options to filter by context.