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 '''
