Search code examples
macroshaxe

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


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

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

}

I'm going to call a method that has a parameter for a type when I construct a letter.


Solution

  • You can pass out to the expression macro and then use Context.typeof() on it. The result will be a function type (TFun) whose first argument you can inspect using pattern matching.

    Here's a working example:

    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 is a an abstract, and to make sure it's not just some random abstract that happens to be named Int in some other package, we check that it's in the toplevel package (pack.length == 0).