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()

Reply via email to