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 5b48d7d28c GROOVY-11549: default replaces abstract in interface
declared methods
5b48d7d28c is described below
commit 5b48d7d28c425a1b18877fd992316a6e3577f2d6
Author: Eric Milles <[email protected]>
AuthorDate: Sun Feb 16 15:13:38 2025 -0600
GROOVY-11549: default replaces abstract in interface declared methods
---
.../java/org/apache/groovy/ast/tools/ClassNodeUtils.java | 13 ++++++++++---
src/test/gls/invocation/CovariantReturnTest.groovy | 12 +++++++++++-
2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
b/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
index 9bb68de1b8..e1d848ee2b 100644
--- a/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
+++ b/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
@@ -58,7 +58,6 @@ import static
org.codehaus.groovy.ast.tools.GeneralUtils.isOrImplements;
import static org.codehaus.groovy.runtime.ArrayGroovyMethods.asBoolean;
import static org.codehaus.groovy.runtime.ArrayTypeUtils.dimension;
import static org.codehaus.groovy.runtime.ArrayTypeUtils.elementType;
-import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
/**
* Utility class for working with ClassNodes
@@ -197,8 +196,16 @@ public class ClassNodeUtils {
for (ClassNode iface : cNode.getInterfaces()) {
Map<String, MethodNode> declaredMethods =
iface.getDeclaredMethodsMap();
for (Map.Entry<String, MethodNode> entry :
declaredMethods.entrySet()) {
- if (entry.getValue().getDeclaringClass().isInterface() &&
(entry.getValue().getModifiers() & ACC_SYNTHETIC) == 0) {
- methodsMap.putIfAbsent(entry.getKey(), entry.getValue());
+ MethodNode mNode = entry.getValue();
+ if (mNode.getDeclaringClass().isInterface()) {
+ if (mNode.isAbstract()) {
+ methodsMap.putIfAbsent(entry.getKey(), mNode);
+ } else if (mNode.isPublic() && !mNode.isStatic()) {
+ mNode = methodsMap.put(entry.getKey(), mNode); //
GROOVY-11549: default replaces abstract
+ if (mNode != null && (!mNode.isAbstract() ||
!mNode.getDeclaringClass().isInterface())) {
+ methodsMap.put(entry.getKey(), mNode);
+ }
+ }
}
}
}
diff --git a/src/test/gls/invocation/CovariantReturnTest.groovy
b/src/test/gls/invocation/CovariantReturnTest.groovy
index e90a29fd12..b67f87d2e2 100644
--- a/src/test/gls/invocation/CovariantReturnTest.groovy
+++ b/src/test/gls/invocation/CovariantReturnTest.groovy
@@ -208,7 +208,7 @@ final class CovariantReturnTest {
// GROOVY-11549
@Test
void testDefaultMethodCovariantReturnForParameterizedType() {
- assertScript '''
+ String types = '''
interface A<T> {
T m()
}
@@ -218,9 +218,19 @@ final class CovariantReturnTest {
return 'B'
}
}
+ '''
+ assertScript types + '''
assert 2 == B.declaredMethods.count { it.name == 'm' }
'''
+
+ assertScript types + '''
+ class C implements A<String>, B {
+ }
+
+ def result = new C().m()
+ assert result == 'B'
+ '''
}
// GROOVY-7849