8210943: Hiding of inner classes not resolved properly
authorhannesw
Fri, 30 Nov 2018 15:39:27 +0100
changeset 52782 f468232c6147
parent 52781 436097b038a1
child 52783 5827f12ecbf0
8210943: Hiding of inner classes not resolved properly Reviewed-by: attila, jlaskey
src/jdk.dynalink/share/classes/jdk/dynalink/beans/AccessibleMembersLookup.java
test/nashorn/src/jdk/dynalink/beans/test/BeansLinkerTest.java
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/AccessibleMembersLookup.java	Fri Nov 30 11:40:48 2018 +0100
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/AccessibleMembersLookup.java	Fri Nov 30 15:39:27 2018 +0100
@@ -65,9 +65,8 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.LinkedHashSet;
+import java.util.LinkedHashMap;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * Utility class for discovering accessible methods and inner classes. Normally, a public member declared on a class is
@@ -78,7 +77,7 @@
  */
 class AccessibleMembersLookup {
     private final Map<MethodSignature, Method> methods;
-    private final Set<Class<?>> innerClasses;
+    private final Map<String, Class<?>> innerClasses;
     private final boolean instance;
 
     /**
@@ -89,7 +88,7 @@
      */
     AccessibleMembersLookup(final Class<?> clazz, final boolean instance) {
         this.methods = new HashMap<>();
-        this.innerClasses = new LinkedHashSet<>();
+        this.innerClasses = new LinkedHashMap<>();
         this.instance = instance;
         lookupAccessibleMembers(clazz);
     }
@@ -110,7 +109,7 @@
     }
 
     Class<?>[] getInnerClasses() {
-        return innerClasses.toArray(new Class<?>[0]);
+        return innerClasses.values().toArray(new Class<?>[0]);
     }
 
     /**
@@ -216,7 +215,8 @@
                 // NOTE: getting inner class objects through getClasses() does not resolve them, so if those classes
                 // were not yet loaded, they'll only get loaded in a non-resolved state; no static initializers for
                 // them will trigger just by doing this.
-                innerClasses.add(innerClass);
+                // Don't overwrite an inner class with an inherited inner class with the same name.
+                innerClasses.putIfAbsent(innerClass.getSimpleName(), innerClass);
             }
         } else {
             searchSuperTypes = true;
--- a/test/nashorn/src/jdk/dynalink/beans/test/BeansLinkerTest.java	Fri Nov 30 11:40:48 2018 +0100
+++ b/test/nashorn/src/jdk/dynalink/beans/test/BeansLinkerTest.java	Fri Nov 30 15:39:27 2018 +0100
@@ -47,6 +47,7 @@
 import jdk.dynalink.NamespaceOperation;
 import jdk.dynalink.NoSuchDynamicMethodException;
 import jdk.dynalink.Operation;
+import jdk.dynalink.beans.StaticClass;
 import jdk.dynalink.support.SimpleRelinkableCallSite;
 import org.testng.Assert;
 import org.testng.annotations.Test;
@@ -224,6 +225,25 @@
         });
     }
 
+    public static class A {
+        public static class Inner {}
+    }
+
+    public static class B extends A {
+        public static class Inner {}
+    }
+
+    @Test
+    public static void testInnerClassGetter() {
+        Object inner1 = call(GET.withNamespace(PROPERTY), StaticClass.forClass(A.class), "Inner");
+        Assert.assertTrue(inner1 instanceof StaticClass);
+        Assert.assertEquals(A.Inner.class, ((StaticClass) inner1).getRepresentedClass());
+
+        Object inner2 = call(GET.withNamespace(PROPERTY), StaticClass.forClass(B.class), "Inner");
+        Assert.assertTrue(inner2 instanceof StaticClass);
+        Assert.assertEquals(B.Inner.class, ((StaticClass) inner2).getRepresentedClass());
+    }
+
     private static void expectNoSuchDynamicMethodException(final Runnable r) {
         try {
             r.run();