This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
new 0c08d52ee2 GROOVY-11387: STC: entry before field for outside map
property reference
0c08d52ee2 is described below
commit 0c08d52ee2fcd820e197a49d3e531dd8ace1d464
Author: Eric Milles <[email protected]>
AuthorDate: Tue May 28 11:28:19 2024 -0500
GROOVY-11387: STC: entry before field for outside map property reference
---
.../transform/stc/StaticTypeCheckingVisitor.java | 19 +++++++++++++------
.../stc/FieldsAndPropertiesSTCTest.groovy | 22 ++++++++++++++++++++++
2 files changed, 35 insertions(+), 6 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 bf9d94ee49..f09578e068 100644
---
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1562,11 +1562,16 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
continue;
}
- // skip property/accessor checks for "field", "this.field",
"this.with { field }", etc. in declaring class of field
- if (field != null && enclosingTypes.contains(current)) {
- if (storeField(field, pexp, receiverType, visitor,
receiver.getData(), !readMode)) {
- return true;
- }
+ if (field != null // GROOVY-11387: entry before field for
indirect or non-this property expressions
+ && (!receiverType.equals(field.getDeclaringClass()) ||
!(isThisExpression(objectExpression)
+ && !(pexp.isImplicitThis() &&
typeCheckingContext.getEnclosingClosure() != null)))
+ && (readMode || !(field.isPublic() ||
field.isProtected()))
+ && isMapProperty(pexp, receiverType)) {
+ field = null;
+ }
+ // skip property/accessor checks for "field", "this.field",
"this.with { field }", etc. within the declaring class of the field
+ else if (field != null && enclosingTypes.contains(current) &&
storeField(field, pexp, receiverType, visitor, receiver.getData(), !readMode)) {
+ return true;
}
PropertyNode property = current.getProperty(propertyName);
@@ -1584,7 +1589,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
visitor.visitMethod(getter);
}
} else if (readMode) { // GROOVY-5001, GROOVY-5491, GROOVY-8555
- if (property != null) { property = null; field = null; }
+ if (property != null) { property = null; assert field ==
null; }
}
// prefer explicit getter or setter over property if receiver
is not 'this'
@@ -1772,6 +1777,8 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
};
if (!pexp.isSpreadSafe()) {
+ if (pexp.isImplicitThis() &&
isThisExpression(pexp.getObjectExpression()))
+ pexp.putNodeMetaData(DYNAMIC_RESOLUTION,Boolean.TRUE); //
GROOVY-11387
return getCombinedBoundType(gts[1]);
} else {
// map*.property syntax acts on Entry
diff --git a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
index 9da6508290..cea091f780 100644
--- a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
+++ b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
@@ -970,6 +970,28 @@ class FieldsAndPropertiesSTCTest extends
StaticTypeCheckingTestCase {
'''
}
+ // GROOVY-11387
+ void testMapPropertyAccess12() {
+ assertScript '''
+ def map = new HashMap<String,String>()
+ @ASTTest(phase=INSTRUCTION_SELECTION, value={
+ assert node.getNodeMetaData(INFERRED_TYPE) == STRING_TYPE
+ })
+ def xxx = map.table
+ @ASTTest(phase=INSTRUCTION_SELECTION, value={
+ assert node.getNodeMetaData(INFERRED_TYPE) == STRING_TYPE
+ })
+ def yyy = map.with{
+ @ASTTest(phase=INSTRUCTION_SELECTION, value={
+ assert node.getNodeMetaData(INFERRED_TYPE) == STRING_TYPE
+ })
+ def zzz = table
+ }
+ assert xxx == null
+ assert yyy == null
+ '''
+ }
+
void testTypeCheckerDoesNotThinkPropertyIsReadOnly() {
assertScript '''
// a base class defining a read-only property