summaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala9
-rw-r--r--src/reflect/scala/reflect/runtime/ReflectionUtils.scala23
2 files changed, 14 insertions, 18 deletions
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index 2bf57d61cc..c6e7a5d7b7 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -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))
diff --git a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
index 2c7be6e317..3c22d478ce 100644
--- a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
+++ b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
@@ -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 }
}