问题
I have a macro which enumerates the direct sub types of a sealed trait:
import scala.reflect.macros.Context
import language.experimental.macros
object Checker {
def apply[A]: Unit = macro applyImpl[A]
def applyImpl[A: c.WeakTypeTag](c: Context): c.Expr[Unit] = {
val tpe = c.weakTypeOf[A].typeSymbol.asClass
require (tpe.isSealed)
tpe.typeSignature // SI-7046
require (tpe.knownDirectSubclasses.nonEmpty)
import c.universe._
c.Expr[Unit](reify {} .tree)
}
}
Then this works:
sealed trait A
case class A1(i: Int) extends A
object NotNested {
val nada = Checker[A]
}
But this fails:
object Nested {
sealed trait A
case class A1(i: Int) extends A
val nada = Checker[A]
}
[error] java.lang.IllegalArgumentException: requirement failed:
Did not find sub classes
I thought I ran into SI-7046, so I added the call to tpe.typeSignature
, but that doesn't help apparently.
I need a work around for this using Scala 2.10.2. Somehow I must enforce some extra type trees to be initialised, I guess?
回答1:
A possible workaround is following (what do you think @EugeneBurmako).
val cls: ClassSymbol = sub.asClass
println(s"knownDirectSubclasses = ${cls.knownDirectSubclasses}")
// print "knownDirectSubclasses = Set()"
val subsub = cls.owner.typeSignature.decls.filter {
case c: ClassSymbol =>
cls != c && c.selfType.baseClasses.contains(cls)
case _ => false
}
println(s"subsub = $subsub")
// print the actual sub classes
来源:https://stackoverflow.com/questions/17165932/macros-knowndirectsubclasses-broken-with-nested-type