1

I have simple Java annotation with one parameter:

public @interface Annot {
   String value();
}

Also I have Java annotation that takes array of Annot as parameter:

public @interface Annotations {
    Annot[] value();
}

I want to generate Annot with paramter "value" using Scala macro like this:

object MyAnnotations {

  def MyAnnotation: Annot = macro myAnnotationMacro

  def myAnnotationMacro(c: whitebox.Context): c.Expr[Annot] = {
    import c.universe._
    c.Expr(q"""new Annot("value")""")
  }
}

While this works:

@Annotations(Array(
  new Annot("value")
))
trait T

This doesn't work:

@Annotations(Array(
  MyAnnotations.MyAnnotation
)) // too many arguments for constructor Annot: ()Annot
trait T

Why? And how can I generate Annot?

1 Answer 1

1

I'm afraid that you can't do what you want with macros.

Typechecking of Java annotations is implemented in a very weird way that is significantly different from the rest of the typechecker. While everything else is typechecked from Tree to Tree, arguments to Java annotations are typechecked from Tree to ClassfileAnnotArg (with the latter not being trees). Your macro expands into a Tree, whereas the typechecker expects ClassfileAnnotArg, so things don't work (and the error message is quite misleading).

I think that it would be possible to change the typechecker to work in your case, but that will require patching the compiler. No idea how to do that from within a macro.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.