diff --git a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/FieldToAccessorTExpr.java b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/FieldToAccessorTExpr.java index d1f04a2bb85..fb4047e7804 100644 --- a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/FieldToAccessorTExpr.java +++ b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/FieldToAccessorTExpr.java @@ -21,6 +21,7 @@ import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.math.BigDecimal; import java.util.Collections; import java.util.List; import java.util.Optional; @@ -30,6 +31,7 @@ import com.github.javaparser.ast.expr.EnclosedExpr; import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.expr.MethodCallExpr; +import org.drools.mvelcompiler.util.BigDecimalArgumentCoercion; import org.drools.util.MethodUtils; import static com.github.javaparser.ast.NodeList.nodeList; @@ -72,7 +74,17 @@ public Node toJavaExpression() { .map(this::convertToStringIfNeeded) .collect(Collectors.toList()); - return new MethodCallExpr((Expression) scope.toJavaExpression(), accessor.getName(), nodeList(expressionArguments)); + Optional rhsType = this.arguments.stream() + .findFirst() + .flatMap(TypedExpression::getType); + + // Right is BigDecimal, left is other, coerce + if(rhsType.isPresent() && rhsType.get().equals(BigDecimal.class) && !type.equals(BigDecimal.class)) { + Expression coercedExpression = new BigDecimalArgumentCoercion().coercedArgument(BigDecimal.class, (Class)type, expressionArguments.get(0)); + return new MethodCallExpr((Expression) scope.toJavaExpression(), accessor.getName(), nodeList(coercedExpression)); + } else { + return new MethodCallExpr((Expression) scope.toJavaExpression(), accessor.getName(), nodeList(expressionArguments)); + } } private Expression convertToStringIfNeeded(TypedExpression argumentExpression) { diff --git a/drools-model/drools-mvel-compiler/src/test/java/org/drools/Person.java b/drools-model/drools-mvel-compiler/src/test/java/org/drools/Person.java index 53c4a508f6e..e99d6887c16 100644 --- a/drools-model/drools-mvel-compiler/src/test/java/org/drools/Person.java +++ b/drools-model/drools-mvel-compiler/src/test/java/org/drools/Person.java @@ -28,6 +28,16 @@ public class Person { private String name; private int age; + private long longValue; + private short shortValue; + private double doubleValue; + private float floatValue; + + private Integer integerBoxed; + private Long longBoxed; + private Short shortBoxed; + private Double doubleBoxed; + private Float floatBoxed; private Person parent; private Address address; @@ -122,4 +132,76 @@ public void setAddresses(List
addresses) { public boolean isEven(int value) { return true; } + + public long getLongValue() { + return longValue; + } + + public void setLongValue(long longValue) { + this.longValue = longValue; + } + + public short getShortValue() { + return shortValue; + } + + public void setShortValue(short shortValue) { + this.shortValue = shortValue; + } + + public double getDoubleValue() { + return doubleValue; + } + + public void setDoubleValue(double doubleValue) { + this.doubleValue = doubleValue; + } + + public float getFloatValue() { + return floatValue; + } + + public void setFloatValue(float floatValue) { + this.floatValue = floatValue; + } + + public Integer getIntegerBoxed() { + return integerBoxed; + } + + public void setIntegerBoxed(Integer integerBoxed) { + this.integerBoxed = integerBoxed; + } + + public Long getLongBoxed() { + return longBoxed; + } + + public void setLongBoxed(Long longBoxed) { + this.longBoxed = longBoxed; + } + + public Short getShortBoxed() { + return shortBoxed; + } + + public void setShortBoxed(Short shortBoxed) { + this.shortBoxed = shortBoxed; + } + + public Double getDoubleBoxed() { + return doubleBoxed; + } + + public void setDoubleBoxed(Double doubleBoxed) { + this.doubleBoxed = doubleBoxed; + } + + public Float getFloatBoxed() { + return floatBoxed; + } + + public void setFloatBoxed(Float floatBoxed) { + this.floatBoxed = floatBoxed; + } } diff --git a/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/MvelCompilerTest.java b/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/MvelCompilerTest.java index 4db881fb600..7de5965da1e 100644 --- a/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/MvelCompilerTest.java +++ b/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/MvelCompilerTest.java @@ -834,6 +834,116 @@ public void testBigDecimalArithmeticWithConversionFromInteger() { "}"); } + @Test + public void testBigDecimalAssignmentToInt() { + test(ctx -> ctx.addDeclaration("$p", Person.class), + "{ " + + " $p.age = $p.salary;\n" + + "}", + "{ " + + " $p.setAge($p.getSalary().intValue());\n" + + "}"); + } + + @Test + public void testBigDecimalAssignmentToIntegerBoxed() { + test(ctx -> ctx.addDeclaration("$p", Person.class), + "{ " + + " $p.integerBoxed = $p.salary;\n" + + "}", + "{ " + + " $p.setIntegerBoxed($p.getSalary().intValue());\n" + + "}"); + } + + @Test + public void testBigDecimalAssignmentToLong() { + test(ctx -> ctx.addDeclaration("$p", Person.class), + "{ " + + " $p.longValue = $p.salary;\n" + + "}", + "{ " + + " $p.setLongValue($p.getSalary().longValue());\n" + + "}"); + } + + @Test + public void testBigDecimalAssignmentToLongBoxed() { + test(ctx -> ctx.addDeclaration("$p", Person.class), + "{ " + + " $p.longBoxed = $p.salary;\n" + + "}", + "{ " + + " $p.setLongBoxed($p.getSalary().longValue());\n" + + "}"); + } + + @Test + public void testBigDecimalAssignmentToShort() { + test(ctx -> ctx.addDeclaration("$p", Person.class), + "{ " + + " $p.shortValue = $p.salary;\n" + + "}", + "{ " + + " $p.setShortValue($p.getSalary().shortValue());\n" + + "}"); + } + + @Test + public void testBigDecimalAssignmentToShortBoxed() { + test(ctx -> ctx.addDeclaration("$p", Person.class), + "{ " + + " $p.shortBoxed = $p.salary;\n" + + "}", + "{ " + + " $p.setShortBoxed($p.getSalary().shortValue());\n" + + "}"); + } + + @Test + public void testBigDecimalAssignmentToDouble() { + test(ctx -> ctx.addDeclaration("$p", Person.class), + "{ " + + " $p.doubleValue = $p.salary;\n" + + "}", + "{ " + + " $p.setDoubleValue($p.getSalary().doubleValue());\n" + + "}"); + } + + @Test + public void testBigDecimalAssignmentToDoubleBoxed() { + test(ctx -> ctx.addDeclaration("$p", Person.class), + "{ " + + " $p.doubleBoxed = $p.salary;\n" + + "}", + "{ " + + " $p.setDoubleBoxed($p.getSalary().doubleValue());\n" + + "}"); + } + + @Test + public void testBigDecimalAssignmentToFloat() { + test(ctx -> ctx.addDeclaration("$p", Person.class), + "{ " + + " $p.floatValue = $p.salary;\n" + + "}", + "{ " + + " $p.setFloatValue($p.getSalary().floatValue());\n" + + "}"); + } + + @Test + public void testBigDecimalAssignmentToFloatBoxed() { + test(ctx -> ctx.addDeclaration("$p", Person.class), + "{ " + + " $p.floatBoxed = $p.salary;\n" + + "}", + "{ " + + " $p.setFloatBoxed($p.getSalary().floatValue());\n" + + "}"); + } + @Test public void testBigDecimalPromotionAllFourOperations() { test(ctx -> ctx.addDeclaration("$p", Person.class),