baldimir commented on code in PR #5617:
URL: 
https://github.com/apache/incubator-kie-drools/pull/5617#discussion_r1419109987


##########
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:
   Added.



##########
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:
   Added.



-- 
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]

Reply via email to