Haxe 自定义元数据到宏调用

Dan*_*ski 5 macros haxe

假设我已经创建了一个可以像这样使用的构建宏

@:build(macros.SampleMacro.build("arg"))
class Main {}
Run Code Online (Sandbox Code Playgroud)

是否可以将其转换为自定义的速记元数据?

@:samplemacro("arg")
class Main {}
Run Code Online (Sandbox Code Playgroud)

有这方面的文档吗?

Dan*_*ski 5

经过多次绊倒后,我发现这是可以做到的。

解决方案的一部分是使用

--macro addGlobalMetadata('$path', '@:build(Build.build())')
Run Code Online (Sandbox Code Playgroud)

这允许您将 @:build 函数分配给 $path 中的所有类。这可以用作编译器选项或 haxflag。

但这本身还不足以采用采用动态参数的元数据标签。但是因为我们现在有一个针对所有类执行的 Build.build() ,所以Build.build() 函数既可以处理检查哪些类具有我们的自定义元数据标记,也可以为我们的这些类构建任何内容。可能需要。

为了检查我们的自定义元数据标签,我们设置检查宏如下:

class Build {

    static var META_STR:String = ":samplemacro";

    macro static public function build():Array<Field> {

        // We check only those Contexts for where a class type exists
        var localClass:Null<Ref<ClassType>> = Context.getLocalClass();
        if(localClass == null) return null; // no class type

        // We check if the metadata for the class contains our 
        // custom metadata string at all
        if(!localClass.get().meta.has(META_STR)) return null;

        // This class does have our custom metadata!
        // Because there may be more than one of the same type
        // of metadata, we extract a list of all the custom metadata tags

        var customTags = localClass.get().meta.extract(META_STR);

        // For each tag we can get at the arguments passed in 
        // by accessing the params field
        for(customTag in customTags){
            var params = customTag.params;

            // Here we can handle each of our @:samplemacro(params) tags,
            // save the params for use later, or 
            // pass the arguments over to another class to deal with
        }

        var fields = Context.getBuildFields();

        // Modify the class fields the way you want

        // Optionally destroy the metadata tags afterwards
        // with localClass.get().meta.remove(META_STR);

        return fields;
    }
}
Run Code Online (Sandbox Code Playgroud)

有关 addGlobalMetadata 的更多详细信息,请访问: /sf/answers/2665284471/

  • 有一个库可以完成确切的事情,并具有一些附加功能:https://github.com/haxetink/tink_syntaxhub (2认同)