Skip to content

Commit

Permalink
GROOVY-8283: SC: field hides getter of super class
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Nov 22, 2024
1 parent a69e055 commit 9819280
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@

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;
Expand Down Expand Up @@ -454,6 +455,12 @@ private boolean makeGetPropertyWithGetter(final Expression receiver, final Class
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);
Expand Down
54 changes: 53 additions & 1 deletion src/test/groovy/bugs/Groovy8283.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -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.*
Expand All @@ -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={
Expand Down Expand Up @@ -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()
Expand Down

0 comments on commit 9819280

Please sign in to comment.