I want to use these parent and child annotations to build reports from case classes:
@scala.annotation.meta.field
class RatingField[T](msg: T => String, isCorrectWhen: T => Boolean) extends StaticAnnotation
@scala.annotation.meta.field
class BooleanRatingField(msg: String => String) extends RatingField[Boolean](x => msg(if (x) "true" else "false")), x => x)
As you can see, fields annotated with these annotations are associated with:
msg
lambda (to build a string from each of them);isCorrectWhen
lambda (says if field is "correct" or "incorrect").
BooleanRatingField
was written to let developer not to write x => x
and if (x) "true" else "false")
for every boolean field.
For example, the case class itself is
case class MyCaseClass(@RatingField[String](f => s"strParam: $f", _.contains("abc"))
strParam: String,
@BooleanRatingField(f => s"---boolParam: $f---")
boolParam: Boolean,
@RatingField[Int](f => s"===intParam: $f===", _ > 100)
intParam: Int)
Now I get and print types of these annotations:
import scala.reflect.runtime.universe.{Annotation, typeOf}
typeOf[MyCaseClass]
.members
.collect { case symbol if symbol.isTerm => symbol.asTerm }
.collect { case term if term.isVal || term.isVar => term.annotations }
.flatMap { annotationsList => annotationsList.find { a: Annotation => a.tree.tpe <:< typeOf[RatingField[_]] } }
.map(_.tree.tpe)
.toSeq
.reverse
.foreach(println)
The result is:
MainObject.RatingField[String]
MainObject.BooleanRatingField
MainObject.RatingField[Int]
The problem is that BooleanRatingField
does not contain isCorrectWhen
lambda so I would like to see it as its parent RatingField[Boolean]
. Is there any way to do this cast?
Aucun commentaire:
Enregistrer un commentaire