如何使用宏获取类方法的参数类型?

时间:2019-05-02 15:38:19

标签: macros haxe

如何使用宏获取类方法的参数类型?

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{
 } 

}

构造字母时,我将调用一个具有类型参数的方法。

2 个答案:

答案 0 :(得分:3)

您可以将out传递给表达式宏,然后在其上使用Context.typeof()。结果将是function typeTFun),您可以使用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';
        }
    }
}