You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2024/05/14 21:00:14 UTC
(groovy) branch GROOVY_4_0_X updated: GROOVY-11369: map entry comes before access method (pt.2)
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_4_0_X by this push:
new 364117de5e GROOVY-11369: map entry comes before access method (pt.2)
364117de5e is described below
commit 364117de5ea44d570fd6c10b719d979e04673ca6
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue May 14 15:49:53 2024 -0500
GROOVY-11369: map entry comes before access method (pt.2)
---
.../transform/stc/StaticTypeCheckingVisitor.java | 34 ++++++++++++++--------
.../stc/FieldsAndPropertiesSTCTest.groovy | 20 +++++++++++++
.../sc/FieldsAndPropertiesStaticCompileTest.groovy | 21 +++++++++++++
3 files changed, 63 insertions(+), 12 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index 9a6eb6b26f..397189ea7e 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -257,6 +257,7 @@ import static org.codehaus.groovy.syntax.Types.MINUS_MINUS;
import static org.codehaus.groovy.syntax.Types.MOD;
import static org.codehaus.groovy.syntax.Types.MOD_EQUAL;
import static org.codehaus.groovy.syntax.Types.PLUS_PLUS;
+import static org.codehaus.groovy.transform.sc.StaticCompilationVisitor.COMPILESTATIC_CLASSNODE;
import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.ArrayList_TYPE;
import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.Collection_TYPE;
import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.LinkedHashMap_TYPE;
@@ -1582,20 +1583,20 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
}
- MethodNode getter = findGetter(current, isserName, pexp.isImplicitThis());
- getter = allowStaticAccessToMember(getter, staticOnly);
- if (getter == null) getter = findGetter(current, getterName, pexp.isImplicitThis());
- getter = allowStaticAccessToMember(getter, staticOnly);
- if (getter != null
- // GROOVY-11319:
- && (!hasAccessToMember(typeCheckingContext.getEnclosingClassNode(), getter.getDeclaringClass(), getter.getModifiers())
- // GROOVY-11369:
- || (!isThisExpression(objectExpression) && !isSuperExpression(objectExpression) && isOrImplements(objectExpressionType, MAP_TYPE)))) {
- getter = null;
+ MethodNode getter = null;
+ if (!isMapProperty(pexp)) { // GROOVY-11369: map entry before getter
+ getter = findGetter(current, isserName, pexp.isImplicitThis());
+ getter = allowStaticAccessToMember(getter, staticOnly);
+ if (getter == null) {
+ getter = findGetter(current, getterName, pexp.isImplicitThis());
+ getter = allowStaticAccessToMember(getter, staticOnly);
+ }
+ if (getter != null && !hasAccessToMember(typeCheckingContext.getEnclosingClassNode(), getter.getDeclaringClass(), getter.getModifiers())) {
+ getter = null; // GROOVY-11319
+ }
+ if (readMode && getter != null && visitor != null) visitor.visitMethod(getter);
}
- if (readMode && getter != null && visitor != null) visitor.visitMethod(getter);
-
PropertyNode property = current.getProperty(propertyName);
property = allowStaticAccessToMember(property, staticOnly);
// prefer explicit getter or setter over property if receiver is not 'this'
@@ -1825,6 +1826,15 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
return null;
}
+ private boolean isMapProperty(final PropertyExpression pexp) {
+ final Expression objectExpression = pexp.getObjectExpression();
+ if ((isThisExpression(objectExpression) || isSuperExpression(objectExpression))
+ && Arrays.asList(getTypeCheckingAnnotations()).contains(COMPILESTATIC_CLASSNODE)) {
+ return false;
+ }
+ return isOrImplements(getType(objectExpression), MAP_TYPE);
+ }
+
/**
* Filters search result to prevent access to instance members from a static
* context.
diff --git a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
index a9ee27e763..8a9d097ec1 100644
--- a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
+++ b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
@@ -711,6 +711,26 @@ class FieldsAndPropertiesSTCTest extends StaticTypeCheckingTestCase {
'''
}
+ // GROOVY-11369
+ void testMapPropertyAccess5a() {
+ for (mod in ['def', 'public', 'protected', '@groovy.transform.PackageScope', 'private']) {
+ assertScript """
+ class C implements Map<String,String> {
+ @Delegate Map<String,String> impl = [:].withDefault{'entry'}
+ $mod getFoo() { 'getter' }
+ void test() {
+ @ASTTest(phase=INSTRUCTION_SELECTION, value={
+ assert node.getNodeMetaData(INFERRED_TYPE) == STRING_TYPE
+ })
+ def which = this.foo
+ assert which == 'entry'
+ }
+ }
+ new C().test()
+ """
+ }
+ }
+
// GROOVY-8074
void testMapPropertyAccess6() {
assertScript '''
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
index 0cd7e9ba50..4cab93b46e 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
@@ -866,6 +866,27 @@ final class FieldsAndPropertiesStaticCompileTest extends FieldsAndPropertiesSTCT
super.testPublicFieldVersusPrivateGetter()
}
+ // GROOVY-11369
+ @Override
+ void testMapPropertyAccess5a() {
+ for (mod in ['def', 'public', 'protected', '@groovy.transform.PackageScope', 'private']) {
+ assertScript """
+ class C implements Map<String,String> {
+ @Delegate Map<String,String> impl = [:].withDefault{'entry'}
+ $mod getFoo() { 'getter' }
+ void test() {
+ @ASTTest(phase=INSTRUCTION_SELECTION, value={
+ assert node.getNodeMetaData(INFERRED_TYPE) == OBJECT_TYPE
+ })
+ def which = this.foo
+ assert which == 'getter'
+ }
+ }
+ new C().test()
+ """
+ }
+ }
+
// GROOVY-11223, GROOVY-11373
@Override
void testMapPropertyAccess10() {