This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_5_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_5_0_X by this push:
new 38622cd5b2 GROOVY-11803: index stray property methods for interface
with default
38622cd5b2 is described below
commit 38622cd5b2be1637692f04ce8f940f46a88cd76a
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 e1a13d9084..36a43be020 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;
@@ -359,6 +361,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<>()));
+ }
}
}
@@ -2362,6 +2367,7 @@ public class MetaClassImpl implements MetaClass,
MutableMetaClass {
applyPropertyDescriptors(propertyDescriptors);
applyStrayPropertyMethods(superClasses, classPropertyIndex, true);
+ applyStrayPropertyMethods(superInterfaces, classPropertyIndex,
true);
applyStrayPropertyMethods(superClasses,
classPropertyIndexForSuper, false);
}
fillStaticPropertyIndex();
@@ -2512,6 +2518,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 '''