This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY-8283
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY-8283 by this push:
new 9819280534 GROOVY-8283: SC: field hides getter of super class
9819280534 is described below
commit 981928053477e7d7790e0b6000e7a4dd5b45b583
Author: Eric Milles <[email protected]>
AuthorDate: Fri Nov 22 12:02:46 2024 -0600
GROOVY-8283: SC: field hides getter of super class
---
.../classgen/asm/sc/StaticTypesCallSiteWriter.java | 7 +++
src/test/groovy/bugs/Groovy8283.groovy | 54 +++++++++++++++++++++-
2 files changed, 60 insertions(+), 1 deletion(-)
diff --git
a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
index cd641ceb40..5a014a4f25 100644
---
a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
+++
b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
@@ -55,6 +55,7 @@ import java.util.function.Predicate;
import static org.apache.groovy.ast.tools.ClassNodeUtils.getField;
import static org.apache.groovy.ast.tools.ClassNodeUtils.getMethod;
+import static org.apache.groovy.ast.tools.ClassNodeUtils.isSubtype;
import static org.apache.groovy.ast.tools.ExpressionUtils.isThisExpression;
import static org.apache.groovy.util.BeanUtils.capitalize;
import static org.codehaus.groovy.ast.ClassHelper.CLASS_Type;
@@ -454,6 +455,12 @@ public class StaticTypesCallSiteWriter extends
CallSiteWriter {
if
(!AsmClassGenerator.isMemberDirectlyAccessible(getterNode.getModifiers(),
getterNode.getDeclaringClass(), controller.getClassNode())) {
return false; // GROOVY-6277
}
+ FieldNode fieldNode = getField(receiverType, propertyName);
+ if (fieldNode != null &&
!getterNode.getDeclaringClass().equals(fieldNode.getDeclaringClass())
+ && isSubtype(getterNode.getDeclaringClass(),
fieldNode.getDeclaringClass()) // field found before getter (starting from
receiver type)
+ &&
AsmClassGenerator.isMemberDirectlyAccessible(fieldNode.getModifiers(),
fieldNode.getDeclaringClass(), controller.getClassNode())) {
+ return false; // GROOVY-8283
+ }
MethodCallExpression call = callX(receiver, getterName);
call.setImplicitThis(implicitThis);
call.setMethodTarget(getterNode);
diff --git a/src/test/groovy/bugs/Groovy8283.groovy
b/src/test/groovy/bugs/Groovy8283.groovy
index 9e75a720b2..fc34722f4a 100644
--- a/src/test/groovy/bugs/Groovy8283.groovy
+++ b/src/test/groovy/bugs/Groovy8283.groovy
@@ -35,7 +35,7 @@ final class Groovy8283 {
A getFoo() { return foo }
}
class D extends C {
- protected B foo = new B() // hides A#foo; should hide A#getFoo
in subclasses
+ protected B foo = new B()
}
'''
assertScript shell, '''import p.*
@@ -56,6 +56,22 @@ final class Groovy8283 {
new E().test()
assert new E().foo.class == A // not the field from this
perspective
'''
+ }
+
+ @Test
+ void testReadFieldPropertyShadowing2() {
+ def shell = new GroovyShell()
+ shell.parse '''package p
+ class A {}
+ class B {}
+ class C {
+ protected A foo = new A()
+ A getFoo() { return foo }
+ }
+ class D extends C {
+ protected B foo = new B()
+ }
+ '''
assertScript shell, '''import p.*
class E extends D {
@groovy.transform.ASTTest(phase=org.codehaus.groovy.control.CompilePhase.INSTRUCTION_SELECTION,
value={
@@ -102,6 +118,42 @@ final class Groovy8283 {
'''
}
+ @Test
+ void testReadFieldPropertyShadowing3() {
+ def shell = GroovyShell.withConfig {
+ ast(groovy.transform.CompileStatic)
+ }
+ shell.parse '''package p
+ class A {}
+ class B {}
+ class C {
+ protected A foo = new A()
+ A getFoo() { return foo }
+ }
+ class D extends C {
+ protected B foo = new B()
+ }
+ '''
+ assertScript shell, '''import p.*
+ class E extends D {
+ void test() {
+ assert foo.class == B
+ assert this.foo.class == B
+ assert [email protected] == B
+ assert this.getFoo().getClass() == A
+
+ def that = new E()
+ assert that.foo.class == B
+ assert [email protected] == B
+ assert that.getFoo().getClass() == A
+ }
+ }
+
+ new E().test()
+ assert new E().foo.class == A // not the field from this
perspective
+ '''
+ }
+
@Test
void testWriteFieldPropertyShadowing() {
def shell = new GroovyShell()