You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2021/12/05 21:48:20 UTC

[groovy] branch master updated: GROOVY-9608: `super.@name` for hidden fields

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new 1ac400f  GROOVY-9608: `super.@name` for hidden fields
1ac400f is described below

commit 1ac400f856b53f4514fe820498103c72277a2c5d
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun Dec 5 15:25:50 2021 -0600

    GROOVY-9608: `super.@name` for hidden fields
---
 src/main/java/groovy/lang/MetaClassImpl.java       | 28 ++++++---------
 .../groovy/runtime/metaclass/MetaMethodIndex.java  |  3 +-
 src/test/groovy/bugs/Groovy9608.groovy             | 40 +++++++++++++---------
 3 files changed, 35 insertions(+), 36 deletions(-)

diff --git a/src/main/java/groovy/lang/MetaClassImpl.java b/src/main/java/groovy/lang/MetaClassImpl.java
index 45f506d..972b3bb 100644
--- a/src/main/java/groovy/lang/MetaClassImpl.java
+++ b/src/main/java/groovy/lang/MetaClassImpl.java
@@ -2455,7 +2455,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
      *
      * @param propertyDescriptors the property descriptors
      */
-    private void setupProperties(PropertyDescriptor[] propertyDescriptors) {
+    private void setupProperties(final PropertyDescriptor[] propertyDescriptors) {
         if (theCachedClass.isInterface) {
             LinkedList<CachedClass> superClasses = new LinkedList<>();
             superClasses.add(ReflectionCache.OBJECT_CLASS);
@@ -2504,7 +2504,6 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
             applyStrayPropertyMethods(superClasses, classPropertyIndex, true);
             applyStrayPropertyMethods(superClasses, classPropertyIndexForSuper, false);
 
-            copyClassPropertyIndexForSuper(classPropertyIndexForSuper);
             makeStaticPropertyIndex();
         }
     }
@@ -2567,13 +2566,6 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
         return staticProperty;
     }
 
-    private void copyClassPropertyIndexForSuper(Map<CachedClass, LinkedHashMap<String, MetaProperty>> dest) {
-        for (Map.Entry<CachedClass, LinkedHashMap<String, MetaProperty>> entry : classPropertyIndex.entrySet()) {
-            LinkedHashMap<String, MetaProperty> newVal = new LinkedHashMap<>();
-            dest.put(entry.getKey(), newVal);
-        }
-    }
-
     private void inheritStaticInterfaceFields(List<CachedClass> superClasses, Set<CachedClass> interfaces) {
         for (CachedClass iclass : interfaces) {
             LinkedHashMap<String, MetaProperty> iPropertyIndex = classPropertyIndex.computeIfAbsent(iclass, k -> new LinkedHashMap<>());
@@ -2586,15 +2578,17 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
         }
     }
 
-    private void inheritFields(LinkedList<CachedClass> superClasses) {
-        LinkedHashMap<String, MetaProperty> last = null;
-        for (CachedClass klass : superClasses) {
-            LinkedHashMap<String, MetaProperty> propertyIndex = classPropertyIndex.computeIfAbsent(klass, k -> new LinkedHashMap<>());
-            if (last != null) {
-                copyNonPrivateFields(last, propertyIndex, klass);
+    private void inheritFields(final Iterable<CachedClass> superClasses) {
+        Map<String, MetaProperty> sci = null;
+        for (CachedClass cc : superClasses) {
+            Map<String, MetaProperty> cci = classPropertyIndex.computeIfAbsent(cc, x -> new LinkedHashMap<>());
+            if (sci != null && !sci.isEmpty()) {
+                copyNonPrivateFields(sci, cci, cc);
+                // GROOVY-9608, GROOVY-9609: add public, protected, and package-private fields to index for super
+                copyNonPrivateFields(sci, classPropertyIndexForSuper.computeIfAbsent(cc, x -> new LinkedHashMap<>()), cc);
             }
-            last = propertyIndex;
-            addFields(klass, propertyIndex);
+            sci = cci;
+            addFields(cc, cci);
         }
     }
 
diff --git a/src/main/java/org/codehaus/groovy/runtime/metaclass/MetaMethodIndex.java b/src/main/java/org/codehaus/groovy/runtime/metaclass/MetaMethodIndex.java
index 85f8dd5..154253e 100644
--- a/src/main/java/org/codehaus/groovy/runtime/metaclass/MetaMethodIndex.java
+++ b/src/main/java/org/codehaus/groovy/runtime/metaclass/MetaMethodIndex.java
@@ -423,8 +423,7 @@ public class MetaMethodIndex {
     }
 
     private static boolean isNonRealMethod(final MetaMethod method) {
-        return method instanceof NewInstanceMetaMethod
-            || method instanceof NewStaticMetaMethod
+        return method instanceof NewMetaMethod
             || method instanceof ClosureMetaMethod
             || method instanceof GeneratedMetaMethod
             || method instanceof ClosureStaticMetaMethod
diff --git a/src/test/groovy/bugs/Groovy9608.groovy b/src/test/groovy/bugs/Groovy9608.groovy
index 1cf5209..1e1784e 100644
--- a/src/test/groovy/bugs/Groovy9608.groovy
+++ b/src/test/groovy/bugs/Groovy9608.groovy
@@ -24,17 +24,17 @@ import static groovy.test.GroovyAssert.assertScript
 
 final class Groovy9608 {
 
+    static class A {
+        public x = 'A'
+    }
+    static class B extends A {
+        public x = 'B'
+    }
+
     @Test
-    void testGetFieldOnSuper() {
+    void testGetFieldOnSelf() {
         assertScript '''
-            import org.codehaus.groovy.runtime.ScriptBytecodeAdapter
-
-            class A {
-              public x = 'A'
-            }
-            class B extends A {
-              public x = 'B'
-            }
+            import groovy.bugs.Groovy9608.*
 
             def a = new A()
             def ax = a.metaClass.getAttribute(A, a, 'x', false)
@@ -43,15 +43,21 @@ final class Groovy9608 {
             def b = new B()
             def bx = b.metaClass.getAttribute(B, b, 'x', false)
             assert bx == 'B'
+        '''
+    }
+
+    @Test
+    void testGetFieldOnSuper() {
+        assertScript '''
+            import groovy.bugs.Groovy9608.*
+            import org.codehaus.groovy.runtime.ScriptBytecodeAdapter
+
+            def b = new B()
+            def bSuperX = b.metaClass.getAttribute(B, b, 'x', true)
+            assert bSuperX == 'A'
 
-            try {
-                def bSuperX = b.metaClass.getAttribute(A, b, 'x', true)
-                assert bSuperX == 'A'
-                bSuperX = ScriptBytecodeAdapter.getFieldOnSuper(A, b, 'x')
-                assert bSuperX == 'A'
-            } catch (MissingFieldException e) {
-                // TODO: Why can't these read public/protected field from super?
-            }
+            bSuperX = ScriptBytecodeAdapter.getFieldOnSuper(B, b, 'x')
+            assert bSuperX == 'A'
         '''
     }
 }