You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Eric Milles (JIRA)" <ji...@apache.org> on 2019/04/11 20:00:02 UTC
[jira] [Created] (GROOVY-9077) STC: inferred type of property that
resolves to method not always stored
Eric Milles created GROOVY-9077:
-----------------------------------
Summary: STC: inferred type of property that resolves to method not always stored
Key: GROOVY-9077
URL: https://issues.apache.org/jira/browse/GROOVY-9077
Project: Groovy
Issue Type: Bug
Affects Versions: 2.5.6
Reporter: Eric Milles
Consider the following:
{code:groovy}
@groovy.transform.CompileStatic
void meth(List list) {
if (list instanceof LinkedList && list.first) {
}
if (list instanceof LinkedList && list.peek()) {
}
}
{code}
{{storeTargetMethod}} is called for the method call expression {{list.peek()}}. However, when {{org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.existsProperty}} resolves {{list.first}} to a method, {{storeTargetMethod}} is not called. This means the AST node does not record the direct method call target. Also, a type-checking extension does not have a chance to handle the method selection event.
This addition addresses the issue for class getters:
{code:java}
if (readMode && checkGetterOrSetter) {
if (getter != null) {
ClassNode cn = inferReturnTypeGenerics(current, getter, ArgumentListExpression.EMPTY_ARGUMENTS);
storeInferredTypeForPropertyExpression(pexp, cn);
// GRECLIPSE add
storeTargetMethod(pexp, getter);
// GRECLIPSE end
pexp.removeNodeMetaData(StaticTypesMarker.READONLY_PROPERTY);
String delegationData = receiver.getData();
if (delegationData != null)
pexp.putNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER, delegationData);
return true;
}
{code}
and this change addresses the issue for extension method getters:
{code:java}
// GROOVY-5568, the property may be defined by DGM
List<ClassNode> dgmReceivers = new ArrayList<ClassNode>(2);
dgmReceivers.add(testClass);
if (isPrimitiveType(testClass)) dgmReceivers.add(getWrapper(testClass));
for (ClassNode dgmReceiver : dgmReceivers) {
List<MethodNode> methods = findDGMMethodsByNameAndArguments(getTransformLoader(), dgmReceiver, "get" + capName, ClassNode.EMPTY_ARRAY);
for (MethodNode m : findDGMMethodsByNameAndArguments(getTransformLoader(), dgmReceiver, "is" + capName, ClassNode.EMPTY_ARRAY)) {
if (Boolean_TYPE.equals(getWrapper(m.getReturnType()))) methods.add(m);
}
if (!methods.isEmpty()) {
List<MethodNode> methodNodes = chooseBestMethod(dgmReceiver, methods, ClassNode.EMPTY_ARRAY);
if (methodNodes.size() == 1) {
MethodNode getter = methodNodes.get(0);
if (visitor != null) {
visitor.visitMethod(getter);
}
ClassNode cn = inferReturnTypeGenerics(dgmReceiver, getter, ArgumentListExpression.EMPTY_ARGUMENTS);
storeInferredTypeForPropertyExpression(pexp, cn);
// GRECLIPSE add
storeTargetMethod(pexp, getter);
// GRECLIPSE end
return true;
}
}
}
{code}
The selection of a setter method is not as simple, since there may be many candidates.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)