summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala34
-rw-r--r--src/reflect/scala/reflect/runtime/ReflectionUtils.scala32
-rw-r--r--test/files/run/reflection-enclosed-basic.check18
-rw-r--r--test/files/run/reflection-enclosed-basic.scala46
-rw-r--r--test/files/run/reflection-enclosed-inner-basic.check20
-rw-r--r--test/files/run/reflection-enclosed-inner-basic.scala52
-rw-r--r--test/files/run/reflection-enclosed-inner-inner-basic.check20
-rw-r--r--test/files/run/reflection-enclosed-inner-inner-basic.scala58
-rw-r--r--test/files/run/reflection-enclosed-inner-nested-basic.check20
-rw-r--r--test/files/run/reflection-enclosed-inner-nested-basic.scala55
-rw-r--r--test/files/run/reflection-enclosed-nested-basic.check20
-rw-r--r--test/files/run/reflection-enclosed-nested-basic.scala52
-rw-r--r--test/files/run/reflection-enclosed-nested-inner-basic.check20
-rw-r--r--test/files/run/reflection-enclosed-nested-inner-basic.scala54
-rw-r--r--test/files/run/reflection-enclosed-nested-nested-basic.check20
-rw-r--r--test/files/run/reflection-enclosed-nested-nested-basic.scala54
-rw-r--r--test/files/run/reflection-modulemirror-inner-good.check3
-rw-r--r--test/files/run/reflection-modulemirror-nested-good.check3
-rw-r--r--test/files/run/reflection-repl-classes.check35
-rw-r--r--test/files/run/reflection-repl-classes.scala22
-rw-r--r--test/files/run/reflection-repl-elementary.check (renamed from test/files/run/reflection-repl.check)0
-rw-r--r--test/files/run/reflection-repl-elementary.scala (renamed from test/files/run/reflection-repl.scala)0
-rw-r--r--test/files/run/reflection-sanitychecks.check4
23 files changed, 611 insertions, 31 deletions
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index 2bf57d61cc..4ce2cda04a 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))
@@ -1089,12 +1092,25 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
noClass
else if (clazz.owner.isPackageClass)
javaClass(clazz.javaClassName)
- else if (clazz.owner.isClass)
- classToJava(clazz.owner.asClass)
- .getDeclaredClasses
- .find(_.getSimpleName == clazz.name.toString)
- .getOrElse(noClass)
- else
+ else if (clazz.owner.isClass) {
+ val childOfClass = !clazz.owner.isModuleClass
+ val childOfTopLevel = clazz.owner.owner.isPackageClass
+ val childOfTopLevelObject = clazz.owner.isModuleClass && childOfTopLevel
+
+ // suggested in https://issues.scala-lang.org/browse/SI-4023?focusedCommentId=54759#comment-54759
+ var ownerClazz = classToJava(clazz.owner.asClass)
+ if (childOfTopLevelObject) ownerClazz = Class.forName(ownerClazz.getName stripSuffix "$", true, ownerClazz.getClassLoader)
+ val ownerChildren = ownerClazz.getDeclaredClasses
+
+ var fullNameOfJavaClass = ownerClazz.getName
+ if (childOfClass || childOfTopLevel) fullNameOfJavaClass += "$"
+ fullNameOfJavaClass += clazz.name
+ if (clazz.isModuleClass) fullNameOfJavaClass += "$"
+
+ // println(s"ownerChildren = ${ownerChildren.toList}")
+ // println(s"fullNameOfJavaClass = $fullNameOfJavaClass")
+ ownerChildren.find(_.getName == fullNameOfJavaClass).getOrElse(noClass)
+ } else
noClass
}
diff --git a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
index 2c7be6e317..e87c6b339b 100644
--- a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
+++ b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
@@ -6,7 +6,7 @@
package scala.reflect.runtime
import java.lang.{Class => jClass}
-import java.lang.reflect.{ InvocationTargetException, UndeclaredThrowableException }
+import java.lang.reflect.{ Method, InvocationTargetException, UndeclaredThrowableException }
/** A few java-reflection oriented utility functions useful during reflection bootstrapping.
*/
@@ -63,25 +63,25 @@ 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 accessorName = if (className endsWith "$") className.substring(0, className.length - 1) else className
+ def singletonAccessor(clazz: Class[_]): Option[Method] =
+ if (clazz == null) None
+ else {
+ val declaredAccessor = clazz.getDeclaredMethods.filter(_.getName == accessorName).headOption
+ declaredAccessor orElse singletonAccessor(clazz.getSuperclass)
+ }
- def invokeFactoryOpt(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): Option[AnyRef] =
- try Some(invokeFactory(cl, className, methodName, args: _*))
- catch { case _: ClassNotFoundException => None }
+ val accessor = singletonAccessor(outer.getClass) getOrElse { throw new NoSuchMethodException(s"${outer.getClass.getName}.$accessorName") }
+ accessor setAccessible true
+ accessor invoke outer
+ }
}
diff --git a/test/files/run/reflection-enclosed-basic.check b/test/files/run/reflection-enclosed-basic.check
new file mode 100644
index 0000000000..41f6a72f1c
--- /dev/null
+++ b/test/files/run/reflection-enclosed-basic.check
@@ -0,0 +1,18 @@
+class B1
+B1
+1
+class B2
+B2
+2
+object B3
+B3
+3
+object B4
+B4
+4
+object B5
+B5
+5
+object B6
+B6
+6
diff --git a/test/files/run/reflection-enclosed-basic.scala b/test/files/run/reflection-enclosed-basic.scala
new file mode 100644
index 0000000000..1dcb6c2a27
--- /dev/null
+++ b/test/files/run/reflection-enclosed-basic.scala
@@ -0,0 +1,46 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.reflect.{classTag, ClassTag}
+
+class B1 { override def toString = "B1"; def foo = 1 }
+private class B2 { override def toString = "B2"; def foo = 2 }
+object B3 { override def toString = "B3"; def foo = 3 }
+private object B4 { override def toString = "B4"; def foo = 4 }
+object B5 extends B1 { override def toString = "B5"; override def foo = 5 }
+private object B6 extends B2 { override def toString = "B6"; override def foo = 6 }
+
+object Test extends App {
+ def testMethodInvocation(instance: Any) = {
+ val instanceMirror = cm.reflect(instance)
+ val method = instanceMirror.symbol.typeSignature.declaration(newTermName("foo")).asMethod
+ val methodMirror = instanceMirror.reflectMethod(method)
+ println(methodMirror())
+ }
+
+ def testNestedClass(name: String) = {
+ val sym = cm.staticClass(name)
+ println(sym)
+ val ctor = sym.typeSignature.declaration(newTermName("<init>")).asMethod
+ val ctorMirror = cm.reflectClass(sym).reflectConstructor(ctor)
+ val instance = ctorMirror()
+ println(instance)
+ testMethodInvocation(instance)
+ }
+
+ testNestedClass("B1")
+ testNestedClass("B2")
+
+ def testNestedModule(name: String) = {
+ val sym = cm.staticModule(name)
+ println(sym)
+ val moduleMirror = cm.reflectModule(sym)
+ val instance = moduleMirror.instance
+ println(instance)
+ testMethodInvocation(instance)
+ }
+
+ testNestedModule("B3")
+ testNestedModule("B4")
+ testNestedModule("B5")
+ testNestedModule("B6")
+}
diff --git a/test/files/run/reflection-enclosed-inner-basic.check b/test/files/run/reflection-enclosed-inner-basic.check
new file mode 100644
index 0000000000..984fb1ff12
--- /dev/null
+++ b/test/files/run/reflection-enclosed-inner-basic.check
@@ -0,0 +1,20 @@
+class B
+List(constructor B, class B1, class B2, object B3, object B4, object B5, object B6)
+class B1
+B1
+1
+class B2
+B2
+2
+object B3
+B3
+3
+object B4
+B4
+4
+object B5
+B5
+5
+object B6
+B6
+6
diff --git a/test/files/run/reflection-enclosed-inner-basic.scala b/test/files/run/reflection-enclosed-inner-basic.scala
new file mode 100644
index 0000000000..2b2c701993
--- /dev/null
+++ b/test/files/run/reflection-enclosed-inner-basic.scala
@@ -0,0 +1,52 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.reflect.{classTag, ClassTag}
+
+class B {
+ class B1 { override def toString = "B1"; def foo = 1 }
+ private class B2 { override def toString = "B2"; def foo = 2 }
+ object B3 { override def toString = "B3"; def foo = 3 }
+ private object B4 { override def toString = "B4"; def foo = 4 }
+ object B5 extends B1 { override def toString = "B5"; override def foo = 5 }
+ private object B6 extends B2 { override def toString = "B6"; override def foo = 6 }
+}
+
+object Test extends App {
+ val b = cm.classSymbol(classTag[B].runtimeClass)
+ println(b)
+ println(b.typeSignature.declarations.toList)
+
+ def testMethodInvocation(instance: Any) = {
+ val instanceMirror = cm.reflect(instance)
+ val method = instanceMirror.symbol.typeSignature.declaration(newTermName("foo")).asMethod
+ val methodMirror = instanceMirror.reflectMethod(method)
+ println(methodMirror())
+ }
+
+ def testInnerClass(name: String) = {
+ val sym = b.typeSignature.declaration(newTypeName(name)).asClass
+ println(sym)
+ val ctor = sym.typeSignature.declaration(newTermName("<init>")).asMethod
+ val ctorMirror = cm.reflect(new B).reflectClass(sym).reflectConstructor(ctor)
+ val instance = ctorMirror()
+ println(instance)
+ testMethodInvocation(instance)
+ }
+
+ testInnerClass("B1")
+ testInnerClass("B2")
+
+ def testInnerModule(name: String) = {
+ val sym = b.typeSignature.declaration(newTermName(name)).asModule
+ println(sym)
+ val moduleMirror = cm.reflect(new B).reflectModule(sym)
+ val instance = moduleMirror.instance
+ println(instance)
+ testMethodInvocation(instance)
+ }
+
+ testInnerModule("B3")
+ testInnerModule("B4")
+ testInnerModule("B5")
+ testInnerModule("B6")
+}
diff --git a/test/files/run/reflection-enclosed-inner-inner-basic.check b/test/files/run/reflection-enclosed-inner-inner-basic.check
new file mode 100644
index 0000000000..8987f31b18
--- /dev/null
+++ b/test/files/run/reflection-enclosed-inner-inner-basic.check
@@ -0,0 +1,20 @@
+class BB
+List(constructor BB, class B1, class B2, object B3, object B4, object B5, object B6)
+class B1
+B1
+1
+class B2
+B2
+2
+object B3
+B3
+3
+object B4
+B4
+4
+object B5
+B5
+5
+object B6
+B6
+6
diff --git a/test/files/run/reflection-enclosed-inner-inner-basic.scala b/test/files/run/reflection-enclosed-inner-inner-basic.scala
new file mode 100644
index 0000000000..1b9e19d37d
--- /dev/null
+++ b/test/files/run/reflection-enclosed-inner-inner-basic.scala
@@ -0,0 +1,58 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.reflect.{classTag, ClassTag}
+
+class B {
+ class BB {
+ class B1 { override def toString = "B1"; def foo = 1 }
+ private class B2 { override def toString = "B2"; def foo = 2 }
+ object B3 { override def toString = "B3"; def foo = 3 }
+ private object B4 { override def toString = "B4"; def foo = 4 }
+ object B5 extends B1 { override def toString = "B5"; override def foo = 5 }
+ private object B6 extends B2 { override def toString = "B6"; override def foo = 6 }
+ }
+}
+
+object Test extends App {
+ val b = cm.classSymbol(classTag[B#BB].runtimeClass)
+ println(b)
+ println(b.typeSignature.declarations.toList)
+
+ def testMethodInvocation(instance: Any) = {
+ val instanceMirror = cm.reflect(instance)
+ val method = instanceMirror.symbol.typeSignature.declaration(newTermName("foo")).asMethod
+ val methodMirror = instanceMirror.reflectMethod(method)
+ println(methodMirror())
+ }
+
+ def testInnerClass(name: String) = {
+ val sym = b.typeSignature.declaration(newTypeName(name)).asClass
+ println(sym)
+ val ctor = sym.typeSignature.declaration(newTermName("<init>")).asMethod
+ val outer1 = new B
+ val outer2 = new outer1.BB
+ val ctorMirror = cm.reflect(outer2).reflectClass(sym).reflectConstructor(ctor)
+ val instance = ctorMirror()
+ println(instance)
+ testMethodInvocation(instance)
+ }
+
+ testInnerClass("B1")
+ testInnerClass("B2")
+
+ def testInnerModule(name: String) = {
+ val sym = b.typeSignature.declaration(newTermName(name)).asModule
+ println(sym)
+ val outer1 = new B
+ val outer2 = new outer1.BB
+ val moduleMirror = cm.reflect(outer2).reflectModule(sym)
+ val instance = moduleMirror.instance
+ println(instance)
+ testMethodInvocation(instance)
+ }
+
+ testInnerModule("B3")
+ testInnerModule("B4")
+ testInnerModule("B5")
+ testInnerModule("B6")
+}
diff --git a/test/files/run/reflection-enclosed-inner-nested-basic.check b/test/files/run/reflection-enclosed-inner-nested-basic.check
new file mode 100644
index 0000000000..0f5176a6e7
--- /dev/null
+++ b/test/files/run/reflection-enclosed-inner-nested-basic.check
@@ -0,0 +1,20 @@
+object BB
+List(constructor BB, class B1, class B2, object B3, object B4, object B5, object B6)
+class B1
+B1
+1
+class B2
+B2
+2
+object B3
+B3
+3
+object B4
+B4
+4
+object B5
+B5
+5
+object B6
+B6
+6
diff --git a/test/files/run/reflection-enclosed-inner-nested-basic.scala b/test/files/run/reflection-enclosed-inner-nested-basic.scala
new file mode 100644
index 0000000000..2800ee2548
--- /dev/null
+++ b/test/files/run/reflection-enclosed-inner-nested-basic.scala
@@ -0,0 +1,55 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.reflect.{classTag, ClassTag}
+
+class B {
+ object BB {
+ class B1 { override def toString = "B1"; def foo = 1 }
+ private class B2 { override def toString = "B2"; def foo = 2 }
+ object B3 { override def toString = "B3"; def foo = 3 }
+ private object B4 { override def toString = "B4"; def foo = 4 }
+ object B5 extends B1 { override def toString = "B5"; override def foo = 5 }
+ private object B6 extends B2 { override def toString = "B6"; override def foo = 6 }
+ }
+}
+
+object Test extends App {
+ val outer1 = new B()
+ val b = cm.moduleSymbol(classTag[outer1.BB.type].runtimeClass)
+ println(b)
+ println(b.typeSignature.declarations.toList)
+
+ def testMethodInvocation(instance: Any) = {
+ val instanceMirror = cm.reflect(instance)
+ val method = instanceMirror.symbol.typeSignature.declaration(newTermName("foo")).asMethod
+ val methodMirror = instanceMirror.reflectMethod(method)
+ println(methodMirror())
+ }
+
+ def testNestedClass(name: String) = {
+ val sym = b.typeSignature.declaration(newTypeName(name)).asClass
+ println(sym)
+ val ctor = sym.typeSignature.declaration(newTermName("<init>")).asMethod
+ val ctorMirror = cm.reflect(outer1.BB).reflectClass(sym).reflectConstructor(ctor)
+ val instance = ctorMirror()
+ println(instance)
+ testMethodInvocation(instance)
+ }
+
+ testNestedClass("B1")
+ testNestedClass("B2")
+
+ def testNestedModule(name: String) = {
+ val sym = b.typeSignature.declaration(newTermName(name)).asModule
+ println(sym)
+ val moduleMirror = cm.reflect(outer1.BB).reflectModule(sym)
+ val instance = moduleMirror.instance
+ println(instance)
+ testMethodInvocation(instance)
+ }
+
+ testNestedModule("B3")
+ testNestedModule("B4")
+ testNestedModule("B5")
+ testNestedModule("B6")
+}
diff --git a/test/files/run/reflection-enclosed-nested-basic.check b/test/files/run/reflection-enclosed-nested-basic.check
new file mode 100644
index 0000000000..b0e61149f8
--- /dev/null
+++ b/test/files/run/reflection-enclosed-nested-basic.check
@@ -0,0 +1,20 @@
+object B
+List(constructor B, class B1, class B2, object B3, object B4, object B5, object B6)
+class B1
+B1
+1
+class B2
+B2
+2
+object B3
+B3
+3
+object B4
+B4
+4
+object B5
+B5
+5
+object B6
+B6
+6
diff --git a/test/files/run/reflection-enclosed-nested-basic.scala b/test/files/run/reflection-enclosed-nested-basic.scala
new file mode 100644
index 0000000000..8b740c2da2
--- /dev/null
+++ b/test/files/run/reflection-enclosed-nested-basic.scala
@@ -0,0 +1,52 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.reflect.{classTag, ClassTag}
+
+object B {
+ class B1 { override def toString = "B1"; def foo = 1 }
+ private class B2 { override def toString = "B2"; def foo = 2 }
+ object B3 { override def toString = "B3"; def foo = 3 }
+ private object B4 { override def toString = "B4"; def foo = 4 }
+ object B5 extends B1 { override def toString = "B5"; override def foo = 5 }
+ private object B6 extends B2 { override def toString = "B6"; override def foo = 6 }
+}
+
+object Test extends App {
+ val b = cm.moduleSymbol(classTag[B.type].runtimeClass)
+ println(b)
+ println(b.typeSignature.declarations.toList)
+
+ def testMethodInvocation(instance: Any) = {
+ val instanceMirror = cm.reflect(instance)
+ val method = instanceMirror.symbol.typeSignature.declaration(newTermName("foo")).asMethod
+ val methodMirror = instanceMirror.reflectMethod(method)
+ println(methodMirror())
+ }
+
+ def testNestedClass(name: String) = {
+ val sym = b.typeSignature.declaration(newTypeName(name)).asClass
+ println(sym)
+ val ctor = sym.typeSignature.declaration(newTermName("<init>")).asMethod
+ val ctorMirror = cm.reflectClass(sym).reflectConstructor(ctor)
+ val instance = ctorMirror()
+ println(instance)
+ testMethodInvocation(instance)
+ }
+
+ testNestedClass("B1")
+ testNestedClass("B2")
+
+ def testNestedModule(name: String) = {
+ val sym = b.typeSignature.declaration(newTermName(name)).asModule
+ println(sym)
+ val moduleMirror = cm.reflectModule(sym)
+ val instance = moduleMirror.instance
+ println(instance)
+ testMethodInvocation(instance)
+ }
+
+ testNestedModule("B3")
+ testNestedModule("B4")
+ testNestedModule("B5")
+ testNestedModule("B6")
+}
diff --git a/test/files/run/reflection-enclosed-nested-inner-basic.check b/test/files/run/reflection-enclosed-nested-inner-basic.check
new file mode 100644
index 0000000000..add7a81c0a
--- /dev/null
+++ b/test/files/run/reflection-enclosed-nested-inner-basic.check
@@ -0,0 +1,20 @@
+class BB
+List(constructor BB, class B1, class B2, object B3, object B4, object B5, object B6)
+class B1
+B1
+1
+class B2
+B2
+2
+object B3
+B3
+3
+object B4
+B4
+4
+object B5
+B5
+5
+object B6
+B6
+6
diff --git a/test/files/run/reflection-enclosed-nested-inner-basic.scala b/test/files/run/reflection-enclosed-nested-inner-basic.scala
new file mode 100644
index 0000000000..7466733d37
--- /dev/null
+++ b/test/files/run/reflection-enclosed-nested-inner-basic.scala
@@ -0,0 +1,54 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.reflect.{classTag, ClassTag}
+
+object B {
+ class BB {
+ class B1 { override def toString = "B1"; def foo = 1 }
+ private class B2 { override def toString = "B2"; def foo = 2 }
+ object B3 { override def toString = "B3"; def foo = 3 }
+ private object B4 { override def toString = "B4"; def foo = 4 }
+ object B5 extends B1 { override def toString = "B5"; override def foo = 5 }
+ private object B6 extends B2 { override def toString = "B6"; override def foo = 6 }
+ }
+}
+
+object Test extends App {
+ val b = cm.classSymbol(classTag[B.BB].runtimeClass)
+ println(b)
+ println(b.typeSignature.declarations.toList)
+
+ def testMethodInvocation(instance: Any) = {
+ val instanceMirror = cm.reflect(instance)
+ val method = instanceMirror.symbol.typeSignature.declaration(newTermName("foo")).asMethod
+ val methodMirror = instanceMirror.reflectMethod(method)
+ println(methodMirror())
+ }
+
+ def testInnerClass(name: String) = {
+ val sym = b.typeSignature.declaration(newTypeName(name)).asClass
+ println(sym)
+ val ctor = sym.typeSignature.declaration(newTermName("<init>")).asMethod
+ val ctorMirror = cm.reflect(new B.BB).reflectClass(sym).reflectConstructor(ctor)
+ val instance = ctorMirror()
+ println(instance)
+ testMethodInvocation(instance)
+ }
+
+ testInnerClass("B1")
+ testInnerClass("B2")
+
+ def testInnerModule(name: String) = {
+ val sym = b.typeSignature.declaration(newTermName(name)).asModule
+ println(sym)
+ val moduleMirror = cm.reflect(new B.BB).reflectModule(sym)
+ val instance = moduleMirror.instance
+ println(instance)
+ testMethodInvocation(instance)
+ }
+
+ testInnerModule("B3")
+ testInnerModule("B4")
+ testInnerModule("B5")
+ testInnerModule("B6")
+}
diff --git a/test/files/run/reflection-enclosed-nested-nested-basic.check b/test/files/run/reflection-enclosed-nested-nested-basic.check
new file mode 100644
index 0000000000..0f5176a6e7
--- /dev/null
+++ b/test/files/run/reflection-enclosed-nested-nested-basic.check
@@ -0,0 +1,20 @@
+object BB
+List(constructor BB, class B1, class B2, object B3, object B4, object B5, object B6)
+class B1
+B1
+1
+class B2
+B2
+2
+object B3
+B3
+3
+object B4
+B4
+4
+object B5
+B5
+5
+object B6
+B6
+6
diff --git a/test/files/run/reflection-enclosed-nested-nested-basic.scala b/test/files/run/reflection-enclosed-nested-nested-basic.scala
new file mode 100644
index 0000000000..8335ea482a
--- /dev/null
+++ b/test/files/run/reflection-enclosed-nested-nested-basic.scala
@@ -0,0 +1,54 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.reflect.{classTag, ClassTag}
+
+object B {
+ object BB {
+ class B1 { override def toString = "B1"; def foo = 1 }
+ private class B2 { override def toString = "B2"; def foo = 2 }
+ object B3 { override def toString = "B3"; def foo = 3 }
+ private object B4 { override def toString = "B4"; def foo = 4 }
+ object B5 extends B1 { override def toString = "B5"; override def foo = 5 }
+ private object B6 extends B2 { override def toString = "B6"; override def foo = 6 }
+ }
+}
+
+object Test extends App {
+ val b = cm.moduleSymbol(classTag[B.BB.type].runtimeClass)
+ println(b)
+ println(b.typeSignature.declarations.toList)
+
+ def testMethodInvocation(instance: Any) = {
+ val instanceMirror = cm.reflect(instance)
+ val method = instanceMirror.symbol.typeSignature.declaration(newTermName("foo")).asMethod
+ val methodMirror = instanceMirror.reflectMethod(method)
+ println(methodMirror())
+ }
+
+ def testNestedClass(name: String) = {
+ val sym = b.typeSignature.declaration(newTypeName(name)).asClass
+ println(sym)
+ val ctor = sym.typeSignature.declaration(newTermName("<init>")).asMethod
+ val ctorMirror = cm.reflectClass(sym).reflectConstructor(ctor)
+ val instance = ctorMirror()
+ println(instance)
+ testMethodInvocation(instance)
+ }
+
+ testNestedClass("B1")
+ testNestedClass("B2")
+
+ def testNestedModule(name: String) = {
+ val sym = b.typeSignature.declaration(newTermName(name)).asModule
+ println(sym)
+ val moduleMirror = cm.reflectModule(sym)
+ val instance = moduleMirror.instance
+ println(instance)
+ testMethodInvocation(instance)
+ }
+
+ testNestedModule("B3")
+ testNestedModule("B4")
+ testNestedModule("B5")
+ testNestedModule("B6")
+}
diff --git a/test/files/run/reflection-modulemirror-inner-good.check b/test/files/run/reflection-modulemirror-inner-good.check
index 0bf38a73d1..fe658e7087 100644
--- a/test/files/run/reflection-modulemirror-inner-good.check
+++ b/test/files/run/reflection-modulemirror-inner-good.check
@@ -1,2 +1 @@
-inner and nested modules are not supported yet
-()
+R
diff --git a/test/files/run/reflection-modulemirror-nested-good.check b/test/files/run/reflection-modulemirror-nested-good.check
index 0bf38a73d1..fe658e7087 100644
--- a/test/files/run/reflection-modulemirror-nested-good.check
+++ b/test/files/run/reflection-modulemirror-nested-good.check
@@ -1,2 +1 @@
-inner and nested modules are not supported yet
-()
+R
diff --git a/test/files/run/reflection-repl-classes.check b/test/files/run/reflection-repl-classes.check
new file mode 100644
index 0000000000..1c7f86c90c
--- /dev/null
+++ b/test/files/run/reflection-repl-classes.check
@@ -0,0 +1,35 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> class A
+defined class A
+
+scala>
+
+scala> class B {
+ def foo(x: A) = 1
+}
+defined class B
+
+scala>
+
+scala> object defs {
+ val cm = reflect.runtime.currentMirror
+ val u = cm.universe
+ val im = cm.reflect(new B)
+ val method = im.symbol.typeSignature.member(u.newTermName("foo")).asMethod
+ val mm = im.reflectMethod(method)
+}
+defined module defs
+
+scala> import defs._
+import defs._
+
+scala>
+
+scala> mm(new A)
+res0: Any = 1
+
+scala>
diff --git a/test/files/run/reflection-repl-classes.scala b/test/files/run/reflection-repl-classes.scala
new file mode 100644
index 0000000000..80e332cde3
--- /dev/null
+++ b/test/files/run/reflection-repl-classes.scala
@@ -0,0 +1,22 @@
+import scala.tools.partest.ReplTest
+
+object Test extends ReplTest {
+ def code = """
+ |class A
+ |
+ |class B {
+ | def foo(x: A) = 1
+ |}
+ |
+ |object defs {
+ | val cm = reflect.runtime.currentMirror
+ | val u = cm.universe
+ | val im = cm.reflect(new B)
+ | val method = im.symbol.typeSignature.member(u.newTermName("foo")).asMethod
+ | val mm = im.reflectMethod(method)
+ |}
+ |import defs._
+ |
+ |mm(new A)
+ |""".stripMargin
+}
diff --git a/test/files/run/reflection-repl.check b/test/files/run/reflection-repl-elementary.check
index 341dd10ab0..341dd10ab0 100644
--- a/test/files/run/reflection-repl.check
+++ b/test/files/run/reflection-repl-elementary.check
diff --git a/test/files/run/reflection-repl.scala b/test/files/run/reflection-repl-elementary.scala
index 72b65a1a70..72b65a1a70 100644
--- a/test/files/run/reflection-repl.scala
+++ b/test/files/run/reflection-repl-elementary.scala
diff --git a/test/files/run/reflection-sanitychecks.check b/test/files/run/reflection-sanitychecks.check
index a1df486b51..821457a999 100644
--- a/test/files/run/reflection-sanitychecks.check
+++ b/test/files/run/reflection-sanitychecks.check
@@ -6,7 +6,7 @@ method #2: 14
constructor #1: scala.ScalaReflectionException: expected a constructor of class D, you provided method bar
constructor #2: scala.ScalaReflectionException: expected a constructor of class D, you provided constructor C
class: CC
-object: java.lang.Error: inner and nested modules are not supported yet
+object: CO
=========members of D in a mirror of D=========
field #1: 21
@@ -16,7 +16,7 @@ method #2: 14
constructor #1: scala.ScalaReflectionException: expected a constructor of class D, you provided method bar
constructor #2: an instance of class D
class: CC
-object: java.lang.Error: inner and nested modules are not supported yet
+object: CO
=========members of E in a mirror of D=========
field #1: scala.ScalaReflectionException: expected a member of class D, you provided value E.foo