发现是否在特定模块类型中声明了一个类



我正在写一个描述结构的DSL。DSL使用类型来引用稍后将实例化的类。我希望强制在特定模块中声明特定类型。这可以是DSL编译后的运行时检查。

实际上,我需要从内部类开始访问外部元素,检查它的类型是否正确,并获得对它的引用。

如果我得到子类型,我可以通过调用typessymbol来使用反射来得到它的符号,在得到的符号中,我看到我可以调用owner来得到外部类型符号。但是,如果我试图将父模块反映为模块(即使父模块是模块),它会抛出异常。

让我们举个例子:

trait TheMixin
object TheParent extends TheMixin {
  case class TheChild()
}
object TestDiscoverParent extends App {
  import scala.reflect.runtime.{currentMirror => cm, universe => ru}
  val theChildType = ru.typeOf[TheParent.TheChild]
  val theChildOwner = theChildType.typeSymbol.owner
  println(theChildOwner)
  val theParentModuleSymbol = theChildOwner.asModule
  val theParentRef = cm.reflectModule(theParentModuleSymbol).instance
  println(theParentRef.isInstanceOf[TheMixin])
}

在本例中,println(theChildOwner)行将打印

object TheParent

但是调用theChildOwner.asModule会抛出一个异常:

Exception in thread "main" scala.ScalaReflectionException: object TheParent is not a module

如何获得对外部对象包装器的引用?

似乎还有一个间接,owner是一个"模块类"。我不太确定这是什么意思,可能只是从技术上讲,每个单例对象背后都有一个实例化一次的类。

所以下面的代码似乎可以工作:

object TestDiscoverParent extends App {
  import scala.reflect.runtime.{currentMirror => cm, universe => ru}
  val theChildType = ru.typeOf[TheParent.TheChild]
  val theChildOwner = theChildType.typeSymbol.owner
  println(theChildOwner)
  require(theChildOwner.isModuleClass)
  val theParentModuleClass = theChildOwner.asClass
  val theParentModuleSymbol = theParentModuleClass.module.asModule
  val theParentRef = cm.reflectModule(theParentModuleSymbol).instance
  println(theParentRef.isInstanceOf[TheMixin])
}

相关内容

  • 没有找到相关文章

最新更新