I'm trying to use Haxe to generate a Javascript file in which each static function/variable is named like a module-level field (package_ClassName_fieldName rather than package_ClassName.fieldName). I'd also like to be able to use build macros though, and as far as I know, those aren't usable with actual module-level fields. Is there some way to get the best of both worlds?
I've tried using build macros to change the class type:
import haxe.macro.Context;
import haxe.macro.Expr; // Field
import haxe.macro.Type; // ClassKind, ClassType
class Macro {
public static macro function convertClassToModuleLevelFields() : Array<Field> {
var ct:ClassType = Context.getLocalClass().get();
ct.kind = ClassKind.KModuleFields(ct.module);
return Context.getBuildFields();
}
}
...but it didn't seem to change anything. Context.defineModule and Context.defineType seemed good for redefining the static class fields as module-level fields, but it doesn't seem like I can convert a class's ClassType to an equivalent TypeDefinition. Compiler.setCustomJSGenerator sounded promising too, but JSGenApi.generateValue always uses dots. Is there any way to do this?
If this is for purposes of interfacing with the code, you could give fields an
@:exposemetadata with a macro:and then
would produce
and you'd be able to access your functions via
window.Test_oneorglobal.Test_one(depending on where JS is running).You can also use
to add a
@:buildto all classes in a package, though note that doing so includes them in the build even if DCE would usually consume them (bug? feature?).If this is for purposes of optimizing the generated code for Closure (github issue), you'd want to use CustomJSGenerator but write your own printer for some/all expressions instead of using
JSGenApi.generateValue. I used to maintain a generator for this, but eventually gave up on it since the gains weren't as noticeable in larger projects.