Types 在Haxe中,如何向带有宏的模块添加类型/类?

Types 在Haxe中,如何向带有宏的模块添加类型/类?,types,module,macros,haxe,Types,Module,Macros,Haxe,我想根据目录中的一些文件动态地向给定模块添加一些新类型 我实际上是想在模块底部填充一堆@:file(…)嵌入类 //This is the module I'm targeting to append embedded ByteArray subtypes (see below) @:build(macros.AutoEmbed.build("some/folder/")) class Embeds { //Empty on purpose, just let the Macro do

我想根据目录中的一些文件动态地向给定模块添加一些新类型

我实际上是想在模块底部填充一堆
@:file(…)
嵌入类

//This is the module I'm targeting to append embedded ByteArray subtypes (see below)
@:build(macros.AutoEmbed.build("some/folder/"))
class Embeds {
    //Empty on purpose, just let the Macro do its thing!
}


// At "macro-time", it should generate these:

@:file("some/folder/ui_main.xml")
class UI_MAIN_XML extends flash.utils.ByteArray { }

@:file("some/folder/config.template.json")
class CONFIG_TEMPLATE_JSON extends flash.utils.ByteArray { }
到目前为止,我发现可能需要修改
Embeds.hx
模块。所以我研究了
Context.getModule(Context.getLocalModule())
。我还研究了
TypeDefinition
,因为它似乎是从头定义新类型的唯一方法

但是
Context.getModule(…)
的问题是它返回一个数组
array
,而不是
array
,所以我不能向它追加新的
TypeDefinition
(另外,我必须弄清楚如何编写它们,呃)。就我而言,这可能是一个不好的假设,但我认为,只要在其上添加更多的
TypeDefinition
,我就可以在模块中动态地提供更多类型

正如你所知道的,我对宏还是很陌生的

编辑


的确,我可以在编译时使用文件系统/文件写入解决方案动态写入/覆盖一个新的
embeddes.hx
文件,但这意味着在IDE的自动完成能够拾取生成的
embeddes.
类(在我的例子中是FlashDevelop)之前,至少需要编译一次。另外,任何时候在定义的文件夹中删除新文件,都会遇到同样的问题:您需要在IDE检测到它之前先编译。是的,我非常喜欢自动完成:)

您可以使用初始化宏:在键入之前执行宏


然后,要实际创建新的类/模块,可以使用Context.defineModule:

从build宏开始。您可以构建类字段和创建类型

这是一个宏,它只会生成一个类型和相应的字段:

#if macro
import haxe.macro.Context;
import haxe.macro.Expr;

class AutoEmbed
{
    macro static public function build(folder:String):Array<Field>
    {
        var inClass = Context.getLocalClass().get();

        // explore folder and create those:

        var fileName = 'resource/strings.json';
        var name = fileName.split('/').pop().split('.').join('_');

        var valueExpr = makeType(inClass.pack, name, fileName);

        var field = {
            name: name,
            access: [APublic, AStatic, AInline],
            kind: FVar(null, valueExpr),
            pos: Context.currentPos()
        }

        return [field];
    }

    static function makeType(pack:Array<String>, name:String, fileName:String) 
    {
        var pos = Context.currentPos();
        var className = name.toUpperCase();

        var cdef = macro class Tmp extends haxe.io.BytesData { }
        cdef.pack = pack.copy();
        cdef.name = className;

        cdef.meta = [{
            name: ':file',
            params: [Context.makeExpr(fileName, pos)],
            pos: pos
        }];

        haxe.macro.Context.defineType(cdef);

        return {
            expr:EConst(CIdent(className)),
            pos:pos
        };
    }
}
#end

漂亮完整的代码示例!谢谢但问题是,
Tmp
宏类Tmp extends haxe.io.BytesData部分中的
Tmp
从何而来?我还可以扩展flash.utils.ByteArray而不是haxe的版本吗(老实说,我不确定两者之间的区别…)?我使用了一个伪类名,因为我不知道如何在这里使用动态值。。。BytesData与Flash ByteArray相同-您可能也可以使用它。
trace(Embed.strings_json); // [ByteArray]

@:build(AutoEmbed.build('some/folder'))
class Embeds
{
    // generate field strings_json pointing to class STRINGS_JSON
}