Skip to content

Releases: elixir-vibe/ex_ast

v0.12.0

15 May 09:05

Choose a tag to compare

Added

  • JSON output for mix ex_ast.search, mix ex_ast.replace, and mix ex_ast.diff via --format json / --json, backed by Jason.Encoder protocol implementations for ExAST result structs.
  • %ExAST.CompiledPattern{} metadata for compiled patterns, including candidate signatures, structural terms, and broad/multi-node flags.
  • ExAST.Pattern.compile_ast/1 for callers that need the normalized pattern AST.
  • ExAST.rewrite_plan/4 and ExAST.Rewriter for inspecting replacement plans before applying patches, with overlapping-replacement conflict detection.
  • File-level parallelism for unbounded ExAST.search/3 and search_many/3, configurable with :concurrency.
  • Conservative source-text prefiltering using index terms to avoid parsing files that cannot match a pattern.
  • ExAST.Comments.associated/3 for retrieving comments related to a source range (:before, :after, :inside, :inline, or aggregate :comment).
  • Import-aware call matching for imported functions such as import Ecto.Query, only: [from: 2] matching Ecto.Query.from(_, _).
  • Reach, ExSlop, and ExDNA-backed static analysis hardening in CI via an isolated tools/reach_runner project.

Changed

  • ExAST.Pattern.compile/1 now returns %ExAST.CompiledPattern{} instead of a raw normalized AST. Use ExAST.Pattern.compile_ast/1 for the old AST shape.
  • ExAST.search/3 results now include the matched :range.
  • ExAST.replace/4 now plans rewrites before applying them and supports format: true; the CLI exposes this as --format-output.
  • Syntax-aware diffing now treats same-body function renames as function updates rather than delete+insert pairs.
  • mix ci now includes explicit ExSlop smell analysis and Reach smell/dead-code checks in addition to existing compile, format, Credo, Dialyzer, tests, and ExDNA checks.

v0.11.2

12 May 12:58

Choose a tag to compare

Fixed

  • Wildcard _ and _name now match function names in def/defp patterns with arguments. Previously defp _(_), do: _ would not match defp helper(x), do: x + 1.

v0.11.1

11 May 09:05

Choose a tag to compare

Added

  • piped() selector predicate — matches only when the selected node is a pipe expression (|>). Since ExAST normalizes pipes during matching, there was previously no way to distinguish piped from direct call forms. Use where(piped()) to match only piped calls, or where(not piped()) for direct calls only.

v0.11.0

06 May 14:11

Choose a tag to compare

Added

  • ExAST.Index.plan/1, ExAST.Index.terms/1, and structural index plan
    structs for building external candidate indexes while keeping ExAST as the
    semantic verifier.
  • ExAST.Index.Terms.from_source/1, from_ast/1, from_pattern/1, and term
    signal classification helpers.
  • ExAST.Selector.requires_source?/1, requires_comments?/1, find_all/3,
    and match?/3 for source-aware selector planning and verification.
  • ExAST.Comments.extract/1 and ExAST.Comments.text/1 for comment extraction
    with source position metadata.
  • ExAST.Symbols.definitions/1 and ExAST.Symbols.references/1 for syntactic
    definition/reference extraction.
  • Symbol helpers for stable qualified names and optional BEAM-native MFA tuples:
    ExAST.Symbols.qualified_name/1, mfa/1, and matches?/2.
  • Indexing and code intelligence guide.

v0.10.1

05 May 12:25

Choose a tag to compare

Fixed

  • Restored pipe-aware pattern matching after the 0.10.0 candidate prefilter optimization. Piped calls such as data |> Enum.map(fun) now match direct call patterns like Enum.map(_, _) again.

v0.10.0

05 May 12:16

Choose a tag to compare

Added

  • ExAST.Patcher.find_many/3 for running multiple named AST pattern checks in a single traversal where possible, returning matches tagged with :pattern.
  • ExAST.search_many/3 for searching files with multiple named patterns while preserving search/3 options such as :limit.

Changed

  • Optimized repeated single-node pattern matching by compiling patterns once, normalizing candidate nodes once per traversal, and using conservative call signature prefilters for common local, remote, piped, and nested call patterns.

v0.9.1

04 May 11:17

Choose a tag to compare

Changed

  • Restructured documentation: short README with topic-based guides (Getting Started, Pattern Language, Querying, CLI Reference, Diff)

v0.9.0

04 May 10:42

Choose a tag to compare

Added

  • Capture guardswhere/2 now accepts ^pin syntax to filter on captured values, similar to Ecto's parameter references. Supports match?/2 for structural checks, plain comparisons, multi-capture expressions, and composition with existing structural predicates.

  • Source text in match resultsPatcher.find_all/3 now includes a :source field with the matched source snippet.

  • Module attribute pattern matching — attribute names are now captureable: @name Application.get_env(_, _)

v0.8.1

01 May 08:55

Choose a tag to compare

Fixed

  • CLI commands now handle closed stdout pipes cleanly, so commands like mix ex_ast.search ... | head no longer emit EPIPE writer crash messages.

v0.8.0

28 Apr 10:34

Choose a tag to compare

Added

  • Comment predicates for source-aware queries: comment/1, comment_before/1, comment_after/1, comment_inside/1, and comment_inline/1.
  • Comment matchers accept strings, regexes, and explicit text matchers like prefix/2, suffix/2, and text/2.
  • CLI comment filters detect /.../ and ~r/.../ regex syntax.

Hex: https://hex.pm/packages/ex_ast/0.8.0
Docs: https://hexdocs.pm/ex_ast/0.8.0