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

How to get the parameter type of the class method with macro?

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

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

}

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

您可以将out传递给表达式宏,然后使用Context.typeof() on it. The result will be a function type (TFun) whose first argument you can inspect using 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).

事实上,模式匹配可以走得更远:

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';
        }
    }
}