This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_5_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_5_0_X by this push:
new 99ddcf17be GROOVY-11675: split property may declare final modifier for
accessors
99ddcf17be is described below
commit 99ddcf17bed599ecb13b7ddec6227a330e3a53d5
Author: Eric Milles <[email protected]>
AuthorDate: Wed Sep 17 08:44:56 2025 -0500
GROOVY-11675: split property may declare final modifier for accessors
---
.../groovy/ast/tools/PropertyNodeUtils.java | 15 ++++--
src/test/groovy/groovy/PropertyTest.groovy | 55 +++++++++++++++++++++-
2 files changed, 64 insertions(+), 6 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/PropertyNodeUtils.java
b/src/main/java/org/codehaus/groovy/ast/tools/PropertyNodeUtils.java
index 1f282023d8..a0abc685a6 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/PropertyNodeUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/PropertyNodeUtils.java
@@ -23,6 +23,7 @@ import org.codehaus.groovy.ast.PropertyNode;
import java.lang.reflect.Modifier;
public class PropertyNodeUtils {
+
/**
* Fields within the AST that have no explicit visibility are deemed to be
properties
* and represented by a PropertyNode. The Groovy compiler creates accessor
methods and
@@ -33,11 +34,17 @@ public class PropertyNodeUtils {
* methods (such as {@code volatile} and {@code transient}) but other
modifiers are carried over,
* for example {@code static}.
*
- * @param propNode the original property node
+ * @since 2.4.8
+ * @param node the original property node
* @return the modifiers which make sense for an accessor method
*/
- public static int adjustPropertyModifiersForMethod(PropertyNode propNode) {
- // GROOVY-3726: clear some modifiers so that they do not get applied
to methods
- return propNode.getModifiers() & ~(Modifier.FINAL | Modifier.TRANSIENT
| Modifier.VOLATILE);
+ public static int adjustPropertyModifiersForMethod(final PropertyNode
node) {
+ // GROOVY-3726, GROOVY-7969: clear modifiers that do not apply to
methods
+ int mods = node.getModifiers() &
~(Modifier.TRANSIENT|Modifier.VOLATILE);
+ // GROOVY-11675: split property case may declare final modifier
+ if (node.getField() == null || node.getField().isSynthetic()) {
+ mods &= ~Modifier.FINAL;
+ }
+ return mods;
}
}
diff --git a/src/test/groovy/groovy/PropertyTest.groovy
b/src/test/groovy/groovy/PropertyTest.groovy
index 2a9db0a400..761fcde041 100644
--- a/src/test/groovy/groovy/PropertyTest.groovy
+++ b/src/test/groovy/groovy/PropertyTest.groovy
@@ -132,6 +132,57 @@ final class PropertyTest {
assert foo.body == "James"
}
+ // GROOVY-11675
+ @Test
+ void testSplitProperty() {
+ assertScript '''import java.lang.reflect.*
+ class C {
+ @Deprecated private final Integer one
+ final Integer one
+
+ protected synchronized Integer two
+ synchronized Integer two
+
+ public Integer three
+ @Deprecated Integer three
+ }
+
+ Member m = C.getDeclaredField('one')
+ assert m.isAnnotationPresent(Deprecated)
+ assert m.modifiers == Modifier.PRIVATE + Modifier.FINAL
+
+ m = C.getDeclaredMethod('getOne')
+ assert !m.isAnnotationPresent(Deprecated)
+ assert m.modifiers == Modifier.PUBLIC + Modifier.FINAL
+
+ groovy.test.GroovyAssert.shouldFail(NoSuchMethodException) {
+ m = C.getDeclaredMethod('setOne', Integer)
+ }
+
+ m = C.getDeclaredField('two')
+ assert m.modifiers == Modifier.PROTECTED
+ // field cannot carry modifier SYNCHRONIZED
+
+ m = C.getDeclaredMethod('getTwo')
+ assert m.modifiers == Modifier.PUBLIC + Modifier.SYNCHRONIZED
+
+ m = C.getDeclaredMethod('setTwo', Integer)
+ assert m.modifiers == Modifier.PUBLIC + Modifier.SYNCHRONIZED
+
+ m = C.getDeclaredField('three')
+ assert m.modifiers == Modifier.PUBLIC
+ assert !m.isAnnotationPresent(Deprecated)
+
+ m = C.getDeclaredMethod('getThree')
+ assert m.modifiers == Modifier.PUBLIC
+ assert m.isAnnotationPresent(Deprecated)
+
+ m = C.getDeclaredMethod('setThree', Integer)
+ assert m.modifiers == Modifier.PUBLIC
+ assert m.isAnnotationPresent(Deprecated)
+ '''
+ }
+
@Test
void testFinalProperty() {
assertScript '''
@@ -821,7 +872,7 @@ final class PropertyTest {
static class Child extends Base {
protected String field = 'foo' + super.field
- def getField() { field }
+ def getField() { field }
void setSuperField(value) { super.field = value }
@@ -829,7 +880,7 @@ final class PropertyTest {
def thing = 'bar thing'
- def superthing() {
+ def superthing() {
'bar1' + super.thing
}