You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2022/05/19 16:11:48 UTC
[groovy] 02/03: GROOVY-10092: STC: cannot assign `boolean` to non-`boolean` primitives
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 83bca9c6d88f720a6a5b61074ed8cd9c77d2368b
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Wed May 18 16:51:06 2022 -0500
GROOVY-10092: STC: cannot assign `boolean` to non-`boolean` primitives
---
.../transform/stc/StaticTypeCheckingSupport.java | 48 +++++++++++-----------
src/test/groovy/transform/stc/BugsSTCTest.groovy | 13 ++----
2 files changed, 29 insertions(+), 32 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index a842fba3ea..b4a76624a8 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -121,9 +121,8 @@ import static org.codehaus.groovy.ast.ClassHelper.make;
import static org.codehaus.groovy.ast.ClassHelper.makeWithoutCaching;
import static org.codehaus.groovy.ast.ClassHelper.short_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.void_WRAPPER_TYPE;
-import static org.codehaus.groovy.ast.tools.WideningCategories.isBigIntCategory;
import static org.codehaus.groovy.ast.tools.WideningCategories.isFloatingCategory;
-import static org.codehaus.groovy.ast.tools.WideningCategories.isNumberCategory;
+import static org.codehaus.groovy.ast.tools.WideningCategories.isLongCategory;
import static org.codehaus.groovy.ast.tools.WideningCategories.lowestUpperBound;
import static org.codehaus.groovy.runtime.DefaultGroovyMethods.asBoolean;
import static org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport.closeQuietly;
@@ -691,22 +690,34 @@ public abstract class StaticTypeCheckingSupport {
ClassNode rightRedirect = right.redirect();
if (leftRedirect == rightRedirect) return true;
- if (rightRedirect == void_WRAPPER_TYPE) return leftRedirect == VOID_TYPE;
- if (rightRedirect == VOID_TYPE) return leftRedirect == void_WRAPPER_TYPE;
+ if (leftRedirect == VOID_TYPE) return rightRedirect == void_WRAPPER_TYPE;
+ if (leftRedirect == void_WRAPPER_TYPE) return rightRedirect == VOID_TYPE;
- if (isNumberType(rightRedirect) || isNumberCategory(rightRedirect)) {
- if (isBigDecimalType(leftRedirect) || Number_TYPE.equals(leftRedirect)) {
- // any number can be assigned to BigDecimal or Number
+ if (isLongCategory(getUnwrapper(leftRedirect))) {
+ // byte, char, int, long or short can be assigned any base number
+ if (isNumberType(rightRedirect) /*|| rightRedirect == char_TYPE*/) {
return true;
}
- if (isBigIntegerType(leftRedirect)) {
- return isBigIntCategory(getUnwrapper(rightRedirect)) || rightRedirect.isDerivedFrom(BigInteger_TYPE);
+ } else if (isFloatingCategory(getUnwrapper(leftRedirect))) {
+ // float or double can be assigned any base number type or BigDecimal
+ if (isNumberType(rightRedirect) || isBigDecimalType(rightRedirect)) {
+ return true;
+ }
+ } else if (isBigDecimalType(leftRedirect) || Number_TYPE.equals(leftRedirect)) {
+ // BigDecimal or Number can be assigned any derivitave of java.lang.Number
+ if (isNumberType(rightRedirect) || rightRedirect.isDerivedFrom(Number_TYPE)) {
+ return true;
+ }
+ } else if (isBigIntegerType(leftRedirect)) {
+ // BigInteger can be assigned byte, char, int, long, short or BigInteger
+ if (isLongCategory(getUnwrapper(rightRedirect)) || rightRedirect.isDerivedFrom(BigInteger_TYPE)) {
+ return true;
}
+ } else if (isWildcardLeftHandSide(leftRedirect)) {
+ // Object, String, [Bb]oolean or Class can be assigned anything (except null to boolean)
+ return !(leftRedirect == boolean_TYPE && isNullConstant(rightExpression));
}
- // anything can be assigned to an Object, String, [Bb]oolean or Class receiver; except null to boolean
- if (isWildcardLeftHandSide(left) && !(leftRedirect == boolean_TYPE && isNullConstant(rightExpression))) return true;
-
if (leftRedirect == char_TYPE && rightRedirect == Character_TYPE) return true;
if (leftRedirect == Character_TYPE && rightRedirect == char_TYPE) return true;
if ((leftRedirect == char_TYPE || leftRedirect == Character_TYPE) && rightRedirect == STRING_TYPE) {
@@ -727,17 +738,8 @@ public abstract class StaticTypeCheckingSupport {
return true;
}
- // simple check on being subclass
- if (right.isDerivedFrom(left) || (left.isInterface() && right.implementsInterface(left))) return true;
-
- // if left and right are primitives or numbers allow
- if (isPrimitiveType(leftRedirect) && isPrimitiveType(rightRedirect)) return true;
- if (isNumberType(leftRedirect) && isNumberType(rightRedirect)) return true;
-
- // left is a float/double and right is a BigDecimal
- if (isFloatingCategory(leftRedirect) && isBigDecimalType(rightRedirect)) {
- return true;
- }
+ // simple sub-type check
+ if (!left.isInterface() ? right.isDerivedFrom(left) : GeneralUtils.isOrImplements(right, left)) return true;
if (right.isDerivedFrom(CLOSURE_TYPE) && isSAMType(left)) {
return true;
diff --git a/src/test/groovy/transform/stc/BugsSTCTest.groovy b/src/test/groovy/transform/stc/BugsSTCTest.groovy
index 7ec25953a8..45f0cd4a91 100644
--- a/src/test/groovy/transform/stc/BugsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/BugsSTCTest.groovy
@@ -1104,15 +1104,10 @@ Printer
// GROOVY-10092
void testAssignBooleanValueToFloatLocalVariable() {
- assertScript '''
- class C {
- void test() {
- float x = true // internal compiler error: Boolean cannot be cast to Number
- }
- }
- //new C().test()
- 'TODO: STC error for incompatible assignment'
- '''
+ shouldFailWithMessages '''
+ float x = true // internal compiler error: Boolean cannot be cast to Number
+ ''',
+ 'Cannot assign value of type boolean to variable of type float'
}
// GROOVY-10424