Search code examples
scalaannotationsscala-macros

Getting Parameters from Scala Macro Annotation


So I have an annotation on a function (DefDef). This annotation has parameters. However, I am confused on how to get the parameters from the constructor.

Usage example:

class TestMacro {
  @Foo(true)
  def foo(): String = ""
  foo
}

Here's the code for the annotation:

class Foo(b: Boolean) extends StaticAnnotation {
  def macroTransform(annottees: Any*) = macro Foo.impl
}

object Foo {
  def impl(c: whitebox.Context)(annottees: c.Tree*): c.Expr[Any] = {
    import c.universe._
    //how do I get value of `b` here???
    c.abort(c.enclosingPosition, "message")
  }
}

Solution

  • What about this:

    val b: Boolean = c.prefix.tree match {
        case q"new Foo($b)" => c.eval[Boolean](c.Expr(b))
    }
    

    For sake of completeness this is the full source:

    import scala.reflect.macros.Context
    import scala.language.experimental.macros
    import scala.annotation.StaticAnnotation
    import scala.annotation.compileTimeOnly
    import scala.reflect.api.Trees
    import scala.reflect.runtime.universe._
    
    class Foo(b: Boolean) extends StaticAnnotation {
      def macroTransform(annottees: Any*) :Any = macro FooMacro.impl
    }
    
    object FooMacro {
      def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
        import c.universe._
        val b: Boolean = c.prefix.tree match {
            case q"new Foo($b)" => c.eval[Boolean](c.Expr(b))
        }
        c.abort(c.enclosingPosition, "message")
      }
    }