Skip to content

Commit

Permalink
GROOVY-11353: STC: def var = null; var = 0 requires wrapper type
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Sep 7, 2024
1 parent 092c0c0 commit 738fe8e
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -903,7 +903,11 @@ && isAssignment(enclosingBinaryExpression.getOperation().getType())) {

boolean isEmptyDeclaration = (expression instanceof DeclarationExpression
&& (rightExpression instanceof EmptyExpression || rType == UNKNOWN_PARAMETER_TYPE));
if (!isEmptyDeclaration && isAssignment(op)) {
if (isEmptyDeclaration) {
// GROOVY-11353: "def var = null" cannot be a primitive type
if (isDynamicTyped(lType) && rType == UNKNOWN_PARAMETER_TYPE)
lType.putNodeMetaData("non-primitive type", Boolean.TRUE);
} else if (isAssignment(op)) {
if (rightExpression instanceof ConstructorCallExpression)
inferDiamondType((ConstructorCallExpression) rightExpression, lType);

Expand Down Expand Up @@ -965,10 +969,9 @@ && isAssignment(enclosingBinaryExpression.getOperation().getType())) {
}
if (!isEmptyDeclaration) {
storeType(expression, resultType);
validateResourceInARM(expression, resultType);
}

validateResourceInARM(expression, resultType);

// GROOVY-5874: if left expression is a closure shared variable, a second pass should be done
if (leftExpression instanceof VariableExpression && ((VariableExpression) leftExpression).isClosureSharedVariable()) {
typeCheckingContext.secondPassExpressions.add(new SecondPassExpression<>(expression));
Expand Down Expand Up @@ -4618,9 +4621,11 @@ protected ClassNode getResultType(ClassNode left, final int op, final ClassNode
if (op == EQUAL || op == ELVIS_EQUAL) {
if (leftExpression instanceof VariableExpression) {
ClassNode initialType = getOriginalDeclarationType(leftExpression);
if (isDynamicTyped(initialType)) { // GROOVY-11375
if (isDynamicTyped(initialType)) { // GROOVY-11353, GROOVY-11375
ClassNode inferredType = leftExpression.getNodeMetaData(INFERRED_TYPE);
if (inferredType != null && !isPrimitiveType(inferredType)) initialType = OBJECT_TYPE;
if (inferredType != null ? !isPrimitiveType(inferredType) : Boolean.TRUE.equals(initialType.getNodeMetaData("non-primitive type"))) {
initialType = OBJECT_TYPE;
}
}

if (isPrimitiveType(rightRedirect) && (initialType.isDerivedFrom(Number_TYPE) || (isObjectType(initialType) && !isDynamicTyped(initialType)))) {
Expand Down
11 changes: 11 additions & 0 deletions src/test/groovy/transform/stc/STCAssignmentTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,17 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
'Cannot find matching method java.io.Serializable#toInteger()'
}

// GROOVY-11353
void testForLoopWithAssignment2() {
assertScript '''
def x = null // Cannot cast object 'null' to class 'int'
for (int i = 0; i < 1; i += 1) {
x = i
}
assert x == 0
'''
}

void testWhileLoopWithAssignment() {
shouldFailWithMessages '''
def x = '123'
Expand Down

0 comments on commit 738fe8e

Please sign in to comment.