This is an automated email from the ASF dual-hosted git repository.
tkobayas pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git
The following commit(s) were added to refs/heads/main by this push:
new 866a77a561 [incubator-kie-drools-6253] BigInteger arithmetic
operations with executable-model (#6276)
866a77a561 is described below
commit 866a77a561f8c143a1c86350eecb3eafb1f41a4d
Author: Toshiya Kobayashi <[email protected]>
AuthorDate: Fri Mar 7 10:17:17 2025 +0900
[incubator-kie-drools-6253] BigInteger arithmetic operations with
executable-model (#6276)
---
.../generator/drlxparse/CoercedExpression.java | 2 +
.../generator/expressiontyper/ExpressionTyper.java | 25 +-
.../codegen/execmodel/bigintegertest/BIFact.java | 43 ++
.../execmodel/bigintegertest/BigIntegerTest.java | 765 ++++++++++++++++++++-
.../codegen/execmodel/bigintegertest/Customer.java | 64 ++
.../codegen/execmodel/bigintegertest/Policy.java | 44 ++
.../java/org/drools/mvelcompiler/LHSPhase.java | 48 +-
.../java/org/drools/mvelcompiler/RHSPhase.java | 24 +-
.../org/drools/mvelcompiler/ReProcessRHSPhase.java | 32 +-
.../mvelcompiler/ast/BigDecimalConvertedExprT.java | 2 +-
.../ast/BigIntegerArithmeticExprT.java | 101 +++
.../mvelcompiler/ast/BigIntegerConvertedExprT.java | 27 +-
...edExprT.java => BigIntegerRelationalExprT.java} | 33 +-
.../mvelcompiler/ast/FieldToAccessorTExpr.java | 10 +-
.../drools/mvelcompiler/ast/MethodCallExprT.java | 4 +-
...oercion.java => BigNumberArgumentCoercion.java} | 29 +-
.../src/test/java/org/drools/Person.java | 10 +
.../java/org/drools/mvelcompiler/CompilerTest.java | 1 +
.../mvelcompiler/ConstraintCompilerTest.java | 63 ++
.../org/drools/mvelcompiler/MvelCompilerTest.java | 318 ++++++++-
20 files changed, 1564 insertions(+), 81 deletions(-)
diff --git
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/CoercedExpression.java
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/CoercedExpression.java
index e26c133273..b4b6923229 100644
---
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/CoercedExpression.java
+++
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/CoercedExpression.java
@@ -20,6 +20,7 @@ package
org.drools.model.codegen.execmodel.generator.drlxparse;
import java.io.Serializable;
import java.math.BigDecimal;
+import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;
@@ -265,6 +266,7 @@ public class CoercedExpression {
b.getType() != String.class &&
b.getType() != Object.class &&
b.getType() != BigDecimal.class &&
+ b.getType() != BigInteger.class &&
!(Map.class.isAssignableFrom(b.getRawClass())) &&
!(b.getExpression() instanceof NullLiteralExpr) &&
b.getType() != Serializable.class;
diff --git
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/expressiontyper/ExpressionTyper.java
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/expressiontyper/ExpressionTyper.java
index 6b6a64ba35..8c3771db4f 100644
---
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/expressiontyper/ExpressionTyper.java
+++
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/expressiontyper/ExpressionTyper.java
@@ -23,6 +23,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.math.BigDecimal;
+import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -92,7 +93,7 @@ import org.drools.mvel.parser.ast.expr.PointFreeExpr;
import org.drools.mvel.parser.printer.PrintUtil;
import org.drools.mvelcompiler.CompiledExpressionResult;
import org.drools.mvelcompiler.ConstraintCompiler;
-import org.drools.mvelcompiler.util.BigDecimalArgumentCoercion;
+import org.drools.mvelcompiler.util.BigNumberArgumentCoercion;
import org.drools.util.ClassUtils;
import org.drools.util.MethodUtils;
import org.drools.util.Pair;
@@ -827,17 +828,23 @@ public class ExpressionTyper {
}
/*
- * BigDecimal arithmetic operations should be converted to method calls.
We may also apply this to BigInteger.
+ * BigDecimal/BigInteger arithmetic operations should be converted to
method calls.
*/
public static boolean
shouldConvertArithmeticBinaryToMethodCall(BinaryExpr.Operator operator,
java.lang.reflect.Type leftType, java.lang.reflect.Type rightType) {
- return isArithmeticOperator(operator) &&
(leftType.equals(BigDecimal.class) || rightType.equals(BigDecimal.class));
+ return isArithmeticOperator(operator) &&
(leftType.equals(BigDecimal.class) || rightType.equals(BigDecimal.class) ||
leftType.equals(BigInteger.class) || rightType.equals(BigInteger.class));
}
/*
- * After arithmetic to method call conversion, BigDecimal should take
precedence regardless of left or right. We may also apply this to BigInteger.
+ * After arithmetic to method call conversion, BigDecimal/BigInteger
should take precedence regardless of left or right.
*/
public static java.lang.reflect.Type
getBinaryTypeAfterConversion(java.lang.reflect.Type leftType,
java.lang.reflect.Type rightType) {
- return (leftType.equals(BigDecimal.class) ||
rightType.equals(BigDecimal.class)) ? BigDecimal.class : leftType;
+ if (leftType.equals(BigDecimal.class) ||
rightType.equals(BigDecimal.class)) {
+ return BigDecimal.class;
+ } else if (leftType.equals(BigInteger.class) ||
rightType.equals(BigInteger.class)) {
+ return BigInteger.class;
+ } else {
+ return leftType;
+ }
}
private java.lang.reflect.Type getBinaryType(TypedExpression
leftTypedExpression, TypedExpression rightTypedExpression, Operator operator) {
@@ -906,7 +913,7 @@ public class ExpressionTyper {
RuleContext.FunctionType typedDeclaredFunction =
functionType.get();
methodCallExpr.setScope(null);
- promoteBigDecimalParameters(methodCallExpr, argsType,
typedDeclaredFunction.getArgumentsType().toArray(new Class[0]));
+ promoteBigNumberParameters(methodCallExpr, argsType,
typedDeclaredFunction.getArgumentsType().toArray(new Class[0]));
return new TypedExpressionCursor(methodCallExpr,
typedDeclaredFunction.getReturnType());
}
@@ -917,7 +924,7 @@ public class ExpressionTyper {
}
Class<?>[] actualArgumentTypes = m.getParameterTypes();
- promoteBigDecimalParameters(methodCallExpr, argsType,
actualArgumentTypes);
+ promoteBigNumberParameters(methodCallExpr, argsType,
actualArgumentTypes);
if (methodName.equals("get") &&
List.class.isAssignableFrom(rawClassCursor) && originalTypeCursor instanceof
ParameterizedType) {
return new TypedExpressionCursor(methodCallExpr,
((ParameterizedType) originalTypeCursor).getActualTypeArguments()[0]);
@@ -926,7 +933,7 @@ public class ExpressionTyper {
return new TypedExpressionCursor(methodCallExpr,
actualTypeFromGenerics(originalTypeCursor, m.getGenericReturnType(),
rawClassCursor));
}
- private void promoteBigDecimalParameters(MethodCallExpr methodCallExpr,
Class[] argsType, Class<?>[] actualArgumentTypes) {
+ private void promoteBigNumberParameters(MethodCallExpr methodCallExpr,
Class[] argsType, Class<?>[] actualArgumentTypes) {
if (actualArgumentTypes.length == argsType.length &&
actualArgumentTypes.length == methodCallExpr.getArguments().size()) {
for (int i = 0; i < argsType.length; i++) {
Class<?> argumentType = argsType[i];
@@ -938,7 +945,7 @@ public class ExpressionTyper {
// unbind the original argumentExpression first, otherwise
setArgument() will remove the argumentExpression from
coercedExpression.childrenNodes
// It will result in failing to find DrlNameExpr in AST at
DrlsParseUtil.transformDrlNameExprToNameExpr()
methodCallExpr.replace(argumentExpression, new
NameExpr("placeholder"));
- Expression coercedExpression = new
BigDecimalArgumentCoercion().coercedArgument(argumentType, actualArgumentType,
argumentExpression);
+ Expression coercedExpression = new
BigNumberArgumentCoercion().coercedArgument(argumentType, actualArgumentType,
argumentExpression);
methodCallExpr.setArgument(i, coercedExpression);
}
}
diff --git
a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/bigintegertest/BIFact.java
b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/bigintegertest/BIFact.java
new file mode 100644
index 0000000000..5b4b92f5f5
--- /dev/null
+++
b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/bigintegertest/BIFact.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.drools.model.codegen.execmodel.bigintegertest;
+
+import java.math.BigInteger;
+
+public class BIFact {
+
+ private BigInteger value1;
+ private BigInteger value2;
+
+ public BigInteger getValue1() {
+ return value1;
+ }
+
+ public void setValue1(BigInteger value1) {
+ this.value1 = value1;
+ }
+
+ public BigInteger getValue2() {
+ return value2;
+ }
+
+ public void setValue2(BigInteger value2) {
+ this.value2 = value2;
+ }
+}
diff --git
a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/bigintegertest/BigIntegerTest.java
b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/bigintegertest/BigIntegerTest.java
index d170304868..2896e7bbbd 100644
---
a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/bigintegertest/BigIntegerTest.java
+++
b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/bigintegertest/BigIntegerTest.java
@@ -19,8 +19,12 @@
package org.drools.model.codegen.execmodel.bigintegertest;
import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
import org.drools.model.codegen.execmodel.BaseModelTest;
+import org.drools.model.codegen.execmodel.domain.Person;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.kie.api.runtime.KieSession;
@@ -29,6 +33,342 @@ import static org.assertj.core.api.Assertions.assertThat;
public class BigIntegerTest extends BaseModelTest {
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testBigIntegerGreaterThan(RUN_TYPE runType) {
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + Customer.class.getCanonicalName() + ";\n" +
+ "import " + Policy.class.getCanonicalName() + ";\n" +
+ "import " + BigInteger.class.getCanonicalName() +
";\n" +
+ "rule \"Set Policy Rate\"\n" +
+ "when\n" +
+ "$customer: Customer( $code: code, rate > 0I )\n" +
+ "$policy: Policy( customer == $code, rate == 0I )\n" +
+ "then\n" +
+ "$policy.setRate(new
BigInteger($customer.getRate().toString()));\n" +
+ "update($policy);\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+
+ Customer customer = new Customer();
+ customer.setCode("code1");
+ customer.setRate(new BigInteger("5"));
+ Policy policy = new Policy();
+ policy.setCustomer(customer.getCode());
+ policy.setRate(new BigInteger("0"));
+
+ ksession.insert(customer);
+ ksession.insert(policy);
+ ksession.fireAllRules();
+
+ assertThat(policy.getRate().toString()).isEqualTo("5");
+
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testBigIntegerCompare(RUN_TYPE runType) {
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + Customer.class.getCanonicalName() + ";\n" +
+ "import " + Policy.class.getCanonicalName() + ";\n" +
+ "import " + BigInteger.class.getCanonicalName() +
";\n" +
+ "rule \"Set Policy Rate\"\n" +
+ "when\n" +
+ "$customer: Customer( $code: code, $cr: rate,
$cr.compareTo(new BigInteger(\"0\")) > 0 )\n" +
+ "$policy: Policy( customer == $code, $pr: rate,
$pr.compareTo(new BigInteger(\"0\")) == 0 )\n" +
+ "then\n" +
+ "$policy.setRate(new
BigInteger($customer.getRate().toString()));\n" +
+ "update($policy);\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+
+ Customer customer = new Customer();
+ customer.setCode("code1");
+ customer.setRate(new BigInteger("5"));
+ Policy policy = new Policy();
+ policy.setCustomer(customer.getCode());
+ policy.setRate(new BigInteger("0"));
+
+ ksession.insert(customer);
+ ksession.insert(policy);
+ ksession.fireAllRules();
+
+ assertThat(policy.getRate().toString()).isEqualTo("5");
+
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testBigIntegerEqualsToNull(RUN_TYPE runType) {
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + Customer.class.getCanonicalName() + ";\n" +
+ "import " + BigInteger.class.getCanonicalName() +
";\n" +
+ "rule \"Set Policy Rate\"\n" +
+ "when\n" +
+ "$customer: Customer( rate == value )\n" +
+ "then\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+
+ Customer customer = new Customer();
+
+ ksession.insert(customer);
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testBigIntegerNotEqualsToNull(RUN_TYPE runType) {
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + Customer.class.getCanonicalName() + ";\n" +
+ "import " + BigInteger.class.getCanonicalName() +
";\n" +
+ "rule \"Set Policy Rate\"\n" +
+ "when\n" +
+ "$customer: Customer( rate != value )\n" +
+ "then\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+
+ Customer customer = new Customer();
+ customer.setCode("code1");
+ customer.setRate(new BigInteger("5"));
+
+ ksession.insert(customer);
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testBigIntegerNotEqualsToLiteralNull(RUN_TYPE runType) {
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + Customer.class.getCanonicalName() + ";\n" +
+ "import " + BigInteger.class.getCanonicalName() +
";\n" +
+ "rule \"Set Policy Rate\"\n" +
+ "when\n" +
+ "$customer: Customer( rate != null )\n" +
+ "then\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+
+ Customer customer = new Customer();
+ customer.setCode("code1");
+ customer.setRate(new BigInteger("5"));
+
+ ksession.insert(customer);
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testBigIntegerNotEqualsToLiteralValue(RUN_TYPE runType) {
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + Customer.class.getCanonicalName() + ";\n" +
+ "import " + BigInteger.class.getCanonicalName() +
";\n" +
+ "rule \"Set Policy Rate\"\n" +
+ "when\n" +
+ "$customer: Customer( rate != 1I )\n" +
+ "then\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+
+ Customer customer = new Customer();
+ customer.setCode("code1");
+ customer.setRate(new BigInteger("5"));
+
+ ksession.insert(customer);
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+ }
+
+ @Disabled("Fails with non-exec-model")
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testBigIntegerGreaterThanNull(RUN_TYPE runType) {
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + Customer.class.getCanonicalName() + ";\n" +
+ "import " + BigInteger.class.getCanonicalName() +
";\n" +
+ "rule \"Set Policy Rate\"\n" +
+ "when\n" +
+ "Customer( rate > value )\n" +
+ "then\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+
+ Customer customer = new Customer();
+ customer.setCode("code1");
+ customer.setRate(new BigInteger("5"));
+
+ ksession.insert(customer);
+ assertThat(ksession.fireAllRules()).isEqualTo(0);
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testBigIntegerEquals(RUN_TYPE runType) {
+ // DROOLS-3527
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + Customer.class.getCanonicalName() + ";\n" +
+ "rule R1\n" +
+ "when\n" +
+ "$customer: Customer( rate == 12I )\n" +
+ "then\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+
+ Customer customer = new Customer();
+ customer.setRate(new BigInteger("12"));
+
+ ksession.insert(customer);
+
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testBigIntegerAdd(RUN_TYPE runType) {
+ // RHDM-1635
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + Customer.class.getCanonicalName() + ";\n" +
+ "import " + BigInteger.class.getCanonicalName() +
";\n" +
+ "rule R when\n" +
+ " $customer: Customer( $rate : (rate + 10) == 20 )\n"
+
+ "then\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+
+ Customer c1 = new Customer();
+ c1.setRate(new BigInteger("10"));
+ Customer c2 = new Customer();
+ c2.setRate(new BigInteger("11"));
+
+ ksession.insert(c1);
+ ksession.insert(c2);
+
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testBigIntegerRemainder(RUN_TYPE runType) {
+ // RHDM-1635
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + Customer.class.getCanonicalName() + ";\n" +
+ "import " + BigInteger.class.getCanonicalName() +
";\n" +
+ "rule R when\n" +
+ " $customer: Customer( $rate : (rate % 10) == 0 )\n" +
+ "then\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+
+ Customer c1 = new Customer();
+ c1.setRate(new BigInteger("20"));
+ Customer c2 = new Customer();
+ c2.setRate(new BigInteger("21"));
+
+ ksession.insert(c1);
+ ksession.insert(c2);
+
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+ }
+
+ public static class Order {
+ private BigInteger price;
+ private BigInteger taxRate;
+ private BigInteger tax;
+
+ public BigInteger getPrice() {
+ return price;
+ }
+ public void setPrice(BigInteger price) {
+ this.price = price;
+ }
+ public BigInteger getTaxRate() {
+ return taxRate;
+ }
+ public void setTaxRate(BigInteger taxRate) {
+ this.taxRate = taxRate;
+ }
+ public BigInteger getTax() {
+ return tax;
+ }
+ public void setTax(BigInteger tax) {
+ this.tax= tax;
+ }
+
+ public String toString() {
+ return this.getClass().getName() + "[" +
+ "price=" + price + "," +
+ "taxRate=" + taxRate + "," +
+ "tax=" + tax + "]";
+ }
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testBigIntegerAndStringComparison(RUN_TYPE runType) {
+ // DROOLS-6823
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " +
BigIntegerTest.Order.class.getCanonicalName() + ";\n" +
+ "rule R1 dialect \"mvel\" when\n" +
+ " $o : Order( $price : price )\n" +
+ " String( this == $price )\n" +
+ "then\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+
+ BigIntegerTest.Order order = new BigIntegerTest.Order();
+ order.setPrice(new BigInteger("300"));
+ ksession.insert(order);
+ ksession.insert("300");
+
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testStringAndBigIntegerComparison(RUN_TYPE runType) {
+ // DROOLS-6823
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " +
BigIntegerTest.Order.class.getCanonicalName() + ";\n" +
+ "rule R1 dialect \"mvel\" when\n" +
+ " $s : String()\n" +
+ " $o : Order( price == $s )\n" +
+ "then\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+
+ BigIntegerTest.Order order = new BigIntegerTest.Order();
+ order.setPrice(new BigInteger("300"));
+ ksession.insert(order);
+ ksession.insert("300");
+
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+ }
+
public static class BiHolder {
private BigInteger bi1;
@@ -62,16 +402,99 @@ public class BigIntegerTest extends BaseModelTest {
}
@ParameterizedTest
- @MethodSource("parameters")
+ @MethodSource("parameters")
+ public void testMultiply(RUN_TYPE runType) {
+ testBigIntegerArithmeticOperation(runType, "BiHolder(bi2 == bi1 *
10)", "10", "100");
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testMultiplyWithNegativeValue(RUN_TYPE runType) {
+ testBigIntegerArithmeticOperation(runType, "BiHolder(bi2 == bi1 *
-1)", "10", "-10");
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testMultiplyWithBindVariable(RUN_TYPE runType) {
+ testBigIntegerArithmeticOperation(runType, "BiHolder($bi1 : bi1, bi2
== $bi1 * 10)", "10", "100");
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testMultiplyWithBindVariableWithNegativeValue(RUN_TYPE
runType) {
+ testBigIntegerArithmeticOperation(runType, "BiHolder($bi1 : bi1, bi2
== $bi1 * -1)", "10", "-10");
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testMultiplyWithBindVariableWithNegativeValueEnclosed(RUN_TYPE
runType) {
+ testBigIntegerArithmeticOperation(runType, "BiHolder($bi1 : bi1, bi2
== $bi1 * (-1))", "10", "-10");
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void
testMultiplyWithBindVariableWithNegativeValueEnclosedBoth(RUN_TYPE runType) {
+ testBigIntegerArithmeticOperation(runType, "BiHolder($bi1 : bi1, bi2
== ($bi1 * -1))", "10", "-10");
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void
testMultiplyWithBindVariableWithNegativeValueEnclosedNest(RUN_TYPE runType) {
+ testBigIntegerArithmeticOperation(runType, "BiHolder($bi1 : bi1, bi2
== ($bi1 * (-1)))", "10", "-10");
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testAddWithBindVariable(RUN_TYPE runType) {
+ testBigIntegerArithmeticOperation(runType, "BiHolder($bi1 : bi1, bi2
== $bi1 + 10)", "10", "20");
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testSubtractWithBindVariable(RUN_TYPE runType) {
+ testBigIntegerArithmeticOperation(runType, "BiHolder($bi1 : bi1, bi2
== $bi1 - 10)", "10", "0");
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testDivideWithBindVariable(RUN_TYPE runType) {
+ testBigIntegerArithmeticOperation(runType, "BiHolder($bi1 : bi1, bi2
== $bi1 / 10)", "10", "1");
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testModWithBindVariable(RUN_TYPE runType) {
+ testBigIntegerArithmeticOperation(runType, "BiHolder($bi1 : bi1, bi2
== $bi1 % 10)", "10", "0");
+ }
+
+ private void testBigIntegerArithmeticOperation(RUN_TYPE runType, String
pattern, String bi1, String bi2) {
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " +
BigIntegerTest.BiHolder.class.getCanonicalName() + ";\n" +
+ "rule R1 dialect \"mvel\" when\n" +
+ pattern + "\n" +
+ "then\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+
+ BigIntegerTest.BiHolder holder = new BigIntegerTest.BiHolder(new
BigInteger(bi1), new BigInteger(bi2));
+ ksession.insert(holder);
+
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
public void testBigIntegerLiteralLhsNegative(RUN_TYPE runType) {
// DROOLS-6596
String str =
"package org.drools.modelcompiler.bigintegerss\n" +
- "import " + BiHolder.class.getCanonicalName() + ";\n" +
- "rule R1 dialect \"mvel\" when\n" +
- " $holder : BiHolder(bi1 > -10I)\n" +
- "then\n" +
- "end";
+ "import " + BiHolder.class.getCanonicalName() + ";\n" +
+ "rule R1 dialect \"mvel\" when\n" +
+ " $holder : BiHolder(bi1 > -10I)\n" +
+ "then\n" +
+ "end";
KieSession ksession = getKieSession(runType, str);
@@ -84,17 +507,17 @@ public class BigIntegerTest extends BaseModelTest {
}
@ParameterizedTest
- @MethodSource("parameters")
+ @MethodSource("parameters")
public void testBigIntegerLiteralRhsNegative(RUN_TYPE runType) {
// DROOLS-6596
String str =
- "package org.drools.modelcompiler.bigdecimals\n" +
- "import " + BiHolder.class.getCanonicalName() + ";\n" +
- "rule R1 dialect \"mvel\" when\n" +
- " $holder : BiHolder()\n" +
- "then\n" +
- " $holder.bi1 = -10I;\n" +
- "end";
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + BiHolder.class.getCanonicalName() + ";\n" +
+ "rule R1 dialect \"mvel\" when\n" +
+ " $holder : BiHolder()\n" +
+ "then\n" +
+ " $holder.bi1 = -10I;\n" +
+ "end";
KieSession ksession = getKieSession(runType, str);
@@ -104,4 +527,318 @@ public class BigIntegerTest extends BaseModelTest {
assertThat(holder.getBi1()).isEqualTo(new BigInteger("-10"));
}
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testBigIntegerLiteralWithBinding(RUN_TYPE runType) {
+ // DROOLS-6936
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " +
BigIntegerTest.BiHolder.class.getCanonicalName() + ";\n" +
+ "global java.util.List result;\n" +
+ "rule R1 dialect \"mvel\"\n" +
+ "when\n" +
+ " $holder : BiHolder($bi1 : bi1, $zero : 0I)\n" +
+ "then\n" +
+ " result.add($zero);\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+ List<BigInteger> result = new ArrayList<>();
+ ksession.setGlobal("result", result);
+
+ BigIntegerTest.BiHolder holder = new BigIntegerTest.BiHolder();
+ holder.setBi1(new BigInteger("10"));
+ ksession.insert(holder);
+ ksession.fireAllRules();
+
+ assertThat(result).containsExactly(new BigInteger("0"));
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void testModifyWithNegativeBigInteger(RUN_TYPE runType) {
+ // DROOLS-7324
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " +
BigIntegerTest.BiHolder.class.getCanonicalName() + ";\n" +
+ "global java.util.List result;\n" +
+ "rule R1 dialect \"mvel\" when\n" +
+ " $bd : BiHolder(bi1 > 5)\n" +
+ "then\n" +
+ " modify($bd) { bi1 = -1 }\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+ List<BigInteger> result = new ArrayList<>();
+ ksession.setGlobal("result", result);
+
+ BigIntegerTest.BiHolder holder = new BigIntegerTest.BiHolder();
+ holder.setBi1(new BigInteger("10"));
+ ksession.insert(holder);
+ int fires = ksession.fireAllRules();
+
+ assertThat(fires).isEqualTo(1);
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void bigIntegerArithmeticInMethodCallScope(RUN_TYPE runType) {
+ // DROOLS-7364
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + Customer.class.getCanonicalName() + ";\n" +
+ "import " + BigInteger.class.getCanonicalName() +
";\n" +
+ "global java.util.List result;\n" +
+ "rule \"Rule 1a\"\n" +
+ " when\n" +
+ " Customer( $ans : (rate * new
BigInteger(\"1000\")).longValue() )\n" +
+ " then\n" +
+ " result.add($ans);\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+ List<Long> result = new ArrayList<>();
+ ksession.setGlobal("result", result);
+
+ Customer customer = new Customer();
+ customer.setRate(new BigInteger("2"));
+ ksession.insert(customer);
+ ksession.fireAllRules();
+
+ assertThat(result).contains(2000L);
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void
bigIntegerArithmeticInMethodCallScopeInMethodCallArgument(RUN_TYPE runType) {
+ // DROOLS-7364
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + Customer.class.getCanonicalName() + ";\n" +
+ "import " + BigInteger.class.getCanonicalName() +
";\n" +
+ "global java.util.List result;\n" +
+ "rule \"Rule 1a\"\n" +
+ " when\n" +
+ " Customer( $ans : String.format(\"%,d\", (rate
* new BigInteger(\"1000\")).longValue()) )\n" +
+ " then\n" +
+ " result.add($ans);\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+ List<String> result = new ArrayList<>();
+ ksession.setGlobal("result", result);
+
+ Customer customer = new Customer();
+ customer.setRate(new BigInteger("2"));
+ ksession.insert(customer);
+ ksession.fireAllRules();
+
+ assertThat(result).contains("2,000");
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void
nonBigIntegerArithmeticInMethodCallScopeInMethodCallArgument(RUN_TYPE runType) {
+ // DROOLS-7364
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + Customer.class.getCanonicalName() + ";\n" +
+ "import " + BigInteger.class.getCanonicalName() +
";\n" +
+ "global java.util.List result;\n" +
+ "rule \"Rule 1a\"\n" +
+ " when\n" +
+ " Customer( $ans : String.format(\"%,d\",
(longValue * Long.valueOf(1000L)).longValue()) )\n" +
+ " then\n" +
+ " result.add($ans);\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+ List<String> result = new ArrayList<>();
+ ksession.setGlobal("result", result);
+
+ Customer customer = new Customer();
+ customer.setLongValue(2L);
+ ksession.insert(customer);
+ ksession.fireAllRules();
+
+ assertThat(result).contains("2,000");
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void
bigIntegerArithmeticInMethodCallArgumentWithoutEnclosedExpr(RUN_TYPE runType) {
+ // DROOLS-7364
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + Customer.class.getCanonicalName() + ";\n" +
+ "import " +
BigIntegerTest.Util.class.getCanonicalName() + ";\n" +
+ "import " + BigInteger.class.getCanonicalName() +
";\n" +
+ "global java.util.List result;\n" +
+ "rule \"Rule 1a\"\n" +
+ " when\n" +
+ " Customer( $ans : Util.getString(\"%,d\", rate
* new BigInteger(\"1000\")) )\n" +
+ " then\n" +
+ " result.add($ans);\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+ List<String> result = new ArrayList<>();
+ ksession.setGlobal("result", result);
+
+ Customer customer = new Customer();
+ customer.setRate(new BigInteger("2"));
+ ksession.insert(customer);
+ ksession.fireAllRules();
+
+ assertThat(result).contains("2,000");
+ }
+
+ public static class Util {
+
+ public static String getString(String format, BigInteger bd) {
+ return String.format("%,d", bd.longValue());
+ }
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void
bigIntegerCoercionInMethodArgument_shouldNotFailToBuild(RUN_TYPE runType) {
+ // KIE-748
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + BIFact.class.getCanonicalName() + ";\n" +
+ "import static " +
BigIntegerTest.class.getCanonicalName() + ".intToString;\n" +
+ "rule \"Rule 1a\"\n" +
+ " when\n" +
+ " BIFact( intToString(value2 - 1) == \"2\" )\n"
+
+ " then\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+
+ BIFact biFact = new BIFact();
+ biFact.setValue2(new BigInteger("3"));
+
+ ksession.insert(biFact);
+
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void
bigIntegerCoercionInNestedMethodArgument_shouldNotFailToBuild(RUN_TYPE runType)
{
+ // KIE-748
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + BIFact.class.getCanonicalName() + ";\n" +
+ "import static " +
BigIntegerTest.class.getCanonicalName() + ".intToString;\n" +
+ "rule \"Rule 1a\"\n" +
+ " when\n" +
+ " BIFact( intToString(value1 * (value2 - 1)) ==
\"20\" )\n" +
+ " then\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+
+ BIFact biFact = new BIFact();
+ biFact.setValue1(new BigInteger("10"));
+ biFact.setValue2(new BigInteger("3"));
+
+ ksession.insert(biFact);
+
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+ }
+
+ public static String intToString(int value) {
+ return Integer.toString(value);
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void
bindVariableToBigIntegerCoercion2Operands_shouldBindCorrectResult(RUN_TYPE
runType) {
+ bindVariableToBigIntegerCoercion(runType, "$var : (1000 * value1)");
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void
bindVariableToBigIntegerCoercion3Operands_shouldBindCorrectResult(RUN_TYPE
runType) {
+ bindVariableToBigIntegerCoercion(runType, "$var : (100000 * value1 /
100)");
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void
bindVariableToBigIntegerCoercion3OperandsWithParentheses_shouldBindCorrectResult(RUN_TYPE
runType) {
+ bindVariableToBigIntegerCoercion(runType, "$var : ((100000 * value1) /
100)");
+ }
+
+ private void bindVariableToBigIntegerCoercion(RUN_TYPE runType, String
binding) {
+ // KIE-775
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + BIFact.class.getCanonicalName() + ";\n" +
+ "global java.util.List result;\n" +
+ "rule R1\n" +
+ " when\n" +
+ " BIFact( " + binding + " )\n" +
+ " then\n" +
+ " result.add($var);\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+ List<BigInteger> result = new ArrayList<>();
+ ksession.setGlobal("result", result);
+
+ BIFact biFact = new BIFact();
+ biFact.setValue1(new BigInteger("80"));
+
+ ksession.insert(biFact);
+ ksession.fireAllRules();
+
+ assertThat(result).contains(new BigInteger("80000"));
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void bigIntegerInWithInt_shouldNotFailToBuild(RUN_TYPE runType) {
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + BIFact.class.getCanonicalName() + ";\n" +
+ "rule \"Rule 1a\"\n" +
+ " when\n" +
+ " BIFact( value1 in (100, 200) )\n" +
+ " then\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+
+ BIFact biFact = new BIFact();
+ biFact.setValue1(new BigInteger("100"));
+
+ ksession.insert(biFact);
+
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+ }
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void bigIntegerInWithBI_shouldNotFailToBuild(RUN_TYPE runType) {
+ String str =
+ "package org.drools.modelcompiler.bigintegers\n" +
+ "import " + BIFact.class.getCanonicalName() + ";\n" +
+ "rule \"Rule 1a\"\n" +
+ " when\n" +
+ " BIFact( value1 in (100I, 200I) )\n" +
+ " then\n" +
+ "end";
+
+ KieSession ksession = getKieSession(runType, str);
+
+ BIFact biFact = new BIFact();
+ biFact.setValue1(new BigInteger("100"));
+
+ ksession.insert(biFact);
+
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+ }
}
diff --git
a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/bigintegertest/Customer.java
b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/bigintegertest/Customer.java
new file mode 100644
index 0000000000..9c845256b4
--- /dev/null
+++
b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/bigintegertest/Customer.java
@@ -0,0 +1,64 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.drools.model.codegen.execmodel.bigintegertest;
+
+import java.math.BigInteger;
+
+public class Customer {
+
+ private String code;
+
+ private BigInteger rate;
+ private BigInteger value;
+
+ private Long longValue;
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public BigInteger getRate() {
+ return rate;
+ }
+
+ public void setRate(BigInteger rate) {
+ this.rate = rate;
+ }
+
+ public BigInteger getValue() {
+ return value;
+ }
+
+ public void setValue( BigInteger value ) {
+ this.value = value;
+ }
+
+ public Long getLongValue() {
+ return longValue;
+ }
+
+ public void setLongValue(Long longValue) {
+ this.longValue = longValue;
+ }
+
+}
diff --git
a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/bigintegertest/Policy.java
b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/bigintegertest/Policy.java
new file mode 100644
index 0000000000..6399259b89
--- /dev/null
+++
b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/bigintegertest/Policy.java
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.drools.model.codegen.execmodel.bigintegertest;
+
+import java.math.BigInteger;
+
+public class Policy {
+
+ private String customer;
+
+ private BigInteger rate;
+
+ public String getCustomer() {
+ return customer;
+ }
+
+ public void setCustomer(String customer) {
+ this.customer = customer;
+ }
+
+ public BigInteger getRate() {
+ return rate;
+ }
+
+ public void setRate(BigInteger rate) {
+ this.rate = rate;
+ }
+}
diff --git
a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/LHSPhase.java
b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/LHSPhase.java
index f610dc412f..13b56ec06f 100644
---
a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/LHSPhase.java
+++
b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/LHSPhase.java
@@ -21,6 +21,7 @@ package org.drools.mvelcompiler;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.math.BigDecimal;
+import java.math.BigInteger;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -44,6 +45,8 @@ import org.drools.mvel.parser.ast.visitor.DrlGenericVisitor;
import org.drools.mvelcompiler.ast.AssignExprT;
import org.drools.mvelcompiler.ast.BigDecimalArithmeticExprT;
import org.drools.mvelcompiler.ast.BigDecimalConvertedExprT;
+import org.drools.mvelcompiler.ast.BigIntegerArithmeticExprT;
+import org.drools.mvelcompiler.ast.BigIntegerConvertedExprT;
import org.drools.mvelcompiler.ast.BinaryExprT;
import org.drools.mvelcompiler.ast.ExpressionStmtT;
import org.drools.mvelcompiler.ast.FieldToAccessorTExpr;
@@ -157,10 +160,10 @@ public class LHSPhase implements
DrlGenericVisitor<TypedExpression, Void> {
}
- // Conversion of AssignExpr to BigDecimal Arithmetic operation when LHS is
is a BigDecimal variable
- public Optional<TypedExpression> withBigDecimalConversion(AssignExpr
assignExpr,
- TypedExpression
target,
- TypedExpression
value) {
+ // Conversion of AssignExpr to BigDecimal/BigInteger Arithmetic operation
when LHS is a BigDecimal/BigInteger variable
+ public Optional<TypedExpression> withBigNumberConversion(AssignExpr
assignExpr,
+ TypedExpression
target,
+ TypedExpression
value) {
Optional<Type> optRHSType = value.getType();
if(!optRHSType.isPresent()) {
@@ -173,10 +176,16 @@ public class LHSPhase implements
DrlGenericVisitor<TypedExpression, Void> {
}
boolean assigningToFieldAccess = target instanceof
FieldToAccessorTExpr; // handled previously in FieldAccessExpr visitor
- if (!assigningToFieldAccess && target.getType().filter(t -> t ==
BigDecimal.class).isPresent()) {
- String bigDecimalMethod =
BigDecimalArithmeticExprT.toBigDecimalMethod(operator);
- BigDecimalArithmeticExprT convertedBigDecimalExpr = new
BigDecimalArithmeticExprT(bigDecimalMethod, target, value);
- return Optional.of(new AssignExprT(AssignExpr.Operator.ASSIGN,
target, convertedBigDecimalExpr));
+ if (!assigningToFieldAccess) {
+ if (target.getType().filter(t -> t ==
BigDecimal.class).isPresent()) {
+ String bigDecimalMethod =
BigDecimalArithmeticExprT.toBigDecimalMethod(operator);
+ BigDecimalArithmeticExprT convertedBigDecimalExpr = new
BigDecimalArithmeticExprT(bigDecimalMethod, target, value);
+ return Optional.of(new AssignExprT(AssignExpr.Operator.ASSIGN,
target, convertedBigDecimalExpr));
+ } else if (target.getType().filter(t -> t ==
BigInteger.class).isPresent()) {
+ String bigIntegerMethod =
BigIntegerArithmeticExprT.toBigIntegerMethod(operator);
+ BigIntegerArithmeticExprT convertedBigIntegerExpr = new
BigIntegerArithmeticExprT(bigIntegerMethod, target, value);
+ return Optional.of(new AssignExprT(AssignExpr.Operator.ASSIGN,
target, convertedBigIntegerExpr));
+ }
}
return Optional.empty();
}
@@ -195,6 +204,8 @@ public class LHSPhase implements
DrlGenericVisitor<TypedExpression, Void> {
return new FieldToAccessorTExpr(fieldAccessScope, setter,
singletonList(rhsOrError()));
} else if(setter.getParameterTypes()[0] == BigDecimal.class) {
return bigDecimalCompoundOperator(fieldAccessScope,
accessorName, scopeType, parentOperator, setter);
+ } else if(setter.getParameterTypes()[0] == BigInteger.class) {
+ return bigIntegerCompoundOperator(fieldAccessScope,
accessorName, scopeType, parentOperator, setter);
} else {
return compoundOperator(fieldAccessScope, accessorName,
scopeType, parentOperator, setter);
}
@@ -225,6 +236,25 @@ public class LHSPhase implements
DrlGenericVisitor<TypedExpression, Void> {
return new FieldToAccessorTExpr(fieldAccessScope, setter,
singletonList(bigDecimalArithmeticExprT));
}
+ private FieldToAccessorTExpr bigIntegerCompoundOperator(TypedExpression
fieldAccessScope,
+ String
accessorName,
+ Class<?> scopeType,
+
AssignExpr.Operator parentOperator,
+ Method setter) {
+ String bigIntegerArithmeticMethod =
BigIntegerArithmeticExprT.toBigIntegerMethod(parentOperator);
+
+ Method optGetter = ofNullable(getAccessor(scopeType, accessorName))
+ .orElseThrow(() -> new MvelCompilerException("No getter found
but setter is present for accessor: " + accessorName));
+
+ FieldToAccessorTExpr getterExpression = new
FieldToAccessorTExpr(fieldAccessScope, optGetter, emptyList());
+ TypedExpression argument = rhsOrError();
+ if(argument.getType().filter(t -> t != BigInteger.class).isPresent()) {
+ argument = new BigIntegerConvertedExprT(argument);
+ }
+ BigIntegerArithmeticExprT bigIntegerArithmeticExprT = new
BigIntegerArithmeticExprT(bigIntegerArithmeticMethod, getterExpression,
argument);
+ return new FieldToAccessorTExpr(fieldAccessScope, setter,
singletonList(bigIntegerArithmeticExprT));
+ }
+
/**
Conversion of the compound operator applied to number literals
$p.age += 50;
@@ -330,7 +360,7 @@ public class LHSPhase implements
DrlGenericVisitor<TypedExpression, Void> {
TypedExpression target = n.getTarget().accept(this, arg);
Optional<TypedExpression> bigDecimalConversion =
- withBigDecimalConversion(n, target, rhsOrError());
+ withBigNumberConversion(n, target, rhsOrError());
if(bigDecimalConversion.isPresent()) {
return bigDecimalConversion.get();
diff --git
a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/RHSPhase.java
b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/RHSPhase.java
index ef02635054..5fcbbfb6ff 100644
---
a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/RHSPhase.java
+++
b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/RHSPhase.java
@@ -22,6 +22,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.math.BigDecimal;
+import java.math.BigInteger;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@@ -61,7 +62,9 @@ import org.drools.mvel.parser.ast.visitor.DrlGenericVisitor;
import org.drools.mvelcompiler.ast.BigDecimalArithmeticExprT;
import org.drools.mvelcompiler.ast.BigDecimalConvertedExprT;
import org.drools.mvelcompiler.ast.BigDecimalRelationalExprT;
+import org.drools.mvelcompiler.ast.BigIntegerArithmeticExprT;
import org.drools.mvelcompiler.ast.BigIntegerConvertedExprT;
+import org.drools.mvelcompiler.ast.BigIntegerRelationalExprT;
import org.drools.mvelcompiler.ast.BinaryExprT;
import org.drools.mvelcompiler.ast.BooleanLiteralExpressionT;
import org.drools.mvelcompiler.ast.CastExprT;
@@ -90,6 +93,7 @@ import org.drools.util.MethodUtils.NullType;
import static java.util.Optional.ofNullable;
import static
org.drools.mvelcompiler.ast.BigDecimalArithmeticExprT.toBigDecimalMethod;
+import static
org.drools.mvelcompiler.ast.BigIntegerArithmeticExprT.toBigIntegerMethod;
import static org.drools.mvelcompiler.util.OptionalUtils.map2;
import static org.drools.util.ClassUtils.classFromType;
import static org.drools.util.ClassUtils.getAccessor;
@@ -261,10 +265,10 @@ public class RHSPhase implements
DrlGenericVisitor<TypedExpression, VisitorConte
public TypedExpression visit(BinaryExpr n, VisitorContext arg) {
TypedExpression left = n.getLeft().accept(this, arg);
TypedExpression right = n.getRight().accept(this, arg);
- return withPossiblyBigDecimalConversion(left, right, n.getOperator());
+ return withPossiblyBigNumberConversion(left, right, n.getOperator());
}
- private TypedExpression withPossiblyBigDecimalConversion(TypedExpression
left, TypedExpression right, BinaryExpr.Operator operator) {
+ private TypedExpression withPossiblyBigNumberConversion(TypedExpression
left, TypedExpression right, BinaryExpr.Operator operator) {
Optional<Type> optTypeLeft = left.getType();
Optional<Type> optTypeRight = right.getType();
@@ -279,7 +283,7 @@ public class RHSPhase implements
DrlGenericVisitor<TypedExpression, VisitorConte
(typeLeft == String.class || typeRight == String.class);
if (arithmeticOperators.contains(operator) && !isStringConcatenation) {
- return convertToBigDecimalArithmeticExprTIfNeeded(left, right,
operator, typeLeft, typeRight);
+ return convertToBigNumberArithmeticExprTIfNeeded(left, right,
operator, typeLeft, typeRight);
} else if (relationalOperators.contains(operator)) {
return convertToBigDecimalRelationalExprTIfNeeded(left, right,
operator, typeLeft, typeRight);
}
@@ -287,13 +291,19 @@ public class RHSPhase implements
DrlGenericVisitor<TypedExpression, VisitorConte
return new BinaryExprT(left, right, operator);
}
- private TypedExpression
convertToBigDecimalArithmeticExprTIfNeeded(TypedExpression left,
TypedExpression right, BinaryExpr.Operator operator, Type typeLeft, Type
typeRight) {
+ private TypedExpression
convertToBigNumberArithmeticExprTIfNeeded(TypedExpression left, TypedExpression
right, BinaryExpr.Operator operator, Type typeLeft, Type typeRight) {
if (typeLeft == BigDecimal.class && typeRight == BigDecimal.class) {
// do not convert
return new BigDecimalArithmeticExprT(toBigDecimalMethod(operator),
left, right);
} else if (typeLeft != BigDecimal.class && typeRight ==
BigDecimal.class) { // convert left
return new BigDecimalArithmeticExprT(toBigDecimalMethod(operator),
new BigDecimalConvertedExprT(left), right);
} else if (typeLeft == BigDecimal.class && typeRight !=
BigDecimal.class) { // convert right
return new BigDecimalArithmeticExprT(toBigDecimalMethod(operator),
left, new BigDecimalConvertedExprT(right));
+ } else if (typeLeft == BigInteger.class && typeRight ==
BigInteger.class) { // do not convert
+ return new BigIntegerArithmeticExprT(toBigIntegerMethod(operator),
left, right);
+ } else if (typeLeft != BigInteger.class && typeRight ==
BigInteger.class) { // convert left
+ return new BigIntegerArithmeticExprT(toBigIntegerMethod(operator),
new BigIntegerConvertedExprT(left), right);
+ } else if (typeLeft == BigInteger.class && typeRight !=
BigInteger.class) { // convert right
+ return new BigIntegerArithmeticExprT(toBigIntegerMethod(operator),
left, new BigIntegerConvertedExprT(right));
} else {
return new BinaryExprT(left, right, operator);
}
@@ -306,6 +316,12 @@ public class RHSPhase implements
DrlGenericVisitor<TypedExpression, VisitorConte
return new BigDecimalRelationalExprT(operator, new
BigDecimalConvertedExprT(left), right);
} else if (typeLeft == BigDecimal.class && typeRight !=
BigDecimal.class) { // convert right
return new BigDecimalRelationalExprT(operator, left, new
BigDecimalConvertedExprT(right));
+ } else if (typeLeft == BigInteger.class && typeRight ==
BigInteger.class) { // do not convert
+ return new BigIntegerRelationalExprT(operator, left, right);
+ } else if (typeLeft != BigInteger.class && typeRight ==
BigInteger.class) { // convert left
+ return new BigIntegerRelationalExprT(operator, new
BigIntegerConvertedExprT(left), right);
+ } else if (typeLeft == BigInteger.class && typeRight !=
BigInteger.class) { // convert right
+ return new BigIntegerRelationalExprT(operator, left, new
BigIntegerConvertedExprT(right));
} else {
return new BinaryExprT(left, right, operator);
}
diff --git
a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ReProcessRHSPhase.java
b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ReProcessRHSPhase.java
index 4221b92c85..eee816bdd9 100644
---
a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ReProcessRHSPhase.java
+++
b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ReProcessRHSPhase.java
@@ -18,7 +18,9 @@
*/
package org.drools.mvelcompiler;
+import java.lang.reflect.Type;
import java.math.BigDecimal;
+import java.math.BigInteger;
import java.util.Optional;
import java.util.function.Supplier;
@@ -31,6 +33,7 @@ import com.github.javaparser.ast.expr.NameExpr;
import com.github.javaparser.ast.expr.UnaryExpr;
import org.drools.mvel.parser.ast.visitor.DrlGenericVisitor;
import org.drools.mvelcompiler.ast.BigDecimalConvertedExprT;
+import org.drools.mvelcompiler.ast.BigIntegerConvertedExprT;
import org.drools.mvelcompiler.ast.DoubleLiteralExpressionT;
import org.drools.mvelcompiler.ast.IntegerLiteralExpressionT;
import org.drools.mvelcompiler.ast.LongLiteralExpressionT;
@@ -80,39 +83,46 @@ public class ReProcessRHSPhase implements
DrlGenericVisitor<Optional<TypedExpres
@Override
public Optional<TypedExpression> visit(BinaryExpr n,
ReProcessRHSPhase.Context context) {
- return convertWhenLHSISBigDecimal(() -> new
UnalteredTypedExpression(n), context);
+ return convertWhenLHSIsBigNumber(() -> new
UnalteredTypedExpression(n), context);
}
@Override
public Optional<TypedExpression> visit(IntegerLiteralExpr n,
ReProcessRHSPhase.Context context) {
- return convertWhenLHSISBigDecimal(() -> new
IntegerLiteralExpressionT(n), context);
+ return convertWhenLHSIsBigNumber(() -> new
IntegerLiteralExpressionT(n), context);
}
@Override
public Optional<TypedExpression> visit(DoubleLiteralExpr n,
ReProcessRHSPhase.Context context) {
- return convertWhenLHSISBigDecimal(() -> new
DoubleLiteralExpressionT(n), context);
+ return convertWhenLHSIsBigNumber(() -> new
DoubleLiteralExpressionT(n), context);
}
@Override
public Optional<TypedExpression> visit(LongLiteralExpr n,
ReProcessRHSPhase.Context context) {
- return convertWhenLHSISBigDecimal(() -> new LongLiteralExpressionT(n),
context);
+ return convertWhenLHSIsBigNumber(() -> new LongLiteralExpressionT(n),
context);
}
@Override
public Optional<TypedExpression> visit(NameExpr n,
ReProcessRHSPhase.Context context) {
if(mvelCompilerContext
.findDeclarations(n.toString())
- .filter(d -> d.getClazz() != BigDecimal.class)
- .isPresent()) { // avoid wrapping BigDecimal declarations
- return convertWhenLHSISBigDecimal(() -> new
UnalteredTypedExpression(n), context);
+ .filter(d -> d.getClazz() != BigDecimal.class && d.getClazz()
!= BigInteger.class)
+ .isPresent()) { // avoid wrapping BigDecimal/BigInteger
declarations
+ return convertWhenLHSIsBigNumber(() -> new
UnalteredTypedExpression(n), context);
} else {
return Optional.empty();
}
}
- private Optional<TypedExpression>
convertWhenLHSISBigDecimal(Supplier<TypedExpression> conversionFunction,
ReProcessRHSPhase.Context context) {
- return lhs.getType()
- .filter(BigDecimal.class::equals)
- .flatMap(t -> Optional.of(new
BigDecimalConvertedExprT(conversionFunction.get(), context.getUnaryExpr())));
+ private Optional<TypedExpression>
convertWhenLHSIsBigNumber(Supplier<TypedExpression> conversionFunction,
ReProcessRHSPhase.Context context) {
+ Optional<Type> typeOpt = lhs.getType();
+ if (typeOpt.isPresent()) {
+ Type lhsType = typeOpt.get();
+ if (lhsType.equals(BigDecimal.class)) {
+ return Optional.of(new
BigDecimalConvertedExprT(conversionFunction.get(), context.getUnaryExpr()));
+ } else if (lhsType.equals(BigInteger.class)) {
+ return Optional.of(new
BigIntegerConvertedExprT(conversionFunction.get(), context.getUnaryExpr()));
+ }
+ }
+ return Optional.empty();
}
}
diff --git
a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/BigDecimalConvertedExprT.java
b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/BigDecimalConvertedExprT.java
index 9e52e87ceb..d3d57565fa 100644
---
a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/BigDecimalConvertedExprT.java
+++
b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/BigDecimalConvertedExprT.java
@@ -60,7 +60,7 @@ public class BigDecimalConvertedExprT implements
TypedExpression {
@Override
public String toString() {
- return "BigDecimalConstantExprT{" +
+ return "BigDecimalConvertedExprT{" +
"value=" + value +
'}';
}
diff --git
a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/BigIntegerArithmeticExprT.java
b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/BigIntegerArithmeticExprT.java
new file mode 100644
index 0000000000..e5386de95e
--- /dev/null
+++
b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/BigIntegerArithmeticExprT.java
@@ -0,0 +1,101 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.drools.mvelcompiler.ast;
+
+import java.lang.reflect.Type;
+import java.math.BigInteger;
+import java.util.Optional;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.AssignExpr;
+import com.github.javaparser.ast.expr.BinaryExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+
+import static com.github.javaparser.ast.NodeList.nodeList;
+
+public class BigIntegerArithmeticExprT implements TypedExpression {
+
+ private final String name;
+ private final TypedExpression argument;
+ private final TypedExpression scope;
+ private final Type type = BigInteger.class;
+
+ public static String toBigIntegerMethod(BinaryExpr.Operator operator) {
+ switch (operator) {
+ case PLUS: // +
+ return "add";
+ case MINUS: // -
+ return "subtract";
+ case MULTIPLY: // *
+ return "multiply";
+ case DIVIDE: // /
+ return "divide";
+ case REMAINDER: // %
+ return "remainder";
+ }
+ throw new RuntimeException("Unknown operator");
+ }
+
+ public static String toBigIntegerMethod(AssignExpr.Operator operator) {
+ switch (operator) {
+ case PLUS: // +=
+ return "add";
+ case MINUS: // -=
+ return "subtract";
+ case MULTIPLY: // *=
+ return "multiply";
+ case DIVIDE: // /=
+ return "divide";
+ case ASSIGN: // =
+ return "valueOf";
+ }
+ throw new RuntimeException("Unknown operator");
+ }
+
+ public BigIntegerArithmeticExprT(String bigIntegerMethod,
+ TypedExpression scope,
+ TypedExpression argument) {
+ this.name = bigIntegerMethod;
+ this.scope = scope;
+ this.argument = argument;
+ }
+
+ @Override
+ public Optional<Type> getType() {
+ return Optional.of(type);
+ }
+
+ @Override
+ public Node toJavaExpression() {
+ MethodCallExpr methodCallExpr = new MethodCallExpr((Expression)
scope.toJavaExpression(), name,
+ nodeList((Expression) argument.toJavaExpression()));
+ return methodCallExpr;
+ }
+
+ @Override
+ public String toString() {
+ return "BigIntegerArithmeticExprT{" +
+ "name='" + name + '\'' +
+ ", argument=" + argument +
+ ", scope=" + scope +
+ ", type=" + type +
+ '}';
+ }
+}
diff --git
a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/BigIntegerConvertedExprT.java
b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/BigIntegerConvertedExprT.java
index e71baa830a..8eb423280b 100644
---
a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/BigIntegerConvertedExprT.java
+++
b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/BigIntegerConvertedExprT.java
@@ -25,7 +25,12 @@ import java.util.Optional;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.expr.LiteralStringValueExpr;
+import com.github.javaparser.ast.expr.LongLiteralExpr;
import com.github.javaparser.ast.expr.ObjectCreationExpr;
+import com.github.javaparser.ast.expr.StringLiteralExpr;
+import com.github.javaparser.ast.expr.UnaryExpr;
import static com.github.javaparser.ast.NodeList.nodeList;
@@ -34,8 +39,15 @@ public class BigIntegerConvertedExprT implements
TypedExpression {
private final TypedExpression value;
private final Type type = BigInteger.class;
+ private final Optional<UnaryExpr> unaryExpr;
+
public BigIntegerConvertedExprT(TypedExpression value) {
+ this(value, Optional.empty());
+ }
+
+ public BigIntegerConvertedExprT(TypedExpression value, Optional<UnaryExpr>
unaryExpr) {
this.value = value;
+ this.unaryExpr = unaryExpr;
}
@Override
@@ -46,9 +58,22 @@ public class BigIntegerConvertedExprT implements
TypedExpression {
@Override
public Node toJavaExpression() {
+ Expression expr = (Expression) value.toJavaExpression();
+ Expression arg = unaryExpr.map(u -> (Expression) new UnaryExpr(expr,
u.getOperator())).orElse(expr);
+ arg = convertToStringLiteralExprIfPossible(arg);
return new ObjectCreationExpr(null,
StaticJavaParser.parseClassOrInterfaceType(type.getTypeName()),
- nodeList((Expression)
value.toJavaExpression()));
+ nodeList(arg));
+ }
+
+ private Expression convertToStringLiteralExprIfPossible(Expression expr) {
+ // use BigInterger(String) constructor
+ if (expr instanceof IntegerLiteralExpr || expr instanceof
LongLiteralExpr) {
+ return new StringLiteralExpr(((LiteralStringValueExpr)
expr).getValue());
+ } else if (expr instanceof UnaryExpr newUnaryExpr) {
+ return new StringLiteralExpr(newUnaryExpr.toString());
+ }
+ return expr;
}
@Override
diff --git
a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/BigIntegerConvertedExprT.java
b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/BigIntegerRelationalExprT.java
similarity index 54%
copy from
drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/BigIntegerConvertedExprT.java
copy to
drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/BigIntegerRelationalExprT.java
index e71baa830a..5527cebd96 100644
---
a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/BigIntegerConvertedExprT.java
+++
b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/BigIntegerRelationalExprT.java
@@ -22,20 +22,27 @@ import java.lang.reflect.Type;
import java.math.BigInteger;
import java.util.Optional;
-import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.BinaryExpr;
import com.github.javaparser.ast.expr.Expression;
-import com.github.javaparser.ast.expr.ObjectCreationExpr;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.expr.MethodCallExpr;
import static com.github.javaparser.ast.NodeList.nodeList;
-public class BigIntegerConvertedExprT implements TypedExpression {
+public class BigIntegerRelationalExprT implements TypedExpression {
- private final TypedExpression value;
+ private final BinaryExpr.Operator operator;
+ private final TypedExpression argument;
+ private final TypedExpression scope;
private final Type type = BigInteger.class;
- public BigIntegerConvertedExprT(TypedExpression value) {
- this.value = value;
+ public BigIntegerRelationalExprT(BinaryExpr.Operator operator,
+ TypedExpression scope,
+ TypedExpression argument) {
+ this.operator = operator;
+ this.scope = scope;
+ this.argument = argument;
}
@Override
@@ -45,16 +52,18 @@ public class BigIntegerConvertedExprT implements
TypedExpression {
@Override
public Node toJavaExpression() {
-
- return new ObjectCreationExpr(null,
-
StaticJavaParser.parseClassOrInterfaceType(type.getTypeName()),
- nodeList((Expression)
value.toJavaExpression()));
+ MethodCallExpr methodCallExpr = new MethodCallExpr((Expression)
scope.toJavaExpression(), "compareTo",
+
nodeList((Expression) argument.toJavaExpression()));
+ return new BinaryExpr(methodCallExpr, new IntegerLiteralExpr("0"),
operator);
}
@Override
public String toString() {
- return "BigIntegerConvertedExprT{" +
- "value=" + value +
+ return "BigIntegerRelationalExprT{" +
+ "operator=" + operator +
+ ", argument=" + argument +
+ ", scope=" + scope +
+ ", type=" + type +
'}';
}
}
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 e96e314389..804daf6db9 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
@@ -22,6 +22,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
+import java.math.BigInteger;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@@ -31,7 +32,7 @@ import com.github.javaparser.ast.Node;
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.mvelcompiler.util.BigNumberArgumentCoercion;
import org.drools.util.MethodUtils;
import static com.github.javaparser.ast.NodeList.nodeList;
@@ -83,9 +84,10 @@ public class FieldToAccessorTExpr implements TypedExpression
{
.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));
+ // Right is BigDecimal/BigInteger, left is other, coerce
+ if(rhsType.isPresent() && (rhsType.get().equals(BigDecimal.class) &&
!type.equals(BigDecimal.class)
+ || rhsType.get().equals(BigInteger.class)
&& !type.equals(BigInteger.class))) {
+ Expression coercedExpression = new
BigNumberArgumentCoercion().coercedArgument((Class<?>) rhsType.get(),
(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));
diff --git
a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/MethodCallExprT.java
b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/MethodCallExprT.java
index d2d93edce4..e57b9fd397 100644
---
a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/MethodCallExprT.java
+++
b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/MethodCallExprT.java
@@ -27,7 +27,7 @@ import java.util.Optional;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.MethodCallExpr;
-import org.drools.mvelcompiler.util.BigDecimalArgumentCoercion;
+import org.drools.mvelcompiler.util.BigNumberArgumentCoercion;
import static com.github.javaparser.ast.NodeList.nodeList;
import static org.drools.mvelcompiler.util.CoercionUtils.PUT_CALL;
@@ -101,7 +101,7 @@ public class MethodCallExprT implements TypedExpression {
Class<?> argumentType = (Class<?>) argumentTypeOrig;
Class<?> actualType = optionalActualType.get();
if(argumentType != actualType) {
- return new
BigDecimalArgumentCoercion().coercedArgument(argumentType, actualType,
(Expression) a.toJavaExpression());
+ return new
BigNumberArgumentCoercion().coercedArgument(argumentType, actualType,
(Expression) a.toJavaExpression());
}
}
}
diff --git
a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/util/BigDecimalArgumentCoercion.java
b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/util/BigNumberArgumentCoercion.java
similarity index 67%
rename from
drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/util/BigDecimalArgumentCoercion.java
rename to
drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/util/BigNumberArgumentCoercion.java
index 2465c33b3e..a8580f83b0 100644
---
a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/util/BigDecimalArgumentCoercion.java
+++
b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/util/BigNumberArgumentCoercion.java
@@ -19,33 +19,36 @@
package org.drools.mvelcompiler.util;
import java.math.BigDecimal;
+import java.math.BigInteger;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.MethodCallExpr;
import static com.github.javaparser.ast.NodeList.nodeList;
-public class BigDecimalArgumentCoercion {
+public class BigNumberArgumentCoercion {
public Expression coercedArgument(Class<?> argumentType, Class<?>
actualType, Expression argument) {
- boolean argumentTypeIsBigDecimal =
BigDecimal.class.isAssignableFrom(argumentType);
+ boolean argumentTypeIsBigNumber =
BigDecimal.class.isAssignableFrom(argumentType) ||
BigInteger.class.isAssignableFrom(argumentType);
- if (isInteger(actualType) && argumentTypeIsBigDecimal) {
- return bigDecimalToPrimitive(argument, "intValue");
- } else if (isLong(actualType) && argumentTypeIsBigDecimal) {
- return bigDecimalToPrimitive(argument, "longValue");
- } else if (isShort(actualType) && argumentTypeIsBigDecimal) {
- return bigDecimalToPrimitive(argument, "shortValue");
- } else if (isDouble(actualType) && argumentTypeIsBigDecimal) {
- return bigDecimalToPrimitive(argument, "doubleValue");
- } else if (isFloat(actualType) && argumentTypeIsBigDecimal) {
- return bigDecimalToPrimitive(argument, "floatValue");
+ if (argumentTypeIsBigNumber) {
+ if (isInteger(actualType)) {
+ return bigNumberToPrimitive(argument, "intValue");
+ } else if (isLong(actualType)) {
+ return bigNumberToPrimitive(argument, "longValue");
+ } else if (isShort(actualType)) {
+ return bigNumberToPrimitive(argument, "shortValue");
+ } else if (isDouble(actualType)) {
+ return bigNumberToPrimitive(argument, "doubleValue");
+ } else if (isFloat(actualType)) {
+ return bigNumberToPrimitive(argument, "floatValue");
+ }
}
return argument;
}
- private MethodCallExpr bigDecimalToPrimitive(Expression
argumentExpression, String intValue) {
+ private MethodCallExpr bigNumberToPrimitive(Expression argumentExpression,
String intValue) {
return new MethodCallExpr(argumentExpression, intValue, nodeList());
}
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 00b60f8877..79b62bb1fe 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
@@ -19,6 +19,7 @@
package org.drools;
import java.math.BigDecimal;
+import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -50,6 +51,7 @@ public class Person {
private Map<String, String> items = new HashMap<>();
private BigDecimal salary;
+ private BigInteger salaryBI;
private Integer ageAsInteger;
@@ -129,6 +131,14 @@ public class Person {
this.salary = salary;
}
+ public BigInteger getSalaryBI() {
+ return salaryBI;
+ }
+
+ public void setSalaryBI(BigInteger salaryBI) {
+ this.salaryBI = salaryBI;
+ }
+
public Integer getAgeAsInteger() {
return ageAsInteger;
}
diff --git
a/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/CompilerTest.java
b/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/CompilerTest.java
index 6ac766359c..cf36c29a6c 100644
---
a/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/CompilerTest.java
+++
b/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/CompilerTest.java
@@ -44,6 +44,7 @@ interface CompilerTest {
imports.add("java.util.HashMap");
imports.add("java.util.Map");
imports.add("java.math.BigDecimal");
+ imports.add("java.math.BigInteger");
imports.add("org.drools.Address");
imports.add(Person.class.getCanonicalName());
imports.add(Gender.class.getCanonicalName());
diff --git
a/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/ConstraintCompilerTest.java
b/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/ConstraintCompilerTest.java
index 0f6401d371..31a2c106d6 100644
---
a/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/ConstraintCompilerTest.java
+++
b/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/ConstraintCompilerTest.java
@@ -19,6 +19,7 @@
package org.drools.mvelcompiler;
import java.math.BigDecimal;
+import java.math.BigInteger;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Consumer;
@@ -112,6 +113,67 @@ public class ConstraintCompilerTest implements
CompilerTest {
"$bdvalue.add(BigDecimal.valueOf(0.5),
java.math.MathContext.DECIMAL128)");
}
+ @Test
+ public void testBigIntegerStringEquality() {
+ testExpression(c -> c.setRootPatternPrefix(Person.class, "_this"),
"salaryBI == \"90\"",
+ "_this.getSalaryBI().compareTo(new
java.math.BigInteger(\"90\")) == 0");
+ }
+
+ @Test
+ public void testBigIntegerStringNonEquality() {
+ testExpression(c -> c.setRootPatternPrefix(Person.class, "_this"),
"salaryBI != \"90\"",
+ "_this.getSalaryBI().compareTo(new
java.math.BigInteger(\"90\")) != 0");
+ }
+
+ @Test
+ public void testBigIntegerPromotionToIntMethod() {
+ testExpression(c -> c.setRootPatternPrefix(Person.class, "_this"),
"isEven(salaryBI)",
+ "_this.isEven(_this.getSalaryBI().intValue())");
+ }
+
+ @Test
+ public void testBigIntegerMultiplyInt() {
+ testExpression(c -> c.addDeclaration("$bi1", BigInteger.class), "$bi1
* 10",
+ "$bi1.multiply(new java.math.BigInteger(\"10\"))");
+ }
+
+ @Test
+ public void testBigIntegerMultiplyNegativeInt() {
+ testExpression(c -> c.addDeclaration("$bi1", BigInteger.class), "$bi1
* -1",
+ "$bi1.multiply(new java.math.BigInteger(\"-1\"))");
+ }
+
+ @Test
+ public void testBigIntegerAddInt() {
+ testExpression(c -> c.addDeclaration("$bi1", BigInteger.class), "$bi1
+ 10",
+ "$bi1.add(new java.math.BigInteger(\"10\"))");
+ }
+
+ @Test
+ public void testBigIntegerSubtractInt() {
+ testExpression(c -> c.addDeclaration("$bi1", BigInteger.class), "$bi1
- 10",
+ "$bi1.subtract(new java.math.BigInteger(\"10\"))");
+ }
+
+ @Test
+ public void testBigIntegerDivideInt() {
+ testExpression(c -> c.addDeclaration("$bi1", BigInteger.class), "$bi1
/ 10",
+ "$bi1.divide(new java.math.BigInteger(\"10\"))");
+ }
+
+ @Test
+ public void testBigIntegerModInt() {
+ testExpression(c -> c.addDeclaration("$bi1", BigInteger.class), "$bi1
% 10",
+ "$bi1.remainder(new java.math.BigInteger(\"10\"))");
+ }
+
+ @Test
+ public void testBigIntegerValueOfInteger() {
+ testExpression(c -> c.addDeclaration("$bivalue", BigInteger.class),
+ "$bivalue + BigInteger.valueOf(10)",
+ "$bivalue.add(BigInteger.valueOf(10))");
+ }
+
public void testExpression(Consumer<MvelCompilerContext> testFunction,
String inputExpression,
String expectedResult,
@@ -122,6 +184,7 @@ public class ConstraintCompilerTest implements CompilerTest
{
imports.add("java.util.HashMap");
imports.add("java.util.Map");
imports.add("java.math.BigDecimal");
+ imports.add("java.math.BigInteger");
imports.add("org.drools.Address");
imports.add(Person.class.getCanonicalName());
imports.add(Gender.class.getCanonicalName());
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 74bdd45d5b..14f6a9773e 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
@@ -473,7 +473,7 @@ public class MvelCompilerTest implements CompilerTest {
ctx.addDeclaration("$p", Person.class);
},
"{ $p.ageAsInteger = 10000I; }",
- "{ $p.setAgeAsInteger(new java.math.BigInteger(\"10000\")); }");
+ "{ $p.setAgeAsInteger(new
java.math.BigInteger(\"10000\").intValue()); }");
}
@Test
@@ -993,6 +993,322 @@ public class MvelCompilerTest implements CompilerTest {
"}");
}
+ @Test
+ public void testBigInteger() {
+ test("{ " +
+ " BigInteger sum = 0;\n" +
+ " BigInteger money = 10;\n" +
+ " sum += money;\n" +
+ " sum -= money;\n" +
+ "}",
+ "{ " +
+ " java.math.BigInteger sum = new
java.math.BigInteger(\"0\");\n" +
+ " java.math.BigInteger money = new
java.math.BigInteger(\"10\");\n" +
+ " sum = sum.add(money);\n" +
+ " sum = sum.subtract(money);\n" +
+ "}");
+ }
+
+ @Test
+ public void bigIntegerLessThan() {
+ test("{ " +
+ " BigInteger zero = 0;\n" +
+ " BigInteger ten = 10;\n" +
+ " if(zero < ten) {}\n" +
+ "}",
+ "{ " +
+ " java.math.BigInteger zero = new
java.math.BigInteger(\"0\");\n" +
+ " java.math.BigInteger ten = new
java.math.BigInteger(\"10\");\n" +
+ " if (zero.compareTo(ten) < 0) {\n" +
+ " }\n" +
+ "}");
+ }
+
+ @Test
+ public void bigIntegerLessThanOrEqual() {
+ test("{ " +
+ " BigInteger zero = 0;\n" +
+ " BigInteger ten = 10;\n" +
+ " if(zero <= ten) {}\n" +
+ "}",
+ "{ " +
+ " java.math.BigInteger zero = new
java.math.BigInteger(\"0\");\n" +
+ " java.math.BigInteger ten = new
java.math.BigInteger(\"10\");\n" +
+ " if (zero.compareTo(ten) <= 0) {\n" +
+ " }\n" +
+ "}");
+ }
+
+ @Test
+ public void bigIntegerGreaterThan() {
+ test("{ " +
+ " BigInteger zero = 0;\n" +
+ " BigInteger ten = 10;\n" +
+ " if(zero > ten) {}\n" +
+ "}",
+ "{ " +
+ " java.math.BigInteger zero = new
java.math.BigInteger(\"0\");\n" +
+ " java.math.BigInteger ten = new
java.math.BigInteger(\"10\");\n" +
+ " if (zero.compareTo(ten) > 0) {\n" +
+ " }\n" +
+ "}");
+ }
+
+ @Test
+ public void bigIntegerGreaterThanOrEqual() {
+ test("{ " +
+ " BigInteger zero = 0;\n" +
+ " BigInteger ten = 10;\n" +
+ " if(zero >= ten) {}\n" +
+ "}",
+ "{ " +
+ " java.math.BigInteger zero = new
java.math.BigInteger(\"0\");\n" +
+ " java.math.BigInteger ten = new
java.math.BigInteger(\"10\");\n" +
+ " if (zero.compareTo(ten) >= 0) {\n" +
+ " }\n" +
+ "}");
+ }
+
+ @Test
+ public void bigIntegerEquals() {
+ test("{ " +
+ " BigInteger zero = 0;\n" +
+ " if(zero == 23) {}\n" +
+ "}",
+ "{ " +
+ " java.math.BigInteger zero = new
java.math.BigInteger(\"0\");\n" +
+ " if (zero.compareTo(new java.math.BigInteger(\"23\"))
== 0) {\n" +
+ " }\n" +
+ "}");
+ }
+
+ @Test
+ public void bigIntegerNotEquals() {
+ test("{ " +
+ " BigInteger zero = 0;\n" +
+ " if(zero != 23) {}\n" +
+ "}",
+ "{ " +
+ " java.math.BigInteger zero = new
java.math.BigInteger(\"0\");\n" +
+ " if (zero.compareTo(new java.math.BigInteger(\"23\"))
!= 0) {\n" +
+ " }\n" +
+ "}");
+ }
+
+ @Test
+ public void testBigIntegerCompoundOperatorOnField() {
+ test(ctx -> ctx.addDeclaration("$p", Person.class),
+ "{ " +
+ " $p.salaryBI += 50000I;\n" +
+ "}",
+ "{ " +
+ " $p.setSalaryBI($p.getSalaryBI().add(new
java.math.BigInteger(\"50000\")));\n" +
+ "}");
+ }
+
+ @Test
+ public void testBigIntegerCompoundOperatorWithOnField() {
+ test(ctx -> ctx.addDeclaration("$p", Person.class),
+ "{ " +
+ " $p.salaryBI += $p.salaryBI;\n" +
+ "}",
+ "{ " +
+ "
$p.setSalaryBI($p.getSalaryBI().add($p.getSalaryBI()));\n" +
+ "}");
+ }
+
+ @Test
+ public void testBigIntegerArithmetic() {
+ test(ctx -> ctx.addDeclaration("$p", Person.class),
+ "{ " +
+ " java.math.BigInteger operation = $p.salaryBI +
$p.salaryBI;\n" +
+ "}",
+ "{ " +
+ " java.math.BigInteger operation =
$p.getSalaryBI().add($p.getSalaryBI());\n" +
+ "}");
+ }
+
+ @Test
+ public void testBigIntegerArithmeticWithConversionLiteral() {
+ test(ctx -> ctx.addDeclaration("$p", Person.class),
+ "{ " +
+ " java.math.BigInteger operation = $p.salaryBI +
10I;\n" +
+ "}",
+ "{ " +
+ " java.math.BigInteger operation =
$p.getSalaryBI().add(new java.math.BigInteger(\"10\"));\n" +
+ "}");
+ }
+
+ @Test
+ public void testBigIntegerArithmeticWithConversionFromInteger() {
+ test(ctx -> ctx.addDeclaration("$p", Person.class),
+ "{ " +
+ " java.math.BigInteger operation = $p.salaryBI +
10;\n" +
+ "}",
+ "{ " +
+ " java.math.BigInteger operation =
$p.getSalaryBI().add(new java.math.BigInteger(\"10\"));\n" +
+ "}");
+ }
+
+ @Test
+ public void testBigIntegerAssignmentToInt() {
+ test(ctx -> ctx.addDeclaration("$p", Person.class),
+ "{ " +
+ " $p.age = $p.salaryBI;\n" +
+ "}",
+ "{ " +
+ " $p.setAge($p.getSalaryBI().intValue());\n" +
+ "}");
+ }
+
+ @Test
+ public void testBigIntegerAssignmentToIntegerBoxed() {
+ test(ctx -> ctx.addDeclaration("$p", Person.class),
+ "{ " +
+ " $p.integerBoxed = $p.salaryBI;\n" +
+ "}",
+ "{ " +
+ " $p.setIntegerBoxed($p.getSalaryBI().intValue());\n" +
+ "}");
+ }
+
+ @Test
+ public void testBigIntegerAssignmentToLong() {
+ test(ctx -> ctx.addDeclaration("$p", Person.class),
+ "{ " +
+ " $p.longValue = $p.salaryBI;\n" +
+ "}",
+ "{ " +
+ " $p.setLongValue($p.getSalaryBI().longValue());\n" +
+ "}");
+ }
+
+ @Test
+ public void testBigIntegerAssignmentToLongBoxed() {
+ test(ctx -> ctx.addDeclaration("$p", Person.class),
+ "{ " +
+ " $p.longBoxed = $p.salaryBI;\n" +
+ "}",
+ "{ " +
+ " $p.setLongBoxed($p.getSalaryBI().longValue());\n" +
+ "}");
+ }
+
+ @Test
+ public void testBigIntegerAssignmentToShort() {
+ test(ctx -> ctx.addDeclaration("$p", Person.class),
+ "{ " +
+ " $p.shortValue = $p.salaryBI;\n" +
+ "}",
+ "{ " +
+ " $p.setShortValue($p.getSalaryBI().shortValue());\n" +
+ "}");
+ }
+
+ @Test
+ public void testBigIntegerAssignmentToShortBoxed() {
+ test(ctx -> ctx.addDeclaration("$p", Person.class),
+ "{ " +
+ " $p.shortBoxed = $p.salaryBI;\n" +
+ "}",
+ "{ " +
+ " $p.setShortBoxed($p.getSalaryBI().shortValue());\n" +
+ "}");
+ }
+
+ @Test
+ public void testBigIntegerAssignmentToDouble() {
+ test(ctx -> ctx.addDeclaration("$p", Person.class),
+ "{ " +
+ " $p.doubleValue = $p.salaryBI;\n" +
+ "}",
+ "{ " +
+ "
$p.setDoubleValue($p.getSalaryBI().doubleValue());\n" +
+ "}");
+ }
+
+ @Test
+ public void testBigIntegerAssignmentToDoubleBoxed() {
+ test(ctx -> ctx.addDeclaration("$p", Person.class),
+ "{ " +
+ " $p.doubleBoxed = $p.salaryBI;\n" +
+ "}",
+ "{ " +
+ "
$p.setDoubleBoxed($p.getSalaryBI().doubleValue());\n" +
+ "}");
+ }
+
+ @Test
+ public void testBigIntegerAssignmentToFloat() {
+ test(ctx -> ctx.addDeclaration("$p", Person.class),
+ "{ " +
+ " $p.floatValue = $p.salaryBI;\n" +
+ "}",
+ "{ " +
+ " $p.setFloatValue($p.getSalaryBI().floatValue());\n" +
+ "}");
+ }
+
+ @Test
+ public void testBigIntegerAssignmentToFloatBoxed() {
+ test(ctx -> ctx.addDeclaration("$p", Person.class),
+ "{ " +
+ " $p.floatBoxed = $p.salaryBI;\n" +
+ "}",
+ "{ " +
+ " $p.setFloatBoxed($p.getSalaryBI().floatValue());\n" +
+ "}");
+ }
+
+ @Test
+ public void testBigIntegerPromotionAllFourOperations() {
+ test(ctx -> ctx.addDeclaration("$p", Person.class),
+ "{ " +
+ " BigInteger result = 0I;" +
+ " result += 50000;\n" +
+ " result -= 10000;\n" +
+ " result /= 10;\n" +
+ " result *= 10;\n" +
+ " (result *= $p.salaryBI);\n" +
+ " $p.salaryBI = result;" +
+ "}",
+ "{ " +
+ " java.math.BigInteger result = new
java.math.BigInteger(\"0\");\n" +
+ " result = result.add(new
java.math.BigInteger(\"50000\"));\n" +
+ " result = result.subtract(new
java.math.BigInteger(\"10000\"));\n" +
+ " result = result.divide(new
java.math.BigInteger(\"10\"));\n" +
+ " result = result.multiply(new
java.math.BigInteger(\"10\"));\n" +
+ " result = result.multiply($p.getSalaryBI());\n" +
+ " $p.setSalaryBI(result);\n" +
+ "}");
+ }
+
+ @Test
+ public void testPromotionOfIntToBigInteger() {
+ test("{ " +
+ " BigInteger result = 0I;" +
+ " int anotherVariable = 20;" +
+ " result += anotherVariable;\n" + // 20
+ "}",
+ "{ " +
+ " java.math.BigInteger result = new
java.math.BigInteger(\"0\");\n" +
+ " int anotherVariable = 20;\n" +
+ " result = result.add(new
java.math.BigInteger(anotherVariable));\n" +
+ "}");
+ }
+
+ @Test
+ public void testPromotionOfIntToBigIntegerOnField() {
+ test(ctx -> ctx.addDeclaration("$p", Person.class), "{ " +
+ " int anotherVariable = 20;" +
+ " $p.salaryBI += anotherVariable;" +
+ "}",
+ "{ " +
+ " int anotherVariable = 20;\n" +
+ " $p.setSalaryBI($p.getSalaryBI().add(new
java.math.BigInteger(anotherVariable)));\n" +
+ "}");
+ }
+
@Test
public void testModify() {
test(ctx -> ctx.addDeclaration("$p", Person.class),
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]