With scala 2.12.10
Suppose I want to implicitly convert at runtime a case class, in this case Special
to a case class SpecialString
. The implicit conversion is provided by a trait External
. The name for SpecialString
should be the declaration name of the class Special
.
import scala.reflect.runtime.universe.{runtimeMirror, typeOf}
import scala.reflect.runtime.universe
case class Special(i: Int)
case class SpecialString(s: String)
trait External {
val rm = runtimeMirror(getClass.getClassLoader)
val im = rm.reflect(this)
val members = im.symbol.typeSignature.members
def specials: Iterable[universe.Symbol] = members.filter(_.typeSignature <:< typeOf[Special] )
implicit def SpecialIntToString(s: Special): SpecialString = {
val name = im.reflectField(specials.filter(x => im.reflectField(x.asTerm).get.asInstanceOf[Special] == s).head.asTerm).symbol.toString.replace("value ", "")
SpecialString(s"name = $name")
}
}
Currently I'm able to implicitly convert convert members declared inside a class extending the External
trait.
class MyClass extends External {
val firstSpecial = Special(1)
val two = 2
val specialS: SpecialString = firstSpecial
}
class MySecondClass extends MyClass {
val specialS2: SpecialString = firstSpecial
}
val myClass = new MyClass
print(myClass.specialS) // SpecialString(name = firstSpecial)
But I'm not able to convert members that are declared in a super class
class MyClass {
val firstSpecial = Special(1)
val two = 2
val specialS: SpecialString = firstSpecial
}
class MySecondClass extends MyClass with External {
val specialS2: SpecialString = firstSpecial
}
val myClass = new MyClass
print(myClass.specialS)
val mySecondClass = new MySecondClass
print(mySecondClass.specialS2) // java.util.NoSuchElementException: next on empty iterator
Any help?
Aucun commentaire:
Enregistrer un commentaire