Skip to content

Commit

Permalink
GROOVY-11372: STC: write property via extension method
Browse files Browse the repository at this point in the history
3_0_X backport
  • Loading branch information
eric-milles committed May 10, 2024
1 parent 005a3ae commit ff4857e
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1517,6 +1517,23 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re
return true;
}

// in case of a lookup on java.lang.Class, look for instance methods on Class
// as well; in case of static property access Class<Type> and Type are listed
boolean staticOnly = isClassClassNodeWrappingConcreteType(receiverType) ? false
: (receiver.getData() == null ? staticOnlyAccess : false);

List<MethodNode> setters = findSetters(wrapTypeIfNecessary(receiverType), setterName, /*voidOnly:*/false);
setters = allowStaticAccessToMember(setters, staticOnly);
// GROOVY-11372:
ClassLoader loader = getSourceUnit().getClassLoader();
Set<MethodNode> dgmSet = findDGMMethodsForClassNode(loader, receiverType, setterName);
if (isPrimitiveType(receiverType)) findDGMMethodsForClassNode(loader, getWrapper(receiverType), setterName, (java.util.TreeSet<MethodNode>) dgmSet);
for (MethodNode method : dgmSet) {
if ((!staticOnly || method.isStatic()) && method.getParameters().length == 1) {
setters.add(method);
}
}

LinkedList<ClassNode> queue = new LinkedList<>();
queue.add(receiverType);
if (isPrimitiveType(receiverType)) {
Expand All @@ -1533,11 +1550,6 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re
Collections.addAll(queue, current.getInterfaces());
}

boolean staticOnly = (receiver.getData() == null ? staticOnlyAccess : false);
// in case of a lookup on java.lang.Class, look for instance methods on Class
// as well; in case of static property access Class<Type> and Type are listed
if (isClassClassNodeWrappingConcreteType(current)) staticOnly = false;

field = allowStaticAccessToMember(field, staticOnly);

// skip property/accessor checks for "x.@field"
Expand All @@ -1562,8 +1574,6 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re
if (getter != null && !isThisExpression(objectExpression) && !isSuperExpression(objectExpression) && isOrImplements(objectExpressionType, MAP_TYPE)) {
getter = null; // GROOVY-11369: map entry comes before access method
}
List<MethodNode> setters = findSetters(current, setterName, false);
setters = allowStaticAccessToMember(setters, staticOnly);

if (readMode && getter != null && visitor != null) visitor.visitMethod(getter);

Expand Down Expand Up @@ -1616,7 +1626,7 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re
foundGetterOrSetter = (foundGetterOrSetter || getter != null || !setters.isEmpty());
}

if (!readMode || isThisExpression(objectExpression) || isSuperExpression(objectExpression) || !isOrImplements(objectExpressionType, MAP_TYPE)) { // GROOVY-11370
if (readMode && (isThisExpression(objectExpression) || isSuperExpression(objectExpression) || !isOrImplements(objectExpressionType, MAP_TYPE))) { // GROOVY-11370, GROOVY-11372
// GROOVY-5568, GROOVY-9115, GROOVY-9123: the property may be defined by an extension
for (ClassNode dgmReceiver : isPrimitiveType(receiverType) ? new ClassNode[]{receiverType, getWrapper(receiverType)} : new ClassNode[]{receiverType}) {
Set<MethodNode> methods = findDGMMethodsForClassNode(getSourceUnit().getClassLoader(), dgmReceiver, getterName);
Expand All @@ -1637,7 +1647,7 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re
}
ClassNode returnType = inferReturnTypeGenerics(dgmReceiver, getter, ArgumentListExpression.EMPTY_ARGUMENTS);
storeInferredTypeForPropertyExpression(pexp, returnType);
if (readMode) storeTargetMethod(pexp, getter);
storeTargetMethod(pexp, getter);
return true;
}
}
Expand Down
12 changes: 11 additions & 1 deletion src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ class FieldsAndPropertiesSTCTest extends StaticTypeCheckingTestCase {
}

// GROOVY-5232
void testSetterForProperty() {
void testSetterForProperty1() {
assertScript '''
class Person {
String name
Expand All @@ -479,6 +479,16 @@ class FieldsAndPropertiesSTCTest extends StaticTypeCheckingTestCase {
'''
}

// GROOVY-11372
void testSetterForProperty2() {
assertScript '''
def baos = new ByteArrayOutputStream()
assert baos.size() == 0
baos.bytes= new byte[1]
assert baos.size() == 1
'''
}

// GROOVY-5443
void testFieldInitShouldPass() {
assertScript '''
Expand Down

0 comments on commit ff4857e

Please sign in to comment.