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 2022/03/02 02:03:13 UTC
[groovy] branch GROOVY_3_0_X updated: Issue GROOVY-10505: mark trait variables helper methods with trait composition as generated (port to 3_0_X)
This is an automated email from the ASF dual-hosted git repository.
paulk pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
new 94375fe Issue GROOVY-10505: mark trait variables helper methods with trait composition as generated (port to 3_0_X)
94375fe is described below
commit 94375fef24b365b2a9d1990dc38ec4d9c55771b8
Author: Alar Aule <al...@smit.ee>
AuthorDate: Thu Feb 24 19:04:10 2022 +0200
Issue GROOVY-10505: mark trait variables helper methods with trait composition as generated (port to 3_0_X)
---
.../transform/trait/TraitASTTransformation.java | 11 +-
.../groovy/transform/trait/TraitComposer.java | 2 +-
.../transform/GeneratedAnnotationTest.groovy | 132 +++++++++++++++++++++
3 files changed, 139 insertions(+), 6 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
index 8b44557..2eb9b0e 100644
--- a/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
@@ -62,6 +62,7 @@ import java.util.List;
import java.util.Set;
import static org.apache.groovy.ast.tools.AnnotatedNodeUtils.markAsGenerated;
+import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedMethod;
import static org.apache.groovy.ast.tools.MethodNodeUtils.getCodeAsBlock;
import static org.apache.groovy.util.BeanUtils.capitalize;
import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
@@ -417,12 +418,12 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
if (getterBlock != null) {
MethodNode getter = new MethodNode(getterName, propNodeModifiers, node.getType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, getterBlock);
getter.setSynthetic(true);
- cNode.addMethod(getter);
+ addGeneratedMethod(cNode, getter);
if (node.getType().equals(ClassHelper.boolean_TYPE) || node.getType().equals(ClassHelper.Boolean_TYPE)) {
MethodNode secondGetter = new MethodNode("is" + capitalize(name), propNodeModifiers, node.getType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, getterBlock);
secondGetter.setSynthetic(true);
- cNode.addMethod(secondGetter);
+ addGeneratedMethod(cNode, secondGetter);
}
}
if (setterBlock != null) {
@@ -432,7 +433,7 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
MethodNode setter = new MethodNode(setterName, propNodeModifiers, ClassHelper.VOID_TYPE, params(setterParameter), ClassNode.EMPTY_ARRAY, setterBlock);
setter.setSynthetic(true);
- cNode.addMethod(setter);
+ addGeneratedMethod(cNode, setter);
}
}
@@ -502,7 +503,7 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
}
}
// define setter/getter helper methods (setter added even for final fields for legacy compatibility)
- target.addMethod(
+ addGeneratedMethod(target,
Traits.helperSetterName(field),
ACC_PUBLIC | ACC_ABSTRACT,
field.getOriginType(),
@@ -510,7 +511,7 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
ClassNode.EMPTY_ARRAY,
null
);
- target.addMethod(
+ addGeneratedMethod(target,
Traits.helperGetterName(field),
ACC_PUBLIC | ACC_ABSTRACT,
field.getOriginType(),
diff --git a/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java b/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
index a7f1c49..82b5d99 100644
--- a/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
+++ b/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
@@ -305,7 +305,7 @@ public abstract class TraitComposer {
AnnotationNode an = new AnnotationNode(COMPILESTATIC_CLASSNODE);
impl.addAnnotation(an);
cNode.addTransform(StaticCompileTransformation.class, an);
- cNode.addMethod(impl);
+ addGeneratedMethod(cNode, impl);
}
}
}
diff --git a/src/test/org/codehaus/groovy/transform/GeneratedAnnotationTest.groovy b/src/test/org/codehaus/groovy/transform/GeneratedAnnotationTest.groovy
index 28c7842..c0c61fe 100644
--- a/src/test/org/codehaus/groovy/transform/GeneratedAnnotationTest.groovy
+++ b/src/test/org/codehaus/groovy/transform/GeneratedAnnotationTest.groovy
@@ -94,4 +94,136 @@ class GeneratedAnnotationTest extends GroovyShellTestCase {
def method = person.class.declaredMethods.find { it.name == 'invokeMethod' }
assert !('groovy.transform.Generated' in method.annotations*.annotationType().name)
}
+
+ @Test
+ void testCapturedArgForGeneratedClosureIsAnnotatedWithGenerated_GROOVY9396() {
+ def objectUnderTest = evaluate'''
+ class ClassUnderTest {
+ Closure<String> c(String arg) {
+ def closureVar = {
+ arg
+ }
+ closureVar
+ }
+ }
+ new ClassUnderTest()
+ '''
+
+ Closure<String> closure = objectUnderTest.class.getMethod('c', String).invoke(objectUnderTest, 'var')
+ def getArg = closure.class.getMethod('getArg')
+ assert getArg.annotations*.annotationType().name.contains('groovy.transform.Generated')
+ }
+
+ @Test
+ void testTraitComposerMarksGeneratedMethodsForVariablesAsGenerated_GROOVY10505() {
+ def objectUnderTest = evaluate'''
+ trait TraitWithVariable {
+ private String variableA
+ }
+ trait TraitWithFinalVariable {
+ private final String variableB
+ }
+ trait TraitWithStaticVariable {
+ private static String variableC
+ }
+ trait TraitWithVariableInitialized {
+ private String variableA = "simple variable initialized"
+ }
+ trait TraitWithFinalVariableInitialized {
+ private final String variableB = "final variable initialized"
+ }
+ trait TraitWithStaticVariableInitialized {
+ private static String variableC = "static variable initialized"
+ }
+ trait TraitCompose implements TraitWithVariable, TraitWithFinalVariable, TraitWithStaticVariable,
+ TraitWithVariableInitialized, TraitWithFinalVariableInitialized,
+ TraitWithStaticVariableInitialized {
+
+ }
+ class ClassUnderTest implements TraitCompose {
+
+ }
+ new ClassUnderTest()
+ '''
+
+ def method = objectUnderTest.class.declaredMethods.find { it.name == 'TraitWithVariable__variableA$get'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated')
+ method = objectUnderTest.class.declaredMethods.find { it.name == 'TraitWithVariable__variableA$set'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated')
+
+ method = objectUnderTest.class.declaredMethods.find { it.name == 'TraitWithFinalVariable__variableB$get'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated')
+ method = objectUnderTest.class.declaredMethods.find { it.name == 'TraitWithFinalVariable__variableB$set'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated')
+
+ method = objectUnderTest.class.declaredMethods.find { it.name == 'TraitWithStaticVariable__variableC$get'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated')
+ method = objectUnderTest.class.declaredMethods.find { it.name == 'TraitWithStaticVariable__variableC$set'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated')
+
+ method = objectUnderTest.class.declaredMethods.find { it.name == 'TraitWithVariableInitialized__variableA$get'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated')
+ method = objectUnderTest.class.declaredMethods.find { it.name == 'TraitWithVariableInitialized__variableA$set'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated')
+
+ method = objectUnderTest.class.declaredMethods.find { it.name == 'TraitWithFinalVariableInitialized__variableB$get'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated')
+ method = objectUnderTest.class.declaredMethods.find { it.name == 'TraitWithFinalVariableInitialized__variableB$set'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated')
+
+ method = objectUnderTest.class.declaredMethods.find { it.name == 'TraitWithStaticVariableInitialized__variableC$get'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated')
+ method = objectUnderTest.class.declaredMethods.find { it.name == 'TraitWithStaticVariableInitialized__variableC$set'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated')
+ }
+
+ @Test
+ void testTraitComposerMarksGeneratedMethodsForMethodsAsGenerated_GROOVY10505() {
+ def objectUnderTest = evaluate'''
+ trait TraitWithMethod {
+ String methodA() { "method without generated annotation" }
+ }
+ trait TraitWithMethodAsGenerated {
+ @groovy.transform.Generated
+ String methodB() { "method with generated annotation" }
+ }
+ trait TraitWithStaticMethod {
+ static String methodC() { "static method" }
+ }
+ trait TraitWithFinalMethod {
+ final String methodD() { "final method" }
+ }
+ trait TraitCompose implements TraitWithMethod, TraitWithMethodAsGenerated, TraitWithStaticMethod, TraitWithFinalMethod {
+
+ }
+ class ClassUnderTest implements TraitCompose {
+
+ }
+ new ClassUnderTest()
+ '''
+
+ def method = objectUnderTest.class.declaredMethods.find { it.name == 'TraitWithMethodAsGeneratedtrait$super$methodB'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated')
+
+ method = objectUnderTest.class.declaredMethods.find { it.name == 'TraitWithMethodtrait$super$methodA'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated')
+
+ method = objectUnderTest.class.declaredMethods.find { it.name == 'TraitWithFinalMethodtrait$super$methodD'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated')
+
+
+ // and original methods are marked as they were
+
+ method = objectUnderTest.class.declaredMethods.find { it.name == 'methodA'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated') == false
+
+ method = objectUnderTest.class.declaredMethods.find { it.name == 'methodB'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated')
+
+ method = objectUnderTest.class.declaredMethods.find { it.name == 'methodC'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated') == false
+
+ method = objectUnderTest.class.declaredMethods.find { it.name == 'methodD'}
+ assert method.annotations*.annotationType().name.contains('groovy.transform.Generated') == false
+ }
}
\ No newline at end of file