scala AST - 什么是字符串常量文字,我如何找到?
scala AST - what IS a string constant literal and how do I find out?
考虑以下片段
object Main {
def main(args:Array[String]): Unit ={
import Debugger.debug
debug("Hello World")
val x = 0
debug(x)
debug(1)
}
}
我要打印这个
Hello World
x = 0
1
通过使用宏:
import scala.language.experimental.macros
import scala.reflect.macros._
object Debugger {
val doDebug = true
def debug(v : Any) :Unit = macro implDebug
def implDebug(c:blackbox.Context)(v:c.Expr[Any]): c.Expr[Unit] ={
import c.universe._
if(doDebug) {
v match {
case Literal(Constant(_)) => reify{println(v.splice)}
case _ =>
println(v.tree)
println(v.tree.getClass.getName)
val rep = show(v.tree)
val repTree = Literal(Constant(rep))
val repExpr = c.Expr[String](repTree)
reify{
println(repExpr.splice + " = " + v.splice)
}
}
}
else reify{}
}
}
这输出(编译+运行):
[sbt compile bla bla]
"Hello World"
scala.reflect.internal.Trees$Literal
x
scala.reflect.internal.Trees$Ident
1
scala.reflect.internal.Trees$Literal
[info] Running Main
"Hello World" = Hello World
x = 0
1 = 1
所以 ... 显然,"Hello World" 是文字 但 与文字模式不匹配(也尝试过 case Literal(_)
结果同样不令人满意) .
为什么?我需要匹配什么?
您的 implDebug
方法接受 c.Expr[Any]
,它是 c.Tree
的包装器。 Literal(Constant(...))
是文字树值的正确匹配器,但由于您希望在树上进行匹配,因此应改用 v.tree match {...}
。
考虑以下片段
object Main {
def main(args:Array[String]): Unit ={
import Debugger.debug
debug("Hello World")
val x = 0
debug(x)
debug(1)
}
}
我要打印这个
Hello World
x = 0
1
通过使用宏:
import scala.language.experimental.macros
import scala.reflect.macros._
object Debugger {
val doDebug = true
def debug(v : Any) :Unit = macro implDebug
def implDebug(c:blackbox.Context)(v:c.Expr[Any]): c.Expr[Unit] ={
import c.universe._
if(doDebug) {
v match {
case Literal(Constant(_)) => reify{println(v.splice)}
case _ =>
println(v.tree)
println(v.tree.getClass.getName)
val rep = show(v.tree)
val repTree = Literal(Constant(rep))
val repExpr = c.Expr[String](repTree)
reify{
println(repExpr.splice + " = " + v.splice)
}
}
}
else reify{}
}
}
这输出(编译+运行):
[sbt compile bla bla]
"Hello World"
scala.reflect.internal.Trees$Literal
x
scala.reflect.internal.Trees$Ident
1
scala.reflect.internal.Trees$Literal
[info] Running Main
"Hello World" = Hello World
x = 0
1 = 1
所以 ... 显然,"Hello World" 是文字 但 与文字模式不匹配(也尝试过 case Literal(_)
结果同样不令人满意) .
为什么?我需要匹配什么?
您的 implDebug
方法接受 c.Expr[Any]
,它是 c.Tree
的包装器。 Literal(Constant(...))
是文字树值的正确匹配器,但由于您希望在树上进行匹配,因此应改用 v.tree match {...}
。