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 c5d5e0755b1..ea94d53145c 100644 --- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java +++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java @@ -175,8 +175,8 @@ public abstract class StaticTypeCheckingSupport { Short_TYPE, 1, int_TYPE, 2, Integer_TYPE, 2, - Long_TYPE, 3, long_TYPE, 3, + Long_TYPE, 3, float_TYPE, 4, Float_TYPE, 4, double_TYPE, 5, @@ -453,8 +453,11 @@ public static boolean isAssignableTo(ClassNode type, ClassNode toBeAssignedTo) { if (type == toBeAssignedTo || type == UNKNOWN_PARAMETER_TYPE) return true; if (isPrimitiveType(type)) type = getWrapper(type); if (isPrimitiveType(toBeAssignedTo)) toBeAssignedTo = getWrapper(toBeAssignedTo); - if (NUMBER_TYPES.containsKey(type.redirect()) && NUMBER_TYPES.containsKey(toBeAssignedTo.redirect())) { - return NUMBER_TYPES.get(type.redirect()) <= NUMBER_TYPES.get(toBeAssignedTo.redirect()); + Integer source= NUMBER_TYPES.get(type), target= NUMBER_TYPES.get(toBeAssignedTo); + if (source != null && target != null) { return (source.compareTo(target) <= 0); } + // GROOVY-8325, GROOVY-8488: float or double can be assigned a BigDecimal literal + if (BigDecimal_TYPE.equals(type) && (Double_TYPE.equals(toBeAssignedTo) || Float_TYPE.equals(toBeAssignedTo))) { + return true; } if (type.isArray() && toBeAssignedTo.isArray()) { ClassNode sourceComponent = type.getComponentType(), targetComponent = toBeAssignedTo.getComponentType(); diff --git a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy index 8887b4d2062..607c6e97586 100644 --- a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy +++ b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy @@ -944,6 +944,42 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase { } } + // GROOVY-8488 + void testBigDecimalLiteralArgument() { + assertScript ''' + def m1(double d) { Double.valueOf(d) } + def m2(float f) { Float.valueOf(f) } + assert m1(1.0) == 1.0d + assert m2(1.0) == 1.0f + ''' + + shouldFailWithMessages ''' + class C { + def m1(long l) { Long.valueOf(l) } + def m2(int i) { new Integer(i) } + void test() { + m1(1.0) + m2(1.0) + } + } + ''', + 'Cannot find matching method C#m1(java.math.BigDecimal)', + 'Cannot find matching method C#m2(java.math.BigDecimal)' + + shouldFailWithMessages ''' + class C { + def m1(long l) { Long.valueOf(l) } + def m2(int i) { new Integer(i) } + void test() { + m1(1g) + m2(1g) + } + } + ''', + 'Cannot find matching method C#m1(java.math.BigInteger)', + 'Cannot find matching method C#m2(java.math.BigInteger)' + } + void testBoxingShouldCostMore() { assertScript ''' int foo(int x) { 1 }