2017-03-09 78 views
2
case class FieldName(field: String) extends scala.annotation.StaticAnnotation 
@FieldName("foo") trait Foo 
import scala.reflect.runtime.universe._ 

symbolOf[Foo].annotations.head 
// ann: Annotation = FieldName("type") 

如何作为FieldName对象访问注释?该文件提到tree.children.tail,但没有类型。访问案例分类注释

+0

呀。哎呀。固定。 – Reactormonk

回答

3

如果你真的想要的FieldName我能想到的最好的实例是使用ToolBox

scala> case class FieldName(field: String) extends scala.annotation.StaticAnnotation 
defined class FieldName 

scala> @FieldName("foo") trait Foo 
defined trait Foo 

scala> import scala.reflect.runtime.universe._ 
import scala.reflect.runtime.universe._ 

scala> val annotation = symbolOf[Foo].annotations.head 
annotation: reflect.runtime.universe.Annotation = FieldName("foo") 

scala> import scala.tools.reflect.ToolBox 
import scala.tools.reflect.ToolBox 

scala> val tb = runtimeMirror(getClass.getClassLoader).mkToolBox() 
tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = [email protected] 

scala> tb.eval(tb.untypecheck(annotation.tree)).asInstanceOf[FieldName] 
res10: FieldName = FieldName(foo) 

随着.tree.children.tail,您可以访问传递给FieldName的参数,而无需创建实际的实例。

scala> annotation.tree.children.tail.map{ case Literal(Constant(field)) => field } 
res11: List[Any] = List(foo) 

如果你只是希望所有FieldName注解,并提取它们的价值,你可以这样做:

scala> val fields = symbolOf[Foo].annotations.withFilter( 
    | a => a.tree.tpe <:< typeOf[FieldName] 
    |).flatMap( 
    | a => a.tree.children.tail.map{ case Literal(Constant(field)) => field } 
    |) 
fields: List[Any] = List(foo) 
+0

可能有点XY - 按类型访问将确保我不会错误地捕获任何其他注释。但它实际上足以检查它是否是正确的注释并提取值。 – Reactormonk

+0

@Reactormonk噢,我明白你的意思了。 –

+0

如果我有多个注释,我怎么知道哪些字段属于哪个注释? – bashan