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)