feat: add Erlang language support (.erl, .hrl)#830
Open
malou996 wants to merge 7 commits into
Open
Conversation
added 5 commits
June 12, 2026 20:46
Wire the WhatsApp tree-sitter-erlang grammar into the extraction pipeline with a custom visitNode extractor that handles Erlang's fun_decl/function_clause AST structure. Extracts modules, functions, records, type/opaque declarations, macros, imports/includes, exports, and call edges. Benchmarked on poolboy, cowboy, and EMQX — codegraph reduces file reads to zero across all three.
Erlang remote calls like `gen_server:call(...)` now emit qualified `module:function` references that resolve to functions in the target module file. On cowboy, this creates 793 cross-file call edges where previously all calls were file-local. - extractCall: detect `call` nodes inside `remote` parents and emit `module:function` as the callee name - import-resolver: add resolveErlangRemoteCall() that matches the module prefix to the target .erl file stem - test: verify gen_server:start_link, gen_server:call, my_db:lookup are extracted as qualified references
Erlang -behaviour(gen_server). now creates module→behaviour implements edges instead of import nodes. For in-project behaviours, the edge resolves to the actual module; for OTP stdlib behaviours, the reference stays unresolved rather than mis-connecting to a same-named field. On cowboy, this produces 27 correct implements edges (e.g. cowboy_router → cowboy_middleware). A callback synthesizer bridges behaviour function dispatch for in-project behaviours. - erlang.ts: behaviour_attribute emits implements unresolved reference - import-resolver: resolveErlangBehaviourImplements matches module nodes - index.ts: skip name-matcher for Erlang implements (wrong edge > missing) - callback-synthesizer: erlangBehaviourEdges bridges dispatch + adds erlang to IFACE_OVERRIDE_LANGS
Parse .app.src / .app files as Erlang, extracting the application name as a module node and the applications list as import nodes for inter-app dependency tracking.
Connect -include/-include_lib directives to their target .hrl files via file→file imports edges. Resolves same-directory includes first, then falls back to project-wide search.
added 2 commits
June 13, 2026 11:35
…queries The pre-filter, symbol lookup, and CLI commands all handled '.', '::', and '/' separators but missed Erlang's single-colon 'module:function' syntax. This caused 'mdb:dirty_insert' references to be dropped before the Erlang remote call resolver could match them, and made callers/ callees/impact return empty results when queried with the qualified name.
Author
|
Bug fix: module:function syntax in queries |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
tree-sitter-erlangWASM (ABI 14) — thetree-sitter-wasmsbuild doesn't ship one.Extraction (5 commits, layered)
aec13576ae8303module:function()calls resolve across.erlfiles without imports3a84653-behaviour(Name).declarations emitimplementsedges; OTP stdlib behaviours gracefully resolve to null3d186f1.app.src/.appOTP application metadata — application name as module node,applicationslist as import nodes3268159.hrlinclude resolution —-include/-include_libconnect to header files viafile→fileimports edgesWhat's extracted
-module(Name).), records (-record(Name, {...}).) with fieldsfun_decl), with name/arity signatures (handle_msg/2)-type,-opaque)-define(NAME, ...).→constantnodes)-export([...]).)gen_server:start_link(...)) → cross-modulecallsedges-behaviour(gen_server).) →implementsedges + callback synthesis-include,-include_lib) →importsedges to.hrlfiles.app.src) → module + dependency import nodesTest plan
npx vitest run __tests__/extraction.test.ts -t "Erlang")poolboy.app.src→ modulepoolboy+ importskernel/stdlib.hrlresolution:my_server.erl→include/records.hrlimports edgeimplementsedges (module-only matching, name-matcher bypass)