jeudi 7 juin 2018

scala reflection type bounds

I am trying to build a full set of paths from a case class using the Scala reflection api. One of the parameters passed to the constructor has a trait as an upper type bound (all of the instances of the trait are case classes). At runtime I have only been able to access this parameter as an instance of the trait rather than as the underlying case class. Here is an example:

trait UpperBound {
 def value: String
}

case class UpperBoundedImpl(value: String, other: String) extends UpperBound

case class Bounded[Upper <: UpperBound](id: String, upper: Upper) 

def getPaths[T](tt: TypeTag[T]): List[String]

val paths = getPaths(typeTag[Bounded[UpperBoundImpl]])....

In this case I would expect getPaths to return: ["id", "upper.value", "upper.other"]. I have managed to hack it to return ["id", "upper.value"] by getting the isStable symbols from upper but this isn't great because a) I'm missing fields and b) this solution won't generalise (I don't think it would cope if the nested upper contained nested objects itself). The problem seems to be that the Scala reflection API treats the upper as an upper even though it is a typeTag of Bounded[UpperBoundImpl]. Does anyone know how I might get the reflection api to view the upper as its runtime/more specific type rather than as its upper type bound?





Aucun commentaire:

Enregistrer un commentaire