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 {...}