2017-03-09 81 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