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)