I have the following code for evaluating annotations:
def evalAnnotation[A : c.WeakTypeTag](symbol: c.Symbol): Option[A] = {
for (a <- symbol.annotations.find(_.tree.tpe.typeSymbol == weakTypeOf[A].typeSymbol))
yield c.eval(c.Expr[A](c.untypecheck(a.tree.duplicate)))
}
And in another package of the same module there are the following annotations:
package object annotations {
case class udt(name: String = "") extends StaticAnnotation
case class table(name: String = "") extends StaticAnnotation
}
At the client code module, I place these annotations on classes.
Now, a funny thing is that if I put both of these annotations at some class:
@udt @table case class Foo(....)
And then I try to evaluate them in the macro one after another like this:
val udtAnnotation = evalAnnotation[annotations.udt](fooType.typeSymbol)
println(udtAnnotation)
val tableAnnotation = evalAnnotation[annotations.table](fooType.typeSymbol)
println(tableAnnotation)
It miserably fails on the second annotation evaluation. When I had only one annotation in the project, it worked fine every single time.
The error I get is this:
Some(udt(null))
exception when typing com.xxxx.annotations.`package`.table.<init>$default$1()/class scala.reflect.internal.Trees$Apply
=> String @annotation.unchecked.uncheckedVariance does not take parameters in file <no file>
scala.reflect.internal.Types$TypeError: => String @annotation.unchecked.uncheckedVariance does not take parameters
at scala.tools.nsc.typechecker.Contexts$ThrowingReporter.handleError(Contexts.scala:1402)
at scala.tools.nsc.typechecker.Contexts$ContextReporter.issue(Contexts.scala:1254)
at scala.tools.nsc.typechecker.Contexts$Context.issue(Contexts.scala:573)
at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$duplErrorTree$1(Typers.scala:3213)
at scala.tools.nsc.typechecker.Typers$Typer.doTypedApply(Typers.scala:3550)
at scala.tools.nsc.typechecker.Typers$Typer.normalTypedApply$1(Typers.scala:4580)
at scala.tools.nsc.typechecker.Typers$Typer.typedApply$1(Typers.scala:4608)
at scala.tools.nsc.typechecker.Typers$Typer.typedInAnyMode$1(Typers.scala:5370)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5387)
at scala.tools.nsc.transform.Erasure$Eraser.typed1(Erasure.scala:712)
....
exception when typing new com.xxxx.annotations.package.table(com.xxxx.annotations.`package`.table.<init>$default$1())
exception when typing def wrapper(): Object = new com.xxxx.annotations.package.table(com.xxxx.annotations.`package`.table.<init>$default$1())
exception when typing object __wrapper$3$4bd49eefedc34622810a80749b07572f extends Object {
def <init>(): __wrapper$3$4bd49eefedc34622810a80749b07572f.__wrapper$3$4bd49eefedc34622810a80749b07572f.type = {
__wrapper$3$4bd49eefedc34622810a80749b07572f.super.<init>();
()
};
def wrapper(): Object = new com.xxxx.annotations.package.table(com.xxxx.annotations.`package`.table.<init>$default$1())
}
exception when typing package __wrapper$3$4bd49eefedc34622810a80749b07572f {
object __wrapper$3$4bd49eefedc34622810a80749b07572f extends Object {
def <init>(): __wrapper$3$4bd49eefedc34622810a80749b07572f.__wrapper$3$4bd49eefedc34622810a80749b07572f.type = {
__wrapper$3$4bd49eefedc34622810a80749b07572f.super.<init>();
()
};
def wrapper(): Object = new com.xxxx.annotations.package.table(com.xxxx.annotations.`package`.table.<init>$default$1())
}
}
Is it a bug? Why is one failing, when another identical one evaluates just fine?
If I specify the value of name in these annotations, they evaluate ok. Therefore, there must be something wrong with default value handling.
And finally - how to make that reliable?
This is Scala version 2.11.12.