I’m attempting to write some tracing-support ppxes. These basically wrap functions in debugging information.
Short of annotating every module declaration in the file with an extension-attribute, is there a way for me to derive the fully qualified module-name of a given let that has been annotated?
i.e. given
module Sth = struct
module Widget = struct
let%foo func arg arg2 = (* ... *)
end
end
can I reasonably expect to produce the string "My_file.Sth.Widget.func" without resorting to non-context-free APIs?
(A subset is fine, this doesn’t need to be absolutely perfect — I just need more debugging info than (file_name, binding_name) when a value in a large file is named something like make, haha.)
Look here: GitHub - ocaml-ppx/ppx_deriving: Type-driven code generation for OCaml and search for “with_path”. I don’t know how they do it (you can look in the code of their “show” deriver to see it) b/c I merely implemented that same function in my Camlp5-based verison of the “show” deriver. My guess is they did it the same way I did: carry a context that is inherited down the AST, and update the “path” component of that context as you traverse module-definitions.
Yeah, that’s definitely one approach — unfortunately, it’ll require a non-context-free impl. Which I’m afraid may be inevitable, but still, thought someone may have some ideas …
In fact, even if, at first sight, it seems like your transformation isn’t context-free, it’s likely that you can find a more suitable abstraction with which it becomes context-free. Whenever that’s the case, go for context-free!
It would seem that in order to achieve your end, somebody somewhere has to be context dependent. It might not be your code, but it will be code that calls your code or is called by your code or is called after your code. One way or another something is going to be context sensitive.
“Context-free” transformations still have access to some “non context-free” information: see the ctxt argument of the expand function.
This context contains in particular a code_path component, that allows you to retrieve the information listed here. I hope that helps achieve what you want!