如何使用宏获取类方法的参数类型?
class A{
public function new(){
//this how get method out arg[0] Type with macro?
var arg0IsInt:Bool=arg0IsInt(out);
}
public function out(a:Int){ return true; }
macro public function arg0IsInt(e:Expr):Bool{
}
}
构造字母时,我将调用一个具有类型参数的方法。
答案 0 :(得分:3)
您可以将out
传递给表达式宏,然后在其上使用Context.typeof()
。结果将是function type(TFun
),您可以使用pattern matching检查其第一个参数。
这是一个可行的示例:
import haxe.macro.Context;
import haxe.macro.Expr;
class Main {
static function main() {
new Main();
}
public function new() {
trace(arg0IsInt(out)); // true
trace(arg0IsInt(out2)); // false
}
public function out(a:Int) {}
public function out2(a:Float) {}
macro static function arg0IsInt(func:Expr):Expr {
return switch Context.typeof(func) {
case TFun(args, _):
switch args[0].t {
case TAbstract(_.get() => t, _) if (t.name == "Int" && t.pack.length == 0):
macro true;
case _:
macro false;
}
case _:
throw 'argument should be a function';
}
}
}
Int
是一个abstract
,并且要确保它不是在某些其他软件包中恰好被命名为Int
的随机抽象,我们检查它是否在顶级软件包中(pack.length == 0
。
答案 1 :(得分:2)
实际上,使用模式匹配可以走得很远:
import haxe.macro.Context;
import haxe.macro.Expr;
class Test {
static function main() {
new Test();
}
public function new() {
trace(arg0IsInt(out)); // true
trace(arg0IsInt(out2)); // false
}
public function out(a:Int) {}
public function out2(a:Float) {}
macro static function arg0IsInt(func:Expr):Expr {
return switch Context.typeof(func) {
case TFun(_[0] => {t: TAbstract(_.get() => {name: 'Int', pack: []}, _)}, _): macro true;
case TFun(_): macro false;
case _: throw 'argument should be a function';
}
}
}