I have a scala code: trait model and its implementation case class Category with custom annotation which i wish to read later
import scala.annotation.StaticAnnotation
class ExtraFields() extends StaticAnnotation
trait Model {}
case class MyCategory( id: Option[Int],
name: String,
level: Option[Int],
@ExtraFields
parent: Option[MyCategory] = None
) extends Model {
}
and i have trait DBModel and its implementation MyCategoryModel. And i pass MyCategory as type parameter to DBModel
trait DBModel[T <: Model] {
lazy val fields = getClassFields[T]
lazy val fields2 = getClassFields2[T]
}
object MyCategoryModel extends DBModel[MyCategory] {
def getFields = fields
def getFields2 = fields2
}
i want trait DBModel to read fields of case class passed as T parameter, so i call two functions
def getClassFields[T] = {
symbolOf[T].asClass.primaryConstructor
.typeSignature.paramLists.head.map {v =>
v.name.toString -> v.annotations
}
}
def getClassFields2[T: TypeTag]: Iterable[(String, List[universe.Annotation])] =
typeOf[T].members.collect {
case m: MethodSymbol if m.isCaseAccessor =>
m.name.toString -> m.annotations
}
but none of them is working
val res = MyCategoryModel.getFields // runtime exception: free type T is not a class
val res2 = MyCategoryModel.getFields2 // compile error: No TypeTag available for T
If i call them directly
getClassFields[MyCategory]
getClassFields2[MyCategory]
for a first function i get the same error, for the second i get result but universe.annotations can not see my ExtraFields annotation, returning empty lists for each of fields
Could you please explain this black magic and how to conqure it in my case Thank you
UPD playground https://scastie.scala-lang.org/DTTTyA0CSTSZ0Vj7KFW6Hw
Aucun commentaire:
Enregistrer un commentaire