You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2026/09/17 07:16:42 UTC
(groovy) 02/02: GROOVY-12413: TYPE_USE annotations on primitive record components and tuple-constructor parameters are duplicated or misapplied
This is an automated email from the ASF dual-hosted git repository.
paulk-asert pushed a commit to branch GROOVY_6_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit b409e933c9529f96806663d0afe47986db3d8b05
Author: Paul King <pa...@asert.com.au>
AuthorDate: Wed Sep 16 21:57:09 2026 +1000
GROOVY-12413: TYPE_USE annotations on primitive record components and tuple-constructor parameters are duplicated or misapplied
---
.../transform/RecordTypeASTTransformation.java | 2 +-
.../TupleConstructorASTTransformation.java | 2 +-
.../org/codehaus/groovy/classgen/RecordTest.groovy | 32 ++++++++++++++++++++++
3 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/transform/RecordTypeASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/RecordTypeASTTransformation.java
index fbe97906ae..48c2bc078b 100644
--- a/src/main/java/org/codehaus/groovy/transform/RecordTypeASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/RecordTypeASTTransformation.java
@@ -310,7 +310,7 @@ public class RecordTypeASTTransformation extends AbstractASTTransformation imple
}
for (PropertyNode pNode : pList) {
ClassNode pType = pNode.getOriginType();
- ClassNode type = pType.getPlainNodeReference();
+ ClassNode type = pType.getPlainNodeReference(false);
type.setGenericsPlaceHolder(pType.isGenericsPlaceHolder());
type.setGenericsTypes(pType.getGenericsTypes());
RecordComponentNode rec = new RecordComponentNode(cNode, pNode.getName(), type, pNode.getAnnotations());
diff --git a/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java
index 4109f1f498..f59ee8e492 100644
--- a/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java
@@ -392,7 +392,7 @@ public class TupleConstructorASTTransformation extends AbstractASTTransformation
private static Parameter createParam(final FieldNode fNode, final String name, final DefaultsMode defaultsMode, final AbstractASTTransformation xform, final boolean makeImmutable) {
ClassNode fType = fNode.getType();
- ClassNode type = fType.getPlainNodeReference();
+ ClassNode type = fType.getPlainNodeReference(false);
type.setGenericsTypes(fType.getGenericsTypes());
type.setGenericsPlaceHolder(fType.isGenericsPlaceHolder());
diff --git a/src/test/groovy/org/codehaus/groovy/classgen/RecordTest.groovy b/src/test/groovy/org/codehaus/groovy/classgen/RecordTest.groovy
index 1c3025c66e..87667401d9 100644
--- a/src/test/groovy/org/codehaus/groovy/classgen/RecordTest.groovy
+++ b/src/test/groovy/org/codehaus/groovy/classgen/RecordTest.groovy
@@ -116,6 +116,38 @@ final class RecordTest {
'''
}
+ @Test
+ void testTypeUseAnnotationOnPrimitiveRecordComponent() {
+ assertScript shell, '''
+ import java.lang.annotation.*
+ import java.lang.reflect.AnnotatedElement
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target([ElementType.TYPE_USE])
+ @interface NonNeg {}
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target([ElementType.RECORD_COMPONENT, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE_USE])
+ @interface Both {}
+
+ record Point(@NonNeg int x, @Both long y) {}
+
+ def check = { AnnotatedElement ae, Class expected ->
+ def annos = ae.annotations
+ assert annos.size() == 1 && annos[0].annotationType() == expected
+ }
+ Point.recordComponents.each { rc ->
+ def expected = rc.name == 'x' ? NonNeg : Both
+ check(rc.annotatedType, expected)
+ check(rc.accessor.annotatedReturnType, expected)
+ check(Point.getDeclaredField(rc.name).annotatedType, expected)
+ }
+ def ctor = Point.getDeclaredConstructor(int, long)
+ check(ctor.annotatedParameterTypes[0], NonNeg)
+ check(ctor.annotatedParameterTypes[1], Both)
+ '''
+ }
+
@Test
void testNativeRecordOnJDK16_java() {
assumeTrue(isAtLeastJdk('16.0'))