reify(println)编译。
你如何想象功能的象征println (_:String)?这个函数是在哪里定义的?在两种方法中定义:Predef
def println(): Unit
def println(x: Any): Unit
尝试
val mirror = scala.reflect.runtime.universe.runtimeMirror(this.getClass.getClassLoader) // at runtime
// val mirror = c.mirror // at compile time
mirror.staticClass("mypackage.MyClass").typeSignature.decl(TermName("myfunc"))
// method myfunc
或者
typeOf[MyClass].decl(TermName("myfunc"))
// method myfunc
为了MyClass#myfunc
definitions.PredefModule.typeSignature.decl(TermName("println")).alternatives
// List(method println, method println)
对彼此而言println
definitions.PredefModule.typeSignature.decl(TermName("println")).alternatives
.filter(_.asMethod.paramLists.map(_.map(_.typeSignature)) == List(List(definitions.AnyTpe)))
// List(method println)
为println(Any):Unit.
例如
def foo(x: Any): Unit = macro impl
def impl(c: blackbox.Context)(x: c.Tree): c.Tree = {
import c.universe._
val printlnSymb = definitions.PredefModule.typeSignature.decl(TermName("println")).alternatives
.filter(_.asMethod.paramLists.map(_.map(_.typeSignature)) == List(List(definitions.AnyTpe)))
.head
x match {
case q"$f($x)" if f.symbol == printlnSymb =>
println("test")
}
q"()"
}
foo(println(1)) //Warning:scalac: test
reify( println (_:String) ).tree.collect { ...仅List(<none>, <none>, <none>, scala.Predef, <none>, <none>, scala.Predef, <none>, <none>, scala.Predef)因为树reify( println (_:String) ).tree未经过类型检查而产生(对于经过类型检查的树,它会产生List($anonfun, x$1, java.lang.String, scala.Predef.println, scala.Predef.println, scala.Predef, x$1, java.lang.String))。
所以另一个选择是做c.typecheck
def impl(c: blackbox.Context)(x: c.Tree): c.Tree = {
import c.universe._
val printlnSymb = (c.typecheck(q"println(_:Any)", silent = false) match {
case q"($_) => $p($_)" => p
}).symbol
//val printlnSymb = (c.typecheck(reify { println(_:Any) }.tree, silent = false) match {
// case q"($_) => $p($_)" => p
//}).symbol
x match {
case q"$f($x)" if f.symbol == printlnSymb =>
println("test")
}
q"()"
}