"debugging" scala 注释宏

"debugging" scala annotation macros

我的某些 Scala 注释宏似乎没有得到扩展,有没有办法inspect/log在编译时将哪个表达式传递到我的注释宏,因为现在代码甚至无法编译...

def virtualize(tree: Tree): Tree = atPos(tree.pos) {
  tree match {
    case x =>
      println("LOG: "+tree) //will only be printed during runtime
      c.warning(tree.pos, "LOG: "+tree) //will only generate code for a warning 
      super.transform(tree)
  }
}

有没有办法在注释宏中发出编译器警告?

非常感谢!

如果你用idea那么打开终端输入sbt ~compile会时编译 然后你可以在终端中看到如下所示的编译信息日志:

D:\git\scala-macro-example>sbt ~compile
[info] Loading project definition from D:\git\scala-macro-example\project
[info] Set current project to scala-macro-example (in build file:/D:/git/scala-macro-example/)
[info] Updating {file:/D:/git/scala-macro-example/}root...
[info] Resolving jline#jline;2.12.1 ...
[info] Done updating.
[info] Compiling 2 Scala sources to D:\git\scala-macro-example\module\macros\target\scala-2.11\classes...
[error] D:\git\scala-macro-example\module\macros\src\main\scala\macross\teach\WithHello.scala:16: type ClassWithFunc is not a member of package macross.annotat
ion
[error] class WithHelloImpl(val c: Context) extends macross.annotation.ClassWithFunc{
[error]  

之后
object ShowInfo {
  class Show extends StaticAnnotation {
    def macroTransform(annottees: Any*): Any = macro ShowImpl.apply
  }

  class ShowImpl(val c: Context) {
    import c.universe._
    def showInfo(s: String) =
      c.info(c.enclosingPosition, s.split("\n").mkString("\n |---macro info---\n |", "\n |", ""), true)

    def apply(annottees: c.Expr[Any]*): c.Expr[Any] = {
      val a: Seq[c.universe.Tree] = annottees.map(_.tree)
      showInfo(show(a.head))
      c.Expr[Any](Block(a.toList, Literal(Constant(()))))
    }
  }
}

使用如下:

object ShowInfoUsing {
  trait SuperTrait
  class SuperClass

    @ShowInfo.Show
  class ShowInfoUsing(val i: Int = 1) extends SuperClass with SuperTrait {
    def f = 1

    val a = 1
  }


}

您可以在终端看到信息标识

[info]  |---macro info---
[info]  |class ShowInfoUsing extends SuperClass with SuperTrait {
[info]  |  <paramaccessor> val i: Int = _;
[info]  |  def <init>(i: Int = 1) = {
[info]  |    super.<init>();
[info]  |    ()
[info]  |  };
[info]  |  def f = 1;
[info]  |  val a = 1
[info]  |}
[info]     @ShowInfo.Show
[info]