Commit Graph
3 Commits
Author SHA1 Message Date
rajatnagda45 1edda3a704 fix(ocaml): extract classes and their methods and instance variables
The OCaml walker had no branch for class_definition, so a class object --
its methods, its instance variables, and the calls made from method bodies --
was dropped entirely. A file made only of classes produced no nodes at all.

Add a class_definition branch that mints the class node (defines/contains),
walks the object body (object_expression in .ml, class_body_type in .mli) for
method and instance-variable members, and attributes calls in each method body
to that method. Method names are deliberately not registered as local defs:
they are reachable only through obj#m, so binding a bare call to a same-named
method would be a false edge.

(cherry picked from commit 63572f0cbe)
2026-09-26 13:45:58 +01:00
safishamsiandClaude Opus 4.8 9e2387f3e8 fix(ocaml): don't bind a qualified external call to a same-named local def
A qualified call `M.f` where `M` is not a module defined in the same file is
an external-library call (e.g. Hardcaml's `Reg_spec.create`, `Scope.create`).
Resolving it by bare last name bound it to a same-named local `let f`,
producing a false `calls` edge and a `create -> create` self-loop when the
caller was that local `f`. Now: track locally-defined module names; a
qualified call whose root module is not local and whose bare name collides
with a local def is kept as a distinct external target (stub labelled by the
full path), so it neither self-loops nor collapses onto the local def.
Unqualified calls and calls into a locally-defined module still resolve
locally, and cross-file `Geo.area` still collapses onto another file's `area`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-14 21:09:32 +01:00
safishamsiandClaude Opus 4.8 0302bfa7af feat(ocaml): add OCaml .ml/.mli extractor (optional tree-sitter-ocaml extra)
New graphify/extractors/ocaml.py handles both the implementation grammar
(language_ocaml, .ml) and the interface grammar (language_ocaml_interface,
.mli). Emits nodes for modules, top-level/module-level values and functions,
types and their variant constructors; edges for defines/contains, open ->
imports_from, and application -> calls. Qualified paths (Geo.area) resolve to
the final value name, not the module qualifier; local let ... in bindings do
not mint nodes or steal call attribution. Cross-file open/call targets are
sourceless stubs so the corpus rewire collapses them onto the unique real
definition (no #1402 sourced-stub leak).

Wired into detect.py (CODE_EXTENSIONS), extract.py (dispatch +
_EXTRA_FOR_EXTENSION), pyproject.toml ([ocaml] extra + all + dev dep), and
README. Adds tests/test_ocaml.py (behind importorskip).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-14 14:17:07 +01:00