Beamscope.Callgraph.Extractor (Beamscope v0.1.0)

Copy Markdown View Source

Extracts function definitions and call edges from a single file using the same in-process parsers as the chunkers (:epp for Erlang, Code.string_to_quoted for Elixir) — not a second tree-sitter pass, which is what the original call_extractor.py uses. This is Phase 0's core untested hypothesis for the call graph: that a compiler-accurate parse can drive it too, and — for Erlang specifically — one that sees through macro expansion in a way tree-sitter structurally cannot, since :epp fully expands macros as part of parsing while tree-sitter only ever sees the raw ?MACRO(...) token.

Elixir macros are a different story: Code.string_to_quoted/2 parses syntax only, it does not expand macros (that happens later, during compilation) — so a call hidden behind an Elixir macro is just as invisible here as it is to tree-sitter. The macro-transparency advantage is Erlang-specific.

Returns {defs, edges}:

  • defs: [%{name:, module:, file_path:, start_line:, end_line:}]
  • edges: [%{caller_module:, caller_name:, callee_module:, callee_name:, file_path:, line:}]

callee_module: "?" marks a call whose target module couldn't be statically resolved (e.g. Mod:Fun() where Mod is a variable, or Mod.fun() where Mod isn't a literal alias) — matching call_extractor.py's convention so results stay comparable.

Summary

Functions

extract_from_file(path, opts \\ [])

@spec extract_from_file(
  String.t(),
  keyword()
) :: {[map()], [map()]}