Analysis of all cases @:genericBuild before type definition

@:genericBuild(GenericBuildMacro.build())
class MyType<Rest> {}

Type-building macro builds new classes and fields defined by parameters of type Rest. The task is to find equal fields for such classes and determine the chain of inheritance between them. Because the macro is executed sequentially and requires the new type to be returned immediately, you cannot first collect all cases of using MyType<Rest> before generation to analysis. Could there be some way to do this?

Only way I can think of right now is to build in two passes: first pass with -D no-compilation (disables final compilation) which stores all collected cases of MyType into @:persistent static variable(s) inside your GenericBuildMacro (keeping the value of static variables in macro context across compilations) and then second pass which builds MyType based on analyses. Here you have several options: to make analyses at first pass inside build(), second pass or “in the middle” using haxe.macro.Context.onAfterTyping (invoked after the compiler is done typing)

This is an interesting solution. But after some searching, I seem to have found a way to do all this in one build process.
First we build the preliminary versions of the classes (in my case they are completely ready, except for information on inheritance), simultaneously collecting all the cases of use. Then, in onAfterTypeng(), we add @:native("MyTypeFinal") metadata to all these classes and exclude() them from compilation. All that remains is to define types the final classes.

1 Like

Clever, thanks for sharing. Does your exclude() makes definition of MyTypeFinal for each collected case, thus making onAfterTyping to be called again?

The first call to onAfterTyping() creates all modified versions of the required classes. Yes, onAfterTyping() is called again, but the second call I already do not change anything.