Skip to content

Commit

Permalink
GROOVY-11549: default replaces abstract in interface declared methods
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Feb 16, 2025
1 parent e484ac5 commit 5b48d7d
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 4 deletions.
13 changes: 10 additions & 3 deletions src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
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
Expand Down Expand Up @@ -197,8 +196,16 @@ public static void addDeclaredMethodsFromInterfaces(final ClassNode cNode, final
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);
}
}
}
}
}
Expand Down
12 changes: 11 additions & 1 deletion src/test/gls/invocation/CovariantReturnTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ final class CovariantReturnTest {
// GROOVY-11549
@Test
void testDefaultMethodCovariantReturnForParameterizedType() {
assertScript '''
String types = '''
interface A<T> {
T m()
}
Expand All @@ -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
Expand Down

0 comments on commit 5b48d7d

Please sign in to comment.