This is an automated email from the ASF dual-hosted git repository. emilles pushed a commit to branch GROOVY-11746 in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 9882df14c3757e55026d6124200b83cfa21bfa6a Author: Eric Milles <eric.mil...@thomsonreuters.com> AuthorDate: Fri Aug 29 14:46:30 2025 -0500 GROOVY-11746: retain accessible synthetic override --- .../groovy/transform/stc/StaticTypeCheckingSupport.java | 10 +++++++--- .../groovy/transform/stc/StaticTypeCheckingVisitor.java | 3 ++- src/test/groovy/groovy/transform/stc/BugsSTCTest.groovy | 12 +++++++++++- 3 files changed, 20 insertions(+), 5 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 c030eb3cca..5b7128988c 100644 --- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java +++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java @@ -1192,7 +1192,7 @@ public abstract class StaticTypeCheckingSupport { if (toBeRemoved.contains(two)) continue; if (one.getParameters().length == two.getParameters().length) { ClassNode oneDC = one.getDeclaringClass(), twoDC = two.getDeclaringClass(); - if (oneDC == twoDC || isSynthetic(one,two)||isSynthetic(two,one)) { // GROOVY-11341 + if (oneDC == twoDC) { if (ParameterUtils.parametersEqual(one.getParameters(), two.getParameters())) { ClassNode oneRT = one.getReturnType(), twoRT = two.getReturnType(); if (isCovariant(oneRT, twoRT)) { @@ -1201,8 +1201,8 @@ public abstract class StaticTypeCheckingSupport { toBeRemoved.add(one); } } else { - // imperfect solution to determining if two methods are - // equivalent, for example String#compareTo(Object) and + // imperfect solution of determining if two methods are + // equivalent; for example String#compareTo(Object) and // String#compareTo(String) -- in that case, the Object // version is marked as synthetic if (isSynthetic(one, two)) { @@ -1213,6 +1213,10 @@ 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))) { diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index 61b4c7e6bd..2e63acbe50 100644 --- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -5060,10 +5060,11 @@ trying: for (ClassNode[] signature : signatures) { methods = findMethodsWithGenerated(receiver, name); if ("call".equals(name) && receiver.isInterface()) { MethodNode sam = findSAM(receiver); - if (sam != null) { + if (sam != null && !"call".equals(sam.getName())) { MethodNode callMethod = new MethodNode("call", sam.getModifiers(), sam.getReturnType(), sam.getParameters(), sam.getExceptions(), sam.getCode()); callMethod.setDeclaringClass(sam.getDeclaringClass()); callMethod.setSourcePosition(sam); + callMethod.setSynthetic(true); methods.add(callMethod); } } diff --git a/src/test/groovy/groovy/transform/stc/BugsSTCTest.groovy b/src/test/groovy/groovy/transform/stc/BugsSTCTest.groovy index db1f68c2a8..884431492a 100644 --- a/src/test/groovy/groovy/transform/stc/BugsSTCTest.groovy +++ b/src/test/groovy/groovy/transform/stc/BugsSTCTest.groovy @@ -1039,7 +1039,7 @@ class BugsSTCTest extends StaticTypeCheckingTestCase { 'Abstract method m() cannot be called directly' } - // GROOVY-8339, GROOVY-10109, GROOVY-10594 + // GROOVY-8339, GROOVY-10109, GROOVY-10594, GROOVY-11746 void testInvokePublicMethodFromInaccessibleBase() { assertScript ''' new StringBuilder().setLength(0) @@ -1055,6 +1055,16 @@ class BugsSTCTest extends StaticTypeCheckingTestCase { String sub = new StringBuilder("Hello World").substring(0,5) assert sub == 'Hello' ''' + + assertScript ''' + @Grab('org.apache.pdfbox:pdfbox:3.0.5') + import org.apache.pdfbox.pdmodel.PDPageContentStream + import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject + void test(PDPageContentStream stream, PDImageXObject image, float x, float y, float width, float height) { + stream.drawImage(image, x, y, width, height) // drawImage: synthetic in PDPageContentStream for access + } + assert true + ''' } void testInvokeSuperMethodFromCovariantOverride() {