You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Daniel Sun (JIRA)" <ji...@apache.org> on 2018/08/26 02:09:00 UTC

[jira] [Resolved] (GROOVY-8337) STC: instanceof in ternary expression not propagating type info to true expression

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

Daniel Sun resolved GROOVY-8337.
--------------------------------
       Resolution: Fixed
         Assignee: Daniel Sun
    Fix Version/s: 2.5.3
                   3.0.0-alpha-4

It is fixed now.
https://github.com/apache/groovy/commit/e82bd2654536675c7abcf51f250921f44b5c44f1

> STC: instanceof in ternary expression not propagating type info to true expression
> ----------------------------------------------------------------------------------
>
>                 Key: GROOVY-8337
>                 URL: https://issues.apache.org/jira/browse/GROOVY-8337
>             Project: Groovy
>          Issue Type: Bug
>          Components: Static Type Checker
>            Reporter: Eric Milles
>            Assignee: Daniel Sun
>            Priority: Minor
>             Fix For: 3.0.0-alpha-4, 2.5.3
>
>         Attachments: screenshot-1.png
>
>
> {code}
> @CompileStatic
> class Static {
>   private Number n
>   BigDecimal meth() {
>     return n == null || n instanceof BigDecimal ? n : new BigDecimal(n.toString())
>   }
> }
> {code}
> StaticTypeCheckingVisitor is missing the temporary type of the true expression part of the ternary expression because it pops before accessing the type.  One possible solution:
> {code}
>     @Override
>     public void visitTernaryExpression(final TernaryExpression expression) {
>         Map<VariableExpression, List<ClassNode>> oldTracker = pushAssignmentTracking();
>         // create a new temporary element in the if-then-else type info
>         typeCheckingContext.pushTemporaryTypeInfo();
>         expression.getBooleanExpression().visit(this);
>         Expression trueExpression = expression.getTrueExpression();
>         Expression falseExpression = expression.getFalseExpression();
>         trueExpression.visit(this);
>         // GRECLIPSE add
>         final ClassNode typeOfTrue = findCurrentInstanceOfClass(trueExpression, getType(trueExpression));
>         // GRECLIPSE end
>         // pop if-then-else temporary type info
>         typeCheckingContext.popTemporaryTypeInfo();
>         falseExpression.visit(this);
>         ClassNode resultType;
>         if (isNullConstant(trueExpression) || isNullConstant(falseExpression)) {
>             BinaryExpression enclosingBinaryExpression = typeCheckingContext.getEnclosingBinaryExpression();
>             if (enclosingBinaryExpression != null && enclosingBinaryExpression.getRightExpression()==expression) {
>                 resultType = getType(enclosingBinaryExpression.getLeftExpression());
>             } else if (isNullConstant(trueExpression) && isNullConstant(falseExpression)) {
>                 resultType = OBJECT_TYPE;
>             } else if (isNullConstant(trueExpression)) {
>                 resultType = wrapTypeIfNecessary(getType(falseExpression));
>             } else {
>                 resultType = wrapTypeIfNecessary(getType(trueExpression));
>             }
>         } else {
>             // store type information
>             // GRECLIPSE edit
>             //final ClassNode typeOfTrue = getType(trueExpression);
>             // GRECLIPSE end
>             final ClassNode typeOfFalse = getType(falseExpression);
>             resultType = lowestUpperBound(typeOfTrue, typeOfFalse);
>         }
>         storeType(expression, resultType);
>         popAssignmentTracking(oldTracker);
>     }
> {code}



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)