I am currently working on a ppx rewriter, my rule is attached to structured item. I was wondering if there was a way to retrieve information on that context ?
let expand ~ctxt e =
..
let my_rule =
Extension.V3.declare_inline "my_ppx"
Extension.Context.structure_item
<payload>
expand
where ctxt in expand has type:
type Expansion_Context.Extension.t =
{ extension_point_loc : Location.t ; base : Base.t }
(* with Base.t *)
type Base.t =
{ tool_name : string ;
code_path : Code_path.t ;
input_name : string }
In a example:
let add x y = x + y
[%%my_pbt <payload>]
My goal would be to have access to fields such as [add x y] or [x + y]. But I have no idea at this point if it’s possible ?
Firstly, it’s worth noting that Ppxlib is expressive enough to handle any AST → AST transformation you can dream up (via Driver.register_transformation if needbe). It’s just a question of whether your use-case fits into any of the “simpler” APIs that Ppxlib provides.
If your goal is to attach metadata to a structure item, consider using attributes rather than extension points ([@@my_pbt <payload>] rather than [%%my_pbt <payload>]). At the syntax level, item extension points (with %%) are not “attached” to anything but sit inside the parent structure / signature as independent items. So the syntax you describe will look at the AST level more like the following:
(* List of four structure items: *)
let add x y = x + y
[%%my_pbt <payload>]
let sub x y = x + y
[%%my_pbt <payload>]
… and a tool like OCamlformat will format it as such. Item attributes (@@) are actually attached to specific items, and so it’s probably easier to get Ppxlib to reflect your intended interpretation using these.
Unfortunately, it seems Context_free.Rule is missing the exact function you’d need, so you’ll probably want to use Ast_traverse.map with a hand-written method for transforming items with your attribute. You can then pass the #structure method to Driver.register_transformation.