Skip to content

feat: add Elixir language support (.ex / .exs) - #1685

Open
derekclair wants to merge 2 commits into
colbymchenry:mainfrom
derekclair:feat/elixir-language-support
Open

feat: add Elixir language support (.ex / .exs)#1685
derekclair wants to merge 2 commits into
colbymchenry:mainfrom
derekclair:feat/elixir-language-support

Conversation

@derekclair

Copy link
Copy Markdown

Closes #1219.

Indexes Elixir the way the language is written: modules, functions and macros with name/arity identity, structs, types, protocols, and alias / import / require / use. Remote Mod.fun(...) calls resolve through aliases, |> pipes and &fun/arity captures are followed, and static GenServer.call / cast plus apply / spawn MFA targets link when the module is named in source.

This is a from-scratch extractor on current main (the grammar is call-shaped, like Ruby, so definitions are dispatched in visitNode and real calls go through extractCall). Prior open PRs in this area: #871, #228.

What it extracts

  • defmodule / nested modules, def / defp / defmacro / defguard / defdelegate (multi-clause merge, arity-qualified names)
  • @spec signatures, @doc / @moduledoc, defp visibility
  • defstruct fields, @type / @typep / @opaque
  • defprotocol / defimpl, @behaviour
  • alias (including as: and Foo.{A, B}), import / require / use
  • local foo/2 and remote Foo.Bar::baz/1 calls, |> arity, &fun/arity captures
  • GenServer.call/cast(__MODULE__)handle_call/3 / handle_cast/2
  • static apply(Mod, :fun, args) / spawn(Mod, :fun, args)

Grammar: vendored elixir-lang/tree-sitter-elixir 0.3.5 (Apache-2.0, ABI 14). Mix _build / .elixir_ls are default-ignored.

Extraction (real repos)

Repo Size Files Nodes Edges verify-extraction
elixir-plug/plug Small 80 1,146 4,485 PASS
phoenixframework/phoenix Medium 238 3,243 12,380 PASS
blockscout/blockscout Large 2,668 29,501 87,775 PASS

Unit tests: Elixir extraction block in __tests__/extraction.test.ts plus __tests__/elixir-arity-resolution.test.ts (delegation, remote arity, default-args, alias resolution).

Retrieval A/B (n=1, plug only)

Question: How does Plug.Builder compile a plug pipeline so a Conn reaches each plug's call/2?

with without
duration 629s 642s
tool calls 2 2
Read 1 1
codegraph 1 explore 0
cost $0.24 $0.19

Both arms reached lib/plug/builder.ex. The with-arm called codegraph_explore then still Read the file explore had already returned (allocation miss — this answer lives in one file). Not a retrieval win on this small-repo question; extraction quality is the merge bar. Phoenix / BlockScout A/B not run here.

Follow-ups (not in this PR)

  • Phoenix / LiveView route nodes (scope / get / live) and push_navigate — see docs/design/framework-coverage.md
  • HEEx / .heex templates
  • WHEN / branch-guard rules (Elixir if / case / cond / with are call nodes)
  • OTP behaviour-callback synthesizer (Erlang already has this for Var:callback(...) folds)

Re-index Elixir projects after upgrading.

Index Elixir modules, functions/macros (with arity identity and
multi-clause grouping), structs, types, protocols, and
alias/import/require/use. Remote Mod.fun calls resolve through
aliases, pipes and &fun/arity captures are followed, and static
GenServer.call/cast plus apply/spawn MFA targets link when the
module is named in source.

Closes colbymchenry#1219.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0062954fcb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/extraction/languages/elixir.ts Outdated
Comment thread src/extraction/languages/elixir.ts
Comment thread src/resolution/name-matcher.ts Outdated
Comment thread src/extraction/languages/elixir.ts Outdated
Comment thread src/extraction/languages/elixir.ts Outdated
Aliases and imports now apply in source order, including inside a
function (copied maps, popped per clause). An explicit import only:
list emits the qualified target and not the bare name. Local Elixir
calls resolve to the caller's enclosing module. Each defimpl is its
own module scope so two implementations in one file no longer share
callback names.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Elixir

1 participant