Hi,
I have a macro function that can successfully match on an expression
(functions only) using quasiquotes and get an identifier if possible (not
the case of anonymous functions). Now I would like to:
a) Find information regarding the function types
b) And in particular find were the function was declared (type and
position were it is defined)
As an initial step I defined this function:
private def getFuncDef[T:c.WeakTypeTag](c: blackbox.Context)(expr: c.Expr[T]): String = {
import c.universe._
println(showRaw(expr.tree.tpe))
expr.tree.tpe match {
case tq"(..$param) => $body" =>
println(showRaw(param))
println(showRaw(body))
""
case _ =>
println("???????")
""
}
}
Now my problem is that when I pass a function, it never matches.
Say I have a class were in I define a method f
.
class FuncBlob() {
def f(b:Int):Int = -b
val h: Int => Double = (b:Int) => (2*b).toDouble
}
When I pass on f
, I have the following information:
func.tree = {
((b: Int) => blob.f(b))
}
func.tree.type = Int => Int
func.tree.class = class scala.reflect.internal.Trees$Block
func.actualType = Int => Int
func.staticType = Nothing
func.tree.isDef = false
func.tree.isTerm = true
func.tree.isType = false
Raw: Block(List(), Function(List(ValDef(Modifiers(PARAM | SYNTHETIC), TermName(“b”), TypeTree(), EmptyTree)), Apply(Select(Ident(TermName(“blob”)), TermName(“f”)), List(Ident(TermName(“b”))))))
In this case this match works:
expr.tree match {
case q"{ ($paramIn) => $call($param)}" =>
println(s"$call($paramIn) => ???")
call.toString
Notice how we have a Block
that has a Function
. The getFuncDef
prints out:
TypeRef(ThisType(scala), scala.Function1, List(TypeRef(ThisType(scala), scala.Int, List()), TypeRef(ThisType(scala), scala.Int, List())))
Again, we have a Functon1
, but matching fails (2.12.6). So what is wrong
with the quasiquote?
In regards to point (b), is it possible for me to determine that blob.f
is is the def f
in the FuncBlob
class.
Appreciate any pointers.
TIA