Ppxlib: expand a structure item with others structure item

Hello !

As for now I was trying to “expand” structure item with a code like

let expand stri =
  [stri; a_new_structure_item ()]

let impl xs =
  xs |> List.map expand |> List.concat

let () =
  Driver.register_transformation "ppx" ~impl

But the problem with that is if I need to go recursively inside a structure item
(a module for example). I would need to go through the structure item myself

module Foo = struct
  let foo = .. [@@ppx]

  (* would become *)
  let foo = ..
  let new_expanded_structure_item = ..
end

It is possible indeed, but I believe Ast_traverse.map already goes through every structure item.
My goal would be to change the signature of the structure_item method like:

inherit Ast_traverse.map

method! structure_item stri : structure_item = ...

(* into *)

method! structure_item stri : structure_item list = ...

But at this point I don’t really know if something like that is possible, using the current state
of Ppxlib ? I believe it was not intended to be use in that way, but that still would help me a lot :stuck_out_tongue: !

Hi @vch9,

Two possible approaches occur to me:

  • Write your transformer at the structure level of Ast_traverse.map (lists of structure items), and do a concat_map over the children in which items with the [@@ppx] attribute expand to multiple new structure items (otherwise fun x -> [ x ]).

  • Transform the [@@ppx] attribute to the single structure item include struct ... end, which can then contain multiple structure items inside of it.

I believe I’ve seen both of those be used in other PPXes with success.

Hope this helps!

The first approach is similar to the approach I was currently following !
The second one seems to be appropriate for my purpose, I’ll go in that
direction.

Thanks for the tips !

1 Like