cedric
cedric

Reputation: 358

"debugging" scala annotation macros

some of my scala annotation macro do not seem to get expanded, is there a way to inspect/log which expression gets passed to my annotation macro at compile time, because right now the code doesn't even compile...

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)
  }
}

Is there a way to issue compiler warnings in annotation macros?

Thanks a lot!

Upvotes: 2

Views: 1224

Answers (1)

余杰水
余杰水

Reputation: 1384

if you use idea then open terminal enter sbt ~compilewill Time compilation then you can see compilation info log like follow in the terminal :

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]  

after

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(()))))
    }
  }
}

useing like following:

object ShowInfoUsing {
  trait SuperTrait
  class SuperClass

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

    val a = 1
  }


}

you can see info logo in the terminal

[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]

Upvotes: 1

Related Questions