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 dd37d71e97 GROOVY-11341, GROOVY-11746: multi-level covariant and
synthetic
dd37d71e97 is described below
commit dd37d71e9739a6ad3219c76643ea1f7d8bb33a49
Author: Eric Milles <[email protected]>
AuthorDate: Fri Sep 5 09:42:23 2025 -0500
GROOVY-11341, GROOVY-11746: multi-level covariant and synthetic
---
.../transform/stc/StaticTypeCheckingSupport.java | 12 +++++++----
.../groovy/transform/stc/MethodCallsSTCTest.groovy | 23 ++++++++++++++++++++++
2 files changed, 31 insertions(+), 4 deletions(-)
diff --git
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index 5b7128988c..ea9de4082b 100644
---
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -1213,13 +1213,17 @@ public abstract class StaticTypeCheckingSupport {
}
} else if (!oneDC.equals(twoDC)) {
if
(ParameterUtils.parametersEqual(one.getParameters(), two.getParameters())) {
- // GROOVY-11341, GROOVY-11746: multi-level
covariant and synthetic override
- if
(!one.getReturnType().equals(two.getReturnType())) {
-
toBeRemoved.add(isCovariant(two.getReturnType(), one.getReturnType()) ? one :
two);
- } else
// GROOVY-6882, GROOVY-6970: drop overridden or
interface equivalent method
if (!twoDC.isInterface() ?
oneDC.isDerivedFrom(twoDC) : oneDC.implementsInterface(twoDC) || //
GROOVY-10897: concrete vs. abstract
(!disjoint && !one.isAbstract() && !(two instanceof ExtensionMethodNode)))
{
+ // GROOVY-10109, GROOVY-11341, GROOVY-11746:
multi-level covariant and synthetic overrides
+ if (isSynthetic(one, two) && !two.isAbstract()
&& !(two instanceof ExtensionMethodNode)) {
+ ClassNode oneRT = one.getReturnType(),
twoRT = two.getReturnType();
+ if (!oneRT.equals(twoRT) &&
isCovariant(twoRT, oneRT)) {
+ toBeRemoved.add(one); // edge case:
two is covariant
+ continue;
+ }
+ }
toBeRemoved.add(two);
} else if (oneDC.isInterface() ? (disjoint ?
twoDC.implementsInterface(oneDC) : twoDC.isInterface()) :
twoDC.isDerivedFrom(oneDC)) {
toBeRemoved.add(one);
diff --git a/src/test/groovy/groovy/transform/stc/MethodCallsSTCTest.groovy
b/src/test/groovy/groovy/transform/stc/MethodCallsSTCTest.groovy
index b9f068fad7..2b430400eb 100644
--- a/src/test/groovy/groovy/transform/stc/MethodCallsSTCTest.groovy
+++ b/src/test/groovy/groovy/transform/stc/MethodCallsSTCTest.groovy
@@ -1992,6 +1992,29 @@ class MethodCallsSTCTest extends
StaticTypeCheckingTestCase {
}
}
+ // GROOVY-11341, GROOVY-11746
+ void testInterfaceExtensionMethodIsCovariant() {
+ assertScript '''
+ class Thing extends Tuple {
+ Thing() {
+ super(new Object[0])
+ }
+ def getAt(String name) {
+ name
+ }
+ void test() {
+ @ASTTest(phase=INSTRUCTION_SELECTION, value={
+ def md =
node.rightExpression.getNodeMetaData(DIRECT_METHOD_CALL_TARGET)
+ assert md.declaringClass.nameWithoutPackage == 'Thing'
// not Collection
+ })
+ def foo = getAt('foo')
+ }
+ }
+ def thing = new Thing()
+ thing[''] == ''
+ '''
+ }
+
// GROOVY-7987
void testNonStaticMethodViaStaticReceiver() {
shouldFailWithMessages '''