Reputation: 4216
I'm writing a scala macro, which inspects a given function to find it's argument names and types.
def hello(i: Int, s: String) = s + i
It works so far, if I feed the macro like this:
val args: TypeInfo = signature(hello _)
But I also want to be able to supply just a reference to the original function:
def invokeMacro(f: (Int, String) => String) = signature(f)
invokeMacro(hello)
Unfortunately this does not work.
Here is how I obtain the type info within the macro:
val typeInfo = TypeInfo(t.filter(_.isDef).collect {
case ValDef(_, name, typ, _) =>
name.decodedName.toString -> typ.tpe.toString
})
Now I wonder, if it is possible to get hold of the original function 'hello' inside the macro and extract it's type info. Scrutinizing the information available inside the macro with the debugger did not yield what is was hoping for.
So I wonder is it possible, if not: why? If it's possible, how?
Upvotes: 0
Views: 188
Reputation: 170713
Because invokeMacro
is a function, not a macro, it doesn't get its argument's AST, and signature
just sees Ident(TermName("f"))
as its argument (or something like that). This is not a ValDef
, so your match fails. And of course, the name hello
isn't there in any way (but you could get the type).
To work around this, invokeMacro
itself would need to be a macro which just generates the signature(f)
call. Or, more generally, have
def invokeMacro0[A](f: () => A) = macro...
def invokeMacro1[A, B](f: A => B) = macro...
def invokeMacro2[A, B, C](f: (A, B) => C) = macro...
...
Upvotes: 1