2
votes

I am trying to use the new reflection API in Scala 2.10M7 to extract annotations on constructor arguments. The annotations are written in Java as I want them at run time and I got a warning recommending I use Java when I tried doing them in Scala.

I have successfully got a symbol for each constructor argument, and annotations... but I end up with things of type ClassFileAnnotArg (av in the code below). I am not sure what to do with these. Looking at the source code/scaladocs makes it appear that I want to split up on some case classes, but I could not work out how to do so.

I don't think this question is specific to annotations on constructor args, but I wanted to use the more detailed scala reflection for them and can't just use the Java annotation reflection mechanism.

import scala.reflect.runtime._
val ty = universe.typeOf[Test1]
val constructors = ty.member(universe.nme.CONSTRUCTOR)
for (constructor<-constructors.asTerm.alternatives.map{_.asMethod}) {
  println("Constructor = "+constructor)
  println("Overloaded = "+constructor.isOverloaded)
  for (pp<-constructor.params) {
    println("Constructor params")
    for (p<-pp) {
      println("  name="+p.name)
      println("  type="+p.typeSignature)
      for (a<-p.getAnnotations) {
        println("  annotation "+a.atp)
        for ((aname,av)<-a.assocs) {
          println("     "+aname.decoded+"="+av)
        }
      }
    }
  }
}

Is there any way to get an instance of the annotation object (as you do in Java annotations), or do you have to go through getAnnotations / check it is the one you want / iterate through the assocs / check it is the one you want / match the result to the expected type somehow / get the result?

1

1 Answers

1
votes

Currently you can't get an instance of the annotation object, though it's a nice idea. I'll try to squeeze it in before the RC1. upd. Oops, we're in lockdown at the moment. This will have to wait until 2.10.1: https://issues.scala-lang.org/browse/SI-6423

The conventional way is to pattern match on av against LiteralAnnotArg, ArrayAnnotArg and NestedAnnotArg (btw these names will be changed in RC1 to just LiteralArgument, ArrayArgument and `NestedArgument).