2

我有一个宏,它枚举了一个密封特征的直接子类型:

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)
  }
}

然后这个工作:

sealed trait A
case class A1(i: Int) extends A

object NotNested {
  val nada = Checker[A]
}

但这失败了:

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

我以为我遇到了SI-7046,所以我将调用添加到tpe.typeSignature,但这显然没有帮助。

我需要使用 Scala 2.10.2 来解决这个问题。我想我必须以某种方式强制初始化一些额外的类型树?

4

1 回答 1

0

以下是一种可能的解决方法(您认为@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
于 2016-08-11T18:22:44.183 回答