maxmc
maxmc

Reputation: 4216

Scala macro: argument types of a function reference

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

Answers (1)

Alexey Romanov
Alexey Romanov

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

Related Questions