groovy-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Eric Milles (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (GROOVY-8337) STC: instanceof in ternary expression not propagating type info to true expression
Date Mon, 02 Oct 2017 15:11:01 GMT

    [ https://issues.apache.org/jira/browse/GROOVY-8337?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16188291#comment-16188291
] 

Eric Milles commented on GROOVY-8337:
-------------------------------------

I am using 2.4.12.  I agree, on command line and in groovy console it executes.  But I can't
seem to figure out why when it failes within Groovy-Eclipse, which runs the same visitor to
process the source for static compilation.  As you can see from the snippet, I needed to patch
on my end.  But it looked like a probable improvement for the platform, so I opened this issue
and shared my patch.

> 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
>            Priority: Minor
>
> {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
(v6.4.14#64029)

Mime
View raw message