假设我已经创建了一个可以像这样使用的构建宏
@:build(macros.SampleMacro.build("arg"))
class Main {}
Run Code Online (Sandbox Code Playgroud)
是否可以将其转换为自定义的速记元数据?
@:samplemacro("arg")
class Main {}
Run Code Online (Sandbox Code Playgroud)
有这方面的文档吗?
经过多次绊倒后,我发现这是可以做到的。
解决方案的一部分是使用
--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/