Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[backport #1727] SI-7359 cyclic nested java class

The original commit message (from 54a84a3):

SI-6548 reflection correctly enters jinners

When completing Java classes, runtime reflection enumerates their
fields, methods, constructors and inner classes, loads them and
enters them into either the instance part (ClassSymbol) or the
static part (ModuleSymbol).

However unlike fields, methods and constructors, inner classes don't
need to be entered explicitly - they are entered implicitly when
being loaded.

This patch fixes the double-enter problem, make sure that enter-on-load
uses the correct owner, and also hardens jclassAsScala against double
enters that can occur in a different scenario.
  • Loading branch information...
commit 7f9feba0213fc210c7752ab210f900c016032699 1 parent 487584c
@adriaanm adriaanm authored
View
17 src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -687,7 +687,8 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
(if (jModifier.isStatic(mods)) module.moduleClass else clazz).info.decls enter sym
for (jinner <- jclazz.getDeclaredClasses) {
- enter(jclassAsScala(jinner, clazz), jinner.getModifiers)
+ jclassAsScala(jinner) // inner class is entered as a side-effect
+ // no need to call enter explicitly
}
pendingLoadActions = { () =>
@@ -1046,13 +1047,17 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
* @param jclazz The Java class
* @return A Scala class symbol that wraps all reflection info of `jclazz`
*/
- private def jclassAsScala(jclazz: jClass[_]): Symbol = jclassAsScala(jclazz, sOwner(jclazz))
+ private def jclassAsScala(jclazz: jClass[_]): Symbol = {
+ val clazz = sOwner(jclazz) // sOwner called outside of closure for binary compatibility
+ toScala(classCache, jclazz){ (mirror, jclazz) =>
+ mirror.jclassAsScala(jclazz, clazz)
+ }
+ }
private def jclassAsScala(jclazz: jClass[_], owner: Symbol): ClassSymbol = {
- val name = scalaSimpleName(jclazz)
- val completer = (clazz: Symbol, module: Symbol) => new FromJavaClassCompleter(clazz, module, jclazz)
- val (clazz, module) = createClassModule(owner, name, completer)
- classCache enter (jclazz, clazz)
+ val name = scalaSimpleName(jclazz)
+ val completer = (clazz: Symbol, module: Symbol) => new FromJavaClassCompleter(clazz, module, jclazz)
+ val (clazz, _) = createClassModule(owner, name, completer)
clazz
}
View
84 test/files/run/t6989.check
@@ -113,18 +113,6 @@ isProtected = false
isPublic = false
privateWithin = <none>
============
-sym = class $PrivateJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1
-isPrivate = true
-isProtected = false
-isPublic = false
-privateWithin = <none>
-============
-sym = value this$0, signature = foo.JavaClass_1, owner = class $PrivateJavaClass
-isPrivate = false
-isProtected = false
-isPublic = false
-privateWithin = package foo
-============
sym = class $ProtectedJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1
isPrivate = false
isProtected = true
@@ -143,18 +131,6 @@ isProtected = false
isPublic = false
privateWithin = package foo
============
-sym = class $ProtectedJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1
-isPrivate = false
-isProtected = true
-isPublic = false
-privateWithin = package foo
-============
-sym = value this$0, signature = foo.JavaClass_1, owner = class $ProtectedJavaClass
-isPrivate = false
-isProtected = false
-isPublic = false
-privateWithin = package foo
-============
sym = class $PublicJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1
isPrivate = false
isProtected = false
@@ -179,97 +155,55 @@ isProtected = false
isPublic = true
privateWithin = <none>
============
-sym = class $PublicJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1
-isPrivate = false
-isProtected = false
-isPublic = true
-privateWithin = <none>
-============
-sym = constructor $PublicJavaClass, signature = (x$1: foo.JavaClass_1)JavaClass_1.this.$PublicJavaClass, owner = class $PublicJavaClass
+sym = constructor JavaClass_1, signature = ()foo.JavaClass_1, owner = class JavaClass_1
isPrivate = false
isProtected = false
isPublic = true
privateWithin = <none>
============
-sym = value this$0, signature = foo.JavaClass_1, owner = class $PublicJavaClass
-isPrivate = false
-isProtected = false
-isPublic = false
-privateWithin = package foo
-============
-sym = constructor JavaClass_1, signature = ()foo.JavaClass_1, owner = class JavaClass_1
+sym = object JavaClass_1, signature = foo.JavaClass_1.type, owner = package foo
isPrivate = false
isProtected = false
isPublic = true
privateWithin = <none>
============
-sym = class PrivateStaticJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1
+sym = class PrivateStaticJavaClass, signature = ClassInfoType(...), owner = object JavaClass_1
isPrivate = true
isProtected = false
isPublic = false
privateWithin = <none>
============
-sym = object PrivateStaticJavaClass, signature = JavaClass_1.this.PrivateStaticJavaClass.type, owner = class JavaClass_1
+sym = object PrivateStaticJavaClass, signature = foo.JavaClass_1.PrivateStaticJavaClass.type, owner = object JavaClass_1
isPrivate = true
isProtected = false
isPublic = false
privateWithin = <none>
============
-sym = class ProtectedStaticJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1
+sym = class ProtectedStaticJavaClass, signature = ClassInfoType(...), owner = object JavaClass_1
isPrivate = true
isProtected = false
isPublic = false
privateWithin = <none>
============
-sym = object ProtectedStaticJavaClass, signature = JavaClass_1.this.ProtectedStaticJavaClass.type, owner = class JavaClass_1
+sym = object ProtectedStaticJavaClass, signature = foo.JavaClass_1.ProtectedStaticJavaClass.type, owner = object JavaClass_1
isPrivate = true
isProtected = false
isPublic = false
privateWithin = <none>
============
-sym = class PublicStaticJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1
-isPrivate = false
-isProtected = false
-isPublic = true
-privateWithin = <none>
-============
-sym = constructor PublicStaticJavaClass, signature = ()JavaClass_1.this.PublicStaticJavaClass, owner = class PublicStaticJavaClass
-isPrivate = false
-isProtected = false
-isPublic = true
-privateWithin = <none>
-============
-sym = object PublicStaticJavaClass, signature = JavaClass_1.this.PublicStaticJavaClass.type, owner = class JavaClass_1
+sym = class PublicStaticJavaClass, signature = ClassInfoType(...), owner = object JavaClass_1
isPrivate = false
isProtected = false
isPublic = true
privateWithin = <none>
============
-sym = object JavaClass_1, signature = foo.JavaClass_1.type, owner = package foo
-isPrivate = false
-isProtected = false
-isPublic = true
-privateWithin = <none>
-============
-sym = class PrivateStaticJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1
-isPrivate = true
-isProtected = false
-isPublic = false
-privateWithin = <none>
-============
-sym = class ProtectedStaticJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1
-isPrivate = true
-isProtected = false
-isPublic = false
-privateWithin = <none>
-============
-sym = class PublicStaticJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1
+sym = constructor PublicStaticJavaClass, signature = ()foo.JavaClass_1.PublicStaticJavaClass, owner = class PublicStaticJavaClass
isPrivate = false
isProtected = false
isPublic = true
privateWithin = <none>
============
-sym = constructor PublicStaticJavaClass, signature = ()JavaClass_1.this.PublicStaticJavaClass, owner = class PublicStaticJavaClass
+sym = object PublicStaticJavaClass, signature = foo.JavaClass_1.PublicStaticJavaClass.type, owner = object JavaClass_1
isPrivate = false
isProtected = false
isPublic = true
View
2  test/files/run/t6989/JavaClass_1.java
@@ -7,6 +7,8 @@
// I'm leaving the incorrect results of FromJavaClassCompleters in the check
// file, so that we get notified when something changes there.
+// ^^^ It's not clear what those incorrect results were, but the fix for SI-7359
+// (backport of fix for SI-6548) has probably resolved some of these. OP, please revisit this comment.
class PackagePrivateJavaClass {
private int privateField = 0;
View
1  test/files/run/t7359.check
@@ -0,0 +1 @@
+ok
View
3  test/files/run/t7359/Cyclic_1.java
@@ -0,0 +1,3 @@
+abstract class Cyclic {
+ static interface Inner<T extends Inner> { }
+}
View
6 test/files/run/t7359/Test_2.scala
@@ -0,0 +1,6 @@
+import scala.reflect.runtime.universe._
+
+object Test extends App {
+ typeOf[Cyclic].members
+ println("ok")
+}
Please sign in to comment.
Something went wrong with that request. Please try again.