Permalink
Browse files

SI-5498 completes ModuleMirror.instance

As per referenced issue, this patch implements `instance`
for ModuleMirrors corresponding to nested and inner modules.
  • Loading branch information...
xeno-by committed Jul 11, 2012
1 parent d8b35a1 commit e8f1a423d1d02c488ccd8e9940c55c2d9859cf42
@@ -18,7 +18,7 @@ import collection.mutable.{ HashMap, ListBuffer }
import internal.Flags._
//import scala.tools.nsc.util.ScalaClassLoader
//import scala.tools.nsc.util.ScalaClassLoader._
import ReflectionUtils.{singletonInstance}
import ReflectionUtils.{staticSingletonInstance, innerSingletonInstance}
import language.existentials
import scala.runtime.{ScalaRunTime, BoxesRunTime}
import scala.reflect.internal.util.Collections._
@@ -403,8 +403,11 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
def erasure = symbol.moduleClass.asClass
def isStatic = true
def instance = {
if (!symbol.owner.isPackageClass) throw new Error("inner and nested modules are not supported yet")
singletonInstance(classLoader, symbol.fullName)
if (symbol.owner.isPackageClass)
staticSingletonInstance(classLoader, symbol.fullName)
else
if (outer == null) staticSingletonInstance(classToJava(symbol.moduleClass.asClass))
else innerSingletonInstance(outer, symbol.name)
}
def companion: Option[ClassMirror] = symbol.companionClass match {
case cls: ClassSymbol => Some(new JavaClassMirror(outer, cls))
@@ -63,25 +63,18 @@ object ReflectionUtils {
}
}
def singletonInstance(cl: ClassLoader, className: String): AnyRef = {
def staticSingletonInstance(cl: ClassLoader, className: String): AnyRef = {
val name = if (className endsWith "$") className else className + "$"
val clazz = java.lang.Class.forName(name, true, cl)
val singleton = clazz getField "MODULE$" get null
singleton
staticSingletonInstance(clazz)
}
// Retrieves the MODULE$ field for the given class name.
def singletonInstanceOpt(cl: ClassLoader, className: String): Option[AnyRef] =
try Some(singletonInstance(cl, className))
catch { case _: ClassNotFoundException => None }
def staticSingletonInstance(clazz: Class[_]): AnyRef = clazz getField "MODULE$" get null
def invokeFactory(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): AnyRef = {
val singleton = singletonInstance(cl, className)
val method = singleton.getClass.getMethod(methodName, classOf[ClassLoader])
method.invoke(singleton, args: _*)
def innerSingletonInstance(outer: AnyRef, className: String): AnyRef = {
val name = if (className endsWith "$") className.substring(0, className.length - 1) else className
val accessor = outer.getClass getDeclaredMethod name
accessor setAccessible true
accessor invoke outer
}
def invokeFactoryOpt(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): Option[AnyRef] =
try Some(invokeFactory(cl, className, methodName, args: _*))
catch { case _: ClassNotFoundException => None }
}
@@ -1,2 +1 @@
inner and nested modules are not supported yet
()
R
@@ -1,2 +1 @@
inner and nested modules are not supported yet
()
R

0 comments on commit e8f1a42

Please sign in to comment.