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

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

commit 4e73de37ee900d7181e176d03fde07d4f09d0936
Author: Eric Milles <[email protected]>
AuthorDate: Wed Nov 19 14:37:58 2025 -0600

    GROOVY-11803: index stray property methods for interface with default
---
 src/main/java/groovy/lang/MetaClassImpl.java |  7 ++++++
 src/test/groovy/groovy/InterfaceTest.groovy  | 33 ++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/src/main/java/groovy/lang/MetaClassImpl.java 
b/src/main/java/groovy/lang/MetaClassImpl.java
index 317ca86f47..44c44b5373 100644
--- a/src/main/java/groovy/lang/MetaClassImpl.java
+++ b/src/main/java/groovy/lang/MetaClassImpl.java
@@ -97,6 +97,7 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
@@ -113,6 +114,7 @@ import java.util.function.BiConsumer;
 
 import static groovy.lang.Tuple.tuple;
 import static java.lang.Character.isUpperCase;
+import static org.apache.groovy.ast.tools.ClassNodeUtils.isValidAccessorName;
 import static org.apache.groovy.util.Arrays.concat;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.inSamePackage;
 import static org.codehaus.groovy.reflection.ReflectionUtils.checkAccessible;
@@ -360,6 +362,9 @@ public class MetaClassImpl implements MetaClass, 
MutableMetaClass {
                 if (c == theCachedClass || (m.isPublic() && !m.isStatic())) { 
// GROOVY-8164
                     addMetaMethodToIndex(m, mainClassMethodHeader);
                 }
+                if (c != theCachedClass && isValidAccessorName(m.getName())) { 
// GROOVY-11803
+                    metaMethodIndex.addMetaMethod(m, 
metaMethodIndex.indexMap.computeIfAbsent(c.getTheClass(), k -> new 
HashMap<>()));
+                }
             }
         }
 
@@ -2354,6 +2359,7 @@ public class MetaClassImpl implements MetaClass, 
MutableMetaClass {
             applyPropertyDescriptors(propertyDescriptors);
 
             applyStrayPropertyMethods(superClasses, classPropertyIndex, true);
+            applyStrayPropertyMethods(superInterfaces, classPropertyIndex, 
true);
             applyStrayPropertyMethods(superClasses, 
classPropertyIndexForSuper, false);
         }
         fillStaticPropertyIndex();
@@ -2504,6 +2510,7 @@ public class MetaClassImpl implements MetaClass, 
MutableMetaClass {
      */
     private void applyStrayPropertyMethods(CachedClass source, Map<String, 
MetaProperty> target, boolean isThis) {
         var header = metaMethodIndex.getHeader(source.getTheClass());
+        if (header == null) return;
         for (MetaMethodIndex.Cache e : header.values()) {
             String methodName = e.name;
             int methodNameLength = methodName.length();
diff --git a/src/test/groovy/groovy/InterfaceTest.groovy 
b/src/test/groovy/groovy/InterfaceTest.groovy
index 629c141552..62641ccc19 100644
--- a/src/test/groovy/groovy/InterfaceTest.groovy
+++ b/src/test/groovy/groovy/InterfaceTest.groovy
@@ -78,6 +78,39 @@ final class InterfaceTest extends CompilableTestSupport {
         assert err.contains('The interface Comparable cannot be implemented 
more than once with different arguments: java.lang.Comparable (via B) and 
java.lang.Comparable<java.lang.Object> (via A)')
     }
 
+    // GROOVY-11803
+    void testDefaultInterfaceMethod() {
+        assertScript '''
+            interface Foo {
+                default int barSize() {
+                    return bar.size()
+                }
+                String getBar()
+            }
+            class Baz implements Foo {
+                final String bar = 'BAR'
+            }
+
+            assert new Baz().barSize() == 3
+        '''
+        for (kind in ['default','private','static']) {
+            assertScript """
+                interface Foo {
+                    default int barSize() {
+                        return bar.size()
+                    }
+                    $kind String getBar() {
+                        return 'fizzbuzz'
+                    }
+                }
+                class Baz implements Foo {
+                }
+
+                assert new Baz().barSize() == 8
+            """
+        }
+    }
+
     // GROOVY-10060
     void testPrivateInterfaceMethod() {
         assertScript '''

Reply via email to