发现是否在特定模块类型中声明了 class
Discover if a class has been declared inside a particular module type
我正在编写描述结构的 DSL。 DSL 使用类型来引用稍后将实例化的 classes。我想强制在特定模块中声明特定类型。这可以是 DSL 编译后的运行时检查。
本质上我需要从内部 class 开始访问外部元素并检查它的类型是否正确并获取对它的引用。
如果我得到子类型,我可以通过调用 typeSymbol 使用反射获取它的符号,在结果符号中我看到我可以调用 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
是一个"module class"。我不太确定这意味着什么,可能只是技术上每个单例对象背后还有一个实例化一次的 class。
因此以下似乎有效:
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])
}
我正在编写描述结构的 DSL。 DSL 使用类型来引用稍后将实例化的 classes。我想强制在特定模块中声明特定类型。这可以是 DSL 编译后的运行时检查。
本质上我需要从内部 class 开始访问外部元素并检查它的类型是否正确并获取对它的引用。
如果我得到子类型,我可以通过调用 typeSymbol 使用反射获取它的符号,在结果符号中我看到我可以调用 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
是一个"module class"。我不太确定这意味着什么,可能只是技术上每个单例对象背后还有一个实例化一次的 class。
因此以下似乎有效:
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])
}