You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Paul King (JIRA)" <ji...@apache.org> on 2019/04/23 04:59:00 UTC

[jira] [Resolved] (GROOVY-9077) STC: inferred type of property that resolves to method not always stored

     [ https://issues.apache.org/jira/browse/GROOVY-9077?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Paul King resolved GROOVY-9077.
-------------------------------
       Resolution: Fixed
         Assignee: Paul King
    Fix Version/s: 2.5.7
                   3.0.0-beta-1

Proposed changes applied. I'll change issue summary to reflect that getters are covered. Please clone or create a new issue if you believe setters should be fixed at some point too.

> 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
>            Assignee: Paul King
>            Priority: Minor
>             Fix For: 3.0.0-beta-1, 2.5.7
>
>
> 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)