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 e1c2dbe489 GROOVY-11384: STC: map property for implicit-this within
closure
e1c2dbe489 is described below
commit e1c2dbe489b7b5b6daf58547f01a9923d5367a4b
Author: Eric Milles <[email protected]>
AuthorDate: Thu May 23 10:37:51 2024 -0500
GROOVY-11384: STC: map property for implicit-this within closure
---
.../transform/stc/StaticTypeCheckingVisitor.java | 20 ++++++++++----------
.../transform/stc/FieldsAndPropertiesSTCTest.groovy | 17 +++++++++++++++--
2 files changed, 25 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 4262eb31f4..8da905d8cf 100644
---
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1565,8 +1565,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
queue.addFirst(current.getSuperClass());
Collections.addAll(queue, current.getInterfaces());
}
-
- field = allowStaticAccessToMember(field, staticOnly);
+ else field = allowStaticAccessToMember(field, staticOnly);
// skip property/accessor checks for "x.@field"
if (pexp instanceof AttributeExpression) {
@@ -1587,7 +1586,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
property = allowStaticAccessToMember(property, staticOnly);
MethodNode getter = null;
- if (!isMapProperty(pexp)) { // GROOVY-11369: map entry before
getter
+ if (!isMapProperty(pexp, receiverType)) { // GROOVY-11369: map
entry before getter
getter = findGetter(current, isserName,
pexp.isImplicitThis());
getter = allowStaticAccessToMember(getter, staticOnly);
if (getter == null) {
@@ -1651,8 +1650,8 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
foundGetterOrSetter = (foundGetterOrSetter || getter != null
|| !setters.isEmpty());
}
- if (readMode && !isMapProperty(pexp)) { // GROOVY-11369,
GROOVY-11370, GROOVY-11372
- // GROOVY-5568, GROOVY-9115, GROOVY-9123: the property may be
defined by an extension
+ if (readMode && !isMapProperty(pexp, receiverType)) { //
GROOVY-11369, GROOVY-11370, GROOVY-11372
+ // GROOVY-5568, GROOVY-9115, GROOVY-9123: the property may be
provided by an extension method
for (ClassNode dgmReceiver : isPrimitiveType(receiverType) ?
new ClassNode[]{receiverType, getWrapper(receiverType)} : new
ClassNode[]{receiverType}) {
Set<MethodNode> methods =
findDGMMethodsForClassNode(getSourceUnit().getClassLoader(), dgmReceiver,
getterName);
for (MethodNode method :
findDGMMethodsForClassNode(getSourceUnit().getClassLoader(), dgmReceiver,
isserName)) {
@@ -1717,8 +1716,8 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
continue;
if (visitor != null) {
// TODO: type inference on maps and lists, if possible
- PropertyNode node = new PropertyNode(propertyName,
Opcodes.ACC_PUBLIC, propertyType, receiver.getType(), null, null, null);
- node.setDeclaringClass(receiver.getType());
+ PropertyNode node = new PropertyNode(propertyName,
Opcodes.ACC_PUBLIC, propertyType, receiverType, null, null, null);
+ node.setDeclaringClass(receiverType);
visitor.visitProperty(node);
}
storeType(pexp, propertyType);
@@ -1831,13 +1830,14 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
return null;
}
- private boolean isMapProperty(final PropertyExpression pexp) {
- final Expression objectExpression = pexp.getObjectExpression();
+ private boolean isMapProperty(final PropertyExpression pexp, final
ClassNode receiverType) {
+ Expression objectExpression = pexp.getObjectExpression();
if (isThisExpression(objectExpression)
+ && (!pexp.isImplicitThis() ||
typeCheckingContext.getEnclosingClosure() == null)
&&
Arrays.asList(getTypeCheckingAnnotations()).contains(COMPILESTATIC_CLASSNODE)) {
return false;
}
- return isOrImplements(getType(objectExpression), MAP_TYPE);
+ return isOrImplements(receiverType, MAP_TYPE);
}
/**
diff --git a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
index d63a515efb..665143cef4 100644
--- a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
+++ b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
@@ -163,7 +163,7 @@ class FieldsAndPropertiesSTCTest extends
StaticTypeCheckingTestCase {
c.@x = '1'
''',
'Cannot assign value of type java.lang.String to variable of type int'
- }
+ }
void testInferenceFromAttributeType() {
assertScript '''
@@ -512,6 +512,7 @@ class FieldsAndPropertiesSTCTest extends
StaticTypeCheckingTestCase {
class C {
Closure<List> bar = { Date date -> date.getTime() }
}
+ new C()
''',
'Cannot return value of type long for closure expecting java.util.List'
@@ -519,6 +520,7 @@ class FieldsAndPropertiesSTCTest extends
StaticTypeCheckingTestCase {
class C {
java.util.function.Supplier<String> bar = { -> 123 }
}
+ new C()
''',
'Cannot return value of type int for closure expecting
java.lang.String'
}
@@ -687,7 +689,7 @@ class FieldsAndPropertiesSTCTest extends
StaticTypeCheckingTestCase {
'''
}
- // GROOVY-11369
+ // GROOVY-11369, GROOVY-11384
void testMapPropertyAccess5() {
assertScript '''
def map = [:]
@@ -709,6 +711,17 @@ class FieldsAndPropertiesSTCTest extends
StaticTypeCheckingTestCase {
assert !map.containsKey('metaClass')
assert map.containsKey('properties')
'''
+ assertScript '''
+ void test(Map map) {
+ def str = ''
+ str += map.empty
+ str += map.with{ empty }
+ str += map.with{ delegate.empty }
+ str += map.with{ {->owner.empty}() }
+ assert str == 'entryentryentryentry'
+ }
+ test( [:].withDefault{ 'entry' } )
+ '''
}
// GROOVY-11369