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 c14dc71183 GROOVY-11746: retain accessible synthetic override
c14dc71183 is described below
commit c14dc71183d517f6bcd3a58ab4f6145c4c9e245a
Author: Eric Milles <[email protected]>
AuthorDate: Fri Aug 29 14:46:30 2025 -0500
GROOVY-11746: retain accessible synthetic override
---
.../transform/stc/StaticTypeCheckingSupport.java | 10 ++++++---
.../transform/stc/StaticTypeCheckingVisitor.java | 3 ++-
.../groovy/groovy/transform/stc/BugsSTCTest.groovy | 12 +++++++++-
.../provider/collection/runtime/NamedRecord.groovy | 26 ++++++++++++++++------
.../provider/collection/runtime/NamedTuple.groovy | 20 +++++++++++------
5 files changed, 52 insertions(+), 19 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() {
diff --git
a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/NamedRecord.groovy
b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/NamedRecord.groovy
index d8730bf4c8..8dcd535dc2 100644
---
a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/NamedRecord.groovy
+++
b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/NamedRecord.groovy
@@ -18,6 +18,7 @@
*/
package org.apache.groovy.ginq.provider.collection.runtime
+import groovy.transform.AutoFinal
import groovy.transform.CompileStatic
import groovy.transform.stc.POJO
@@ -26,26 +27,37 @@ import groovy.transform.stc.POJO
*
* @since 4.0.0
*/
-@POJO
@CompileStatic
+@AutoFinal
+@POJO
class NamedRecord<E, T> extends NamedTuple<E> {
+
private static final long serialVersionUID = -2554041223576761912L
- private SourceRecord<T> sourceRecord
+
private final List<String> aliasList
+ private SourceRecord<T> sourceRecord
NamedRecord(List<E> elementList, List<String> nameList, List<String>
aliasList = Collections.emptyList()) {
super(elementList, nameList)
this.aliasList = aliasList
}
+ @Override
+ String toString() {
+ return super.toString()
+ }
+
+ @Override
+ def get(String name) {
+ return getAt(name)
+ }
+
@Override
def getAt(String name) {
if (exists(name)) {
- def value = super.getAt(name)
- return value
+ return super.get(name)
}
-
- return sourceRecord.get(name)
+ return sourceRecord?.get(name)
}
List<String> getAliasList() {
@@ -53,7 +65,7 @@ class NamedRecord<E, T> extends NamedTuple<E> {
}
NamedRecord<E, T> sourceRecord(T sr) {
- this.sourceRecord = new SourceRecord<>(sr, aliasList)
+ sourceRecord = new SourceRecord<>(sr, getAliasList())
return this
}
}
diff --git
a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/NamedTuple.groovy
b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/NamedTuple.groovy
index 7deb1d0411..5240c2728b 100644
---
a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/NamedTuple.groovy
+++
b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/NamedTuple.groovy
@@ -18,20 +18,26 @@
*/
package org.apache.groovy.ginq.provider.collection.runtime
+import groovy.transform.AutoFinal
import groovy.transform.CompileStatic
import groovy.transform.PackageScope
import groovy.transform.stc.POJO
+import static groovy.transform.PackageScopeTarget.*
+
/**
* Immutable named list to represent list result of GINQ
*
* @since 4.0.0
*/
+@PackageScope([CLASS, CONSTRUCTORS, METHODS])
@CompileStatic
-@PackageScope
+@AutoFinal
@POJO
class NamedTuple<E> extends Tuple<E> {
+
private static final long serialVersionUID = -5067092453136522209L
+
private final Map<String, E> data
NamedTuple(List<E> elementList, List<String> nameList) {
@@ -54,11 +60,11 @@ class NamedTuple<E> extends Tuple<E> {
}
}
- def get(String name) {
- return getAt(name)
+ public get(String name) {
+ return data.get(name)
}
- def getAt(String name) {
+ public getAt(String name) {
return data.get(name)
}
@@ -67,15 +73,15 @@ class NamedTuple<E> extends Tuple<E> {
}
List<String> getNameList() {
- return Collections.unmodifiableList(data.keySet().toList())
+ return new ArrayList<>(data.keySet())
}
@Override
- String toString() {
+ public String toString() {
StringJoiner sj = new StringJoiner(', ', '(', ')')
for (String name : getNameList()) {
sj.add(name + ':' + this[name])
}
- sj.toString()
+ return sj.toString()
}
}