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] [Created] (GROOVY-8337) STC: instanceof in ternary expression not propagating type info to true expression
Date Mon, 02 Oct 2017 01:01:57 GMT
Eric Milles created GROOVY-8337:
-----------------------------------

             Summary: 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 {
  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