samedi 3 septembre 2016

Using Scala reflection, how can I extract the trait mixin?

My sample domain:

trait Thing2[T, U] {
  val t: T
  val u: U
}
case class TwoThing[P](x: P, t: String, u: P) extends Thing2[String, P]
case class Wow2[A](a: String, b: Thing2[String, A])

val wow = Wow2("blah", TwoThing(1,"hey",2))  // <-- Reflect on this

I'm reflecting on a Wow2[Int] object, and as I go, I pass the knowledge that b is a Thing2[String,Int].

I eventually arrive at reflecting the TwoThing[P] object and still know that it is supposed to be a Thing2[String,Int]. I need something to relate P -> Int so I can substitute the types.

def lookSee( tpe:Type, superParamTypes:List[Type] ) {
  // tpe is TwoThing[P] and superParamTypes is List(String,Int)
  println(tpe)
}

This shows me the output:

[P]scala.AnyRef
        with co.blocke.scalajack.test.Thing2[String,P]
        with scala.Product
        with scala.Serializable {
  val x: P
  private[this] val x: P
  val t: String
  private[this] val t: String
  val u: P
  private[this] val u: P
  def <init>(x: P,t: String,u: P): co.blocke.scalajack.test.TwoThing[P]
  def copy[P](x: P,t: String,u: P): co.blocke.scalajack.test.TwoThing[P]
  def copy$default$1[P]: P @scala.annotation.unchecked.uncheckedVariance
  def copy$default$2[P]: String @scala.annotation.unchecked.uncheckedVariance
  def copy$default$3[P]: P @scala.annotation.unchecked.uncheckedVariance
  override def productPrefix: java.lang.String
  def productArity: scala.Int
  def productElement(x$1: scala.Int): scala.Any
  override def productIterator: Iterator[scala.Any]
  def canEqual(x$1: scala.Any): scala.Boolean
  override def hashCode(): scala.Int
  override def toString(): java.lang.String
  override def equals(x$1: scala.Any): scala.Boolean
}

All the information I need is in this output. I see this is a TwoThing[P] and I can extract P. I see the trait mixin Thing2[String,P]. And thanks to superParamTypes I still know that the params for Thing2 will be [String,Int], so all I need to do is associate P -> Int.

Great... How can I extract the information on line: with co.blocke.scalajack.test.Thing2[String,P] from tpe? Specifically I want the information [String,P] so I can associate it with the desired params [String,Int] and "solve" for P to arrive at my param map for TwoThing (P->Int).





Aucun commentaire:

Enregistrer un commentaire