From 278726c4a75026f8a62a83fd73be99c4b26c16f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tibor=20Zim=C3=A1nyi?= Date: Wed, 11 Oct 2023 08:58:31 +0200 Subject: [PATCH] [kie-issues#624] Fix coercing double type in Mvel compiler (#5550) (cherry picked from commit 67b5880df93aef6847bd1db92dd519b850180b66) --- .../mvelcompiler/MethodCallExprVisitor.java | 6 +-- .../org/drools/mvelcompiler/RHSPhase.java | 7 +++ .../mvelcompiler/ReProcessRHSPhase.java | 7 +++ .../ast/DoubleLiteralExpressionT.java | 52 +++++++++++++++++++ .../mvelcompiler/ConstraintCompilerTest.java | 14 +++++ .../drools/mvelcompiler/MvelCompilerTest.java | 11 ++++ 6 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/DoubleLiteralExpressionT.java diff --git a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/MethodCallExprVisitor.java b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/MethodCallExprVisitor.java index e042ccdafdb..f15bcd3acbd 100644 --- a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/MethodCallExprVisitor.java +++ b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/MethodCallExprVisitor.java @@ -57,7 +57,7 @@ public TypedExpression visit(MethodCallExpr n, RHSPhase.Context arg) { Optional scope = n.getScope().map(s -> s.accept(this, arg)); TypedExpression name = n.getName().accept(this, new RHSPhase.Context(scope.orElse(null))); final List arguments = new ArrayList<>(n.getArguments().size()); - for(Expression child : n.getArguments()) { + for (Expression child : n.getArguments()) { TypedExpression a = child.accept(this, arg); arguments.add(a); } @@ -92,7 +92,7 @@ private MethodCallExprT parseMethod(MethodCallExpr n, .>map(ClassUtils::classFromType) .map(scopeClazz -> MethodUtils.findMethod(scopeClazz, n.getNameAsString(), argumentsType)); - if(method.isEmpty()) { + if (method.isEmpty()) { method = mvelCompilerContext.getRootPattern() .map(scopeClazz -> MethodUtils.findMethod(scopeClazz, n.getNameAsString(), argumentsType)); if(method.isPresent()) { @@ -100,7 +100,7 @@ private MethodCallExprT parseMethod(MethodCallExpr n, } } - if(method.isEmpty()) { + if (method.isEmpty()) { method = mvelCompilerContext.findStaticMethod(n.getNameAsString()); } 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 fa45ed894a3..e863df75b66 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 @@ -33,6 +33,7 @@ import com.github.javaparser.ast.expr.BooleanLiteralExpr; import com.github.javaparser.ast.expr.CastExpr; import com.github.javaparser.ast.expr.CharLiteralExpr; +import com.github.javaparser.ast.expr.DoubleLiteralExpr; import com.github.javaparser.ast.expr.EnclosedExpr; import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.expr.FieldAccessExpr; @@ -61,6 +62,7 @@ import org.drools.mvelcompiler.ast.BooleanLiteralExpressionT; import org.drools.mvelcompiler.ast.CastExprT; import org.drools.mvelcompiler.ast.CharacterLiteralExpressionT; +import org.drools.mvelcompiler.ast.DoubleLiteralExpressionT; import org.drools.mvelcompiler.ast.FieldAccessTExpr; import org.drools.mvelcompiler.ast.FieldToAccessorTExpr; import org.drools.mvelcompiler.ast.IntegerLiteralExpressionT; @@ -329,6 +331,11 @@ public TypedExpression visit(IntegerLiteralExpr n, Context arg) { return new IntegerLiteralExpressionT(n); } + @Override + public TypedExpression visit(DoubleLiteralExpr n, Context arg) { + return new DoubleLiteralExpressionT(n); + } + @Override public TypedExpression visit(CharLiteralExpr n, Context arg) { return new CharacterLiteralExpressionT(n); 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 d036af6e30e..c2b686d9a0b 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 @@ -22,12 +22,14 @@ import com.github.javaparser.ast.Node; import com.github.javaparser.ast.expr.BinaryExpr; +import com.github.javaparser.ast.expr.DoubleLiteralExpr; import com.github.javaparser.ast.expr.IntegerLiteralExpr; import com.github.javaparser.ast.expr.LongLiteralExpr; 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.DoubleLiteralExpressionT; import org.drools.mvelcompiler.ast.IntegerLiteralExpressionT; import org.drools.mvelcompiler.ast.LongLiteralExpressionT; import org.drools.mvelcompiler.ast.TypedExpression; @@ -84,6 +86,11 @@ public Optional visit(IntegerLiteralExpr n, ReProcessRHSPhase.C return convertWhenLHSISBigDecimal(() -> new IntegerLiteralExpressionT(n), context); } + @Override + public Optional visit(DoubleLiteralExpr n, ReProcessRHSPhase.Context context) { + return convertWhenLHSISBigDecimal(() -> new DoubleLiteralExpressionT(n), context); + } + @Override public Optional visit(LongLiteralExpr n, ReProcessRHSPhase.Context context) { return convertWhenLHSISBigDecimal(() -> new LongLiteralExpressionT(n), context); diff --git a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/DoubleLiteralExpressionT.java b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/DoubleLiteralExpressionT.java new file mode 100644 index 00000000000..8a965390e82 --- /dev/null +++ b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/DoubleLiteralExpressionT.java @@ -0,0 +1,52 @@ +/** + * 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 com.github.javaparser.ast.Node; +import com.github.javaparser.ast.expr.DoubleLiteralExpr; + +import java.lang.reflect.Type; +import java.util.Optional; + +public class DoubleLiteralExpressionT implements TypedExpression { + + private final DoubleLiteralExpr doubleLiteralExpr; + + public DoubleLiteralExpressionT(DoubleLiteralExpr doubleLiteralExpr) { + + this.doubleLiteralExpr = doubleLiteralExpr; + } + + @Override + public Optional getType() { + return Optional.of(double.class); + } + + @Override + public Node toJavaExpression() { + return doubleLiteralExpr; + } + + @Override + public String toString() { + return "DoubleLiteralExpressionT{" + + "originalExpression=" + doubleLiteralExpr + + '}'; + } +} 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 34b7d97590f..54c40c8cb84 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 @@ -96,6 +96,20 @@ public void testBigDecimalModInt() { "$bd1.remainder(new java.math.BigDecimal(10), java.math.MathContext.DECIMAL128)"); } + @Test + public void testBigDecimalValueOfInteger() { + testExpression(c -> c.addDeclaration("$bdvalue", BigDecimal.class), + "$bdvalue + BigDecimal.valueOf(10)", + "$bdvalue.add(BigDecimal.valueOf(10), java.math.MathContext.DECIMAL128)"); + } + + @Test + public void testBigDecimalValueOfDouble() { + testExpression(c -> c.addDeclaration("$bdvalue", BigDecimal.class), + "$bdvalue + BigDecimal.valueOf(0.5)", + "$bdvalue.add(BigDecimal.valueOf(0.5), java.math.MathContext.DECIMAL128)"); + } + public void testExpression(Consumer testFunction, String inputExpression, String expectedResult, 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 6631627700f..24e73720385 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 @@ -745,6 +745,17 @@ public void testBigDecimalArithmetic() { "}"); } + @Test + public void testBigDecimalArithmeticWithValueOfDouble() { + test(ctx -> ctx.addDeclaration("$p", Person.class), + "{ " + + " $p.salary = $p.salary + BigDecimal.valueOf(0.5);\n" + + "}", + "{ " + + " $p.setSalary($p.getSalary().add(BigDecimal.valueOf(0.5), java.math.MathContext.DECIMAL128));\n" + + "}"); + } + @Test public void testBigDecimalArithmeticWithConversionLiteral() { test(ctx -> ctx.addDeclaration("$p", Person.class),