Parsing _build/**/*.cmi files; resolving free vars in *.ml files

There are two separate but related questions here, both of which are motivated by features I miss from IntelliJ/Rust that I have not quite replicated in Neovim/LSP.

  1. What is the simplest way to parse _build/**/*.cmi files ? I can’t quite get merlin / ocp-index / ocamlbrowser to work the way I want to. I want to manually parse the _build/**/*.cmi files, and dump out the type information, with all type signatures resolved to full path, so t might become Foo.t, Bar.t, Apple.t or Orange.t depending on context.

  2. I have an input ML file foo.ml ; I want to generated an equivalent foo.ml.out; where for all the free variables in foo.ml, we replace them with their global, full-module path name.

==

In both cases, we an assume the project successfully builds with dune.

The goal here is to either (1) output things that work better with grep or (2) maybe build some simple search tool in React.

The focus here at the moment is that (1) I want the “global, full module path” name of all the free variables, and (2) I want the type signatures of all global definitions, with all type parameters being the “global, full module path” name.

The library compiler-libs.common gives you access to the Cmi_format module which parses them.

Here’s an example of an API that looks up the module information stored in cmi files. I guess it could be a starting point.

1 Like

When I needed to do this (convert .cmi to .mli) I found cmitomli. Worked a treat.