Skip to content

Commit

Permalink
GROOVY-11370: STC: extension method cannot provide map property
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed May 9, 2024
1 parent 2202988 commit 9d41af9
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1616,28 +1616,30 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re
foundGetterOrSetter = (foundGetterOrSetter || getter != null || !setters.isEmpty());
}

// GROOVY-5568: the property may be defined by DGM
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)) {
if (Boolean_TYPE.equals(getWrapper(method.getReturnType()))) methods.add(method);
}
if (isUsingGenericsOrIsArrayUsingGenerics(dgmReceiver)) {
methods.removeIf(method -> // GROOVY-10075: "List<Integer>" vs "List<String>"
!typeCheckMethodsWithGenerics(dgmReceiver, ClassNode.EMPTY_ARRAY, method)
);
}
if (!methods.isEmpty()) {
List<MethodNode> bestMethods = chooseBestMethod(dgmReceiver, methods, ClassNode.EMPTY_ARRAY);
if (bestMethods.size() == 1) {
MethodNode getter = bestMethods.get(0);
if (visitor != null) {
visitor.visitMethod(getter);
if (!readMode || isThisExpression(objectExpression) || isSuperExpression(objectExpression) || !isOrImplements(objectExpressionType, MAP_TYPE)) { // GROOVY-11370
// 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);
for (MethodNode method : findDGMMethodsForClassNode(getSourceUnit().getClassLoader(), dgmReceiver, isserName)) {
if (Boolean_TYPE.equals(getWrapper(method.getReturnType()))) methods.add(method);
}
if (isUsingGenericsOrIsArrayUsingGenerics(dgmReceiver)) {
methods.removeIf(method -> // GROOVY-10075: "List<Integer>" vs "List<String>"
!typeCheckMethodsWithGenerics(dgmReceiver, ClassNode.EMPTY_ARRAY, method)
);
}
if (!methods.isEmpty()) {
List<MethodNode> bestMethods = chooseBestMethod(dgmReceiver, methods, ClassNode.EMPTY_ARRAY);
if (bestMethods.size() == 1) {
MethodNode getter = bestMethods.get(0);
if (visitor != null) {
visitor.visitMethod(getter);
}
ClassNode returnType = inferReturnTypeGenerics(dgmReceiver, getter, ArgumentListExpression.EMPTY_ARGUMENTS);
storeInferredTypeForPropertyExpression(pexp, returnType);
if (readMode) storeTargetMethod(pexp, getter);
return true;
}
ClassNode returnType = inferReturnTypeGenerics(dgmReceiver, getter, ArgumentListExpression.EMPTY_ARGUMENTS);
storeInferredTypeForPropertyExpression(pexp, returnType);
if (readMode) storeTargetMethod(pexp, getter);
return true;
}
}
}
Expand Down
42 changes: 20 additions & 22 deletions src/test/groovy/bugs/Groovy9115.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -18,49 +18,47 @@
*/
package groovy.bugs

import groovy.transform.CompileStatic
import org.junit.Test

import static groovy.test.GroovyAssert.assertScript

@CompileStatic
final class Groovy9115 {

@Test
void testSetPropertyInIfStmt() {
void testSetProperty1() {
assertScript '''
@groovy.transform.CompileStatic
class Derived {
def m() {
if (true) {
File file = File.createTempFile("hello${System.nanoTime()}", ".tmp")
file.text = 'Groovy9115Bug'
assert 'Groovy9115Bug' == file.text
}
return null
void test() {
File file = File.createTempFile('test', null)
try {
file.text = 'GROOVY-9115' // via ResourceGroovyMethods#setText
assert file.text == 'GROOVY-9115'
} finally {
file.delete()
}
}
new Derived().m()
test()
'''
}

@Test
void testSetProperty() {
void testSetProperty2() {
assertScript '''
@groovy.transform.CompileStatic
class Derived {
def m() {
File file = File.createTempFile("hello${System.nanoTime()}", ".tmp")
file.text = 'Groovy9115Bug'
assert 'Groovy9115Bug' == file.text
return null
void test() {
if (true) {
File file = File.createTempFile('test', null)
try {
file.text = 'GROOVY-9115' // via ResourceGroovyMethods#setText
assert file.text == 'GROOVY-9115'
} finally {
file.delete()
}
}
}
new Derived().m()
test()
'''
}
}

0 comments on commit 9d41af9

Please sign in to comment.