If anyone is interested in tackling this, here are some ideas:
optionally let the user specify the query kind (expression, pattern, top-level item, …) via a command-line option;
if the query kind isn’t specified, try parsing the query both as an expression and as a pattern, resulting effectively in one or two queries depending on parsing success;
I think it could be useful to scan for match cases such as | Foo _ -> Error (__ : string) but unfortunately, compiler-libs doesn’t offer an entry point for parsing just a match case. See what’s available in ocaml/parsing/parse.mli at trunk · ocaml/ocaml · GitHub
Yes, but this requires loading (at least partially) all the cmt files to determine which ones are relevant, right? I’m worried about performance when scanning small portions of large projects.
This kind of misses the point, just let me drive ocamlgrep the way I want :–) Command line tools are not necessarily invoked manually. It’s a bit like saying that providing -I options to ocamlc is a bit cumbersome because this needs to be done every time I want to build.
This is why I suggest to first match on file names and only load the .cmt files and check that field only on ambiguities. Except perhaps for that test.ml file, compilation unit names are reasonably unique.
Regarding semantic equivalences, the Coccinelle tool for C gives the ability to define “isomorphisms” (see. standard.iso ) so the user can define easily equivalences reusing the same syntax used for queries. The semgrep tool had a similar capability at some point but it got removed because no one was using the feature. It was pretty cool though (shoutout to Julia Lawall for the original idea).
The way it was implemented was to actually run the semgrep (or coccinelle) matching engine on the query itself (very meta) and rewrite the query as a set of disjunctive patterns (the matching language was expressive enough to support disjunction, conjonction, negation) by running the isomorphic rewrite rules on the query.