lucamolteni commented on code in PR #5617:
URL:
https://github.com/apache/incubator-kie-drools/pull/5617#discussion_r1417577669
##########
drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/util/MethodResolutionUtils.java:
##########
@@ -0,0 +1,183 @@
+package org.drools.mvelcompiler.util;
+
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.utils.Pair;
+import org.drools.mvel.parser.ast.expr.ListCreationLiteralExpression;
+import org.drools.mvel.parser.ast.expr.MapCreationLiteralExpression;
+import org.drools.mvel.parser.ast.visitor.DrlGenericVisitor;
+import org.drools.mvelcompiler.ast.ListExprT;
+import org.drools.mvelcompiler.ast.MapExprT;
+import org.drools.mvelcompiler.ast.TypedExpression;
+import org.drools.mvelcompiler.context.MvelCompilerContext;
+import org.drools.util.ClassUtils;
+import org.drools.util.MethodUtils;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+public final class MethodResolutionUtils {
+
+ private MethodResolutionUtils() {
+ // It is forbidden to create instances of util classes.
+ }
+
+ /**
+ * [] is ambiguous in mvel - it can represent an empty list or an empty
map.
+ * It cannot be distinguished on a language level, so this is a
workaround:
+ * - When there [] written in a rule, mvel parser parses it as an empty
list.
+ * - The only possible way with constructors, when there is such
parameter, is try to guess the correct parameter type when trying to read the
constructor from a class.
+ * - This uses all indexes of empty lists or empty maps in the
constructor parameters.
+ * - When not possible to resolve the constructor with a list or map
parameter, it will try to resolve a constructor with the other collection
parameter.
+ * - This happens for all empty list and map parameters resolved by the
parser, until a proper constructor is found.
+ */
+ public static List<TypedExpression> coerceCorrectConstructorArguments(
+ final Class<?> type,
+ List<TypedExpression> arguments,
+ List<Integer> emptyListArgumentIndexes) {
+ // Rather work only with the argumentsType and when a method is
resolved, flip the arguments list based on it.
+ final List<TypedExpression> coercedArgumentsTypesList = new
ArrayList<>(arguments);
+ // This needs to go through all possible combinations.
+ final int indexesListSize = emptyListArgumentIndexes.size();
Review Comment:
Add unit tests for this method as well
##########
drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/MethodCallExprVisitor.java:
##########
@@ -89,43 +87,21 @@ private MethodCallExprT parseMethod(MethodCallExpr n,
Optional<TypedExpression> scope,
TypedExpression name,
List<TypedExpression> arguments,
- Class<?>[] argumentsType) {
- Optional<Method> method = scope.flatMap(TypedExpression::getType)
- .<Class<?>>map(ClassUtils::classFromType)
- .map(scopeClazz -> MethodUtils.findMethod(scopeClazz,
n.getNameAsString(), argumentsType));
-
- if (method.isEmpty()) {
- method = mvelCompilerContext.getRootPattern()
- .map(scopeClazz -> MethodUtils.findMethod(scopeClazz,
n.getNameAsString(), argumentsType));
- if(method.isPresent()) {
- scope = mvelCompilerContext.createRootTypePrefix();
- }
+ List<Integer>
emptyCollectionArgumentIndexes) {
+ Pair<Optional<Method>, Optional<TypedExpression>> resolveMethodResult =
+ MethodResolutionUtils.resolveMethod(n, mvelCompilerContext,
scope, arguments);
+ // This is a workaround for mvel empty list and map ambiguity, please
see the description in getTypedArguments() method.
+ if (resolveMethodResult.a.isEmpty() &&
!emptyCollectionArgumentIndexes.isEmpty()) {
+ resolveMethodResult =
MethodResolutionUtils.resolveMethodWithEmptyCollectionArguments(n,
mvelCompilerContext, resolveMethodResult.b, arguments,
emptyCollectionArgumentIndexes);
Review Comment:
Can you please add unit tests in `drools-mvel-compiler` module covering this
case?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]