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.git


The following commit(s) were added to refs/heads/main by this push:
     new 1a5d67680a0 [incubator-kie-6891] DRL10 ANTLR4 parser does not support 
lambdas and methods in functions (#6896)
1a5d67680a0 is described below

commit 1a5d67680a0f6c395ff82981fd81cb040a6a8546
Author: Toshiya Kobayashi <[email protected]>
AuthorDate: Fri Aug 14 09:00:08 2026 +0900

    [incubator-kie-6891] DRL10 ANTLR4 parser does not support lambdas and 
methods in functions (#6896)
---
 .../drl/parser/antlr4/MiscDRLParserTest.java       | 98 ++++++++++++++++++++++
 .../org/drools/drl/parser/antlr4/DRL10Parser.g4    | 15 ++--
 .../model/codegen/execmodel/FunctionsTest.java     | 63 ++++++++++++++
 3 files changed, 171 insertions(+), 5 deletions(-)

diff --git 
a/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/MiscDRLParserTest.java
 
b/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/MiscDRLParserTest.java
index 90cde154380..9b80b71efe5 100644
--- 
a/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/MiscDRLParserTest.java
+++ 
b/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/MiscDRLParserTest.java
@@ -4054,6 +4054,104 @@ class MiscDRLParserTest {
         
assertThat(function.getBody()).isEqualToIgnoringWhitespace("List<String> 
results = new ArrayList<>(); return results;");
     }
 
+    @Test
+    void functionWithLambdaExpression() {
+        // incubator-kie-issues#6891 : expression-bodied lambda as a method 
argument
+        final String text = "function void applyToAll(java.util.List xs, 
java.util.List out) {\n" +
+                "    xs.forEach(e -> out.add(e));\n" +
+                "}";
+        PackageDescr packageDescr = parseAndGetPackageDescr(text);
+
+        FunctionDescr function = packageDescr.getFunctions().get(0);
+
+        assertThat(function.getName()).isEqualTo("applyToAll");
+        
assertThat(function.getParameterTypes()).containsExactly("java.util.List", 
"java.util.List");
+        assertThat(function.getParameterNames()).containsExactly("xs", "out");
+        
assertThat(function.getBody()).isEqualToIgnoringWhitespace("xs.forEach(e -> 
out.add(e));");
+    }
+
+    @Test
+    void functionWithBlockBodiedLambda() {
+        // incubator-kie-issues#6891 : block-bodied lambda as a method argument
+        final String text = "function void applyToAll(java.util.List xs, 
java.util.List out) {\n" +
+                "    xs.forEach(e -> { out.add(e); });\n" +
+                "}";
+        PackageDescr packageDescr = parseAndGetPackageDescr(text);
+
+        FunctionDescr function = packageDescr.getFunctions().get(0);
+
+        assertThat(function.getName()).isEqualTo("applyToAll");
+        
assertThat(function.getParameterTypes()).containsExactly("java.util.List", 
"java.util.List");
+        assertThat(function.getParameterNames()).containsExactly("xs", "out");
+        
assertThat(function.getBody()).isEqualToIgnoringWhitespace("xs.forEach(e -> { 
out.add(e); });");
+    }
+
+    @Test
+    void functionWithTypedLambdaParameter() {
+        // incubator-kie-issues#6891 : lambda with an explicitly typed 
parameter as a method argument
+        final String text = "function void applyToAll(java.util.List xs, 
java.util.List out) {\n" +
+                "    xs.forEach((Object e) -> out.add(e));\n" +
+                "}";
+        PackageDescr packageDescr = parseAndGetPackageDescr(text);
+
+        FunctionDescr function = packageDescr.getFunctions().get(0);
+
+        assertThat(function.getName()).isEqualTo("applyToAll");
+        
assertThat(function.getParameterTypes()).containsExactly("java.util.List", 
"java.util.List");
+        assertThat(function.getParameterNames()).containsExactly("xs", "out");
+        
assertThat(function.getBody()).isEqualToIgnoringWhitespace("xs.forEach((Object 
e) -> out.add(e));");
+    }
+
+    @Test
+    void functionWithInstanceMethodReference() {
+        // incubator-kie-issues#6891 : instance method reference (obj::m) as a 
method argument
+        final String text = "function void applyToAll(java.util.List xs, 
java.util.List out) {\n" +
+                "    xs.forEach(out::add);\n" +
+                "}";
+        PackageDescr packageDescr = parseAndGetPackageDescr(text);
+
+        FunctionDescr function = packageDescr.getFunctions().get(0);
+
+        assertThat(function.getName()).isEqualTo("applyToAll");
+        
assertThat(function.getParameterTypes()).containsExactly("java.util.List", 
"java.util.List");
+        assertThat(function.getParameterNames()).containsExactly("xs", "out");
+        
assertThat(function.getBody()).isEqualToIgnoringWhitespace("xs.forEach(out::add);");
+    }
+
+    @Test
+    void functionWithTypeMethodReference() {
+        // incubator-kie-issues#6891 : type method reference (Type::m) inside 
a stream chain
+        final String text = "function java.util.List 
toUpperCase(java.util.List<String> xs) {\n" +
+                "    return 
xs.stream().map(String::toUpperCase).collect(java.util.stream.Collectors.toList());\n"
 +
+                "}";
+        PackageDescr packageDescr = parseAndGetPackageDescr(text);
+
+        FunctionDescr function = packageDescr.getFunctions().get(0);
+
+        assertThat(function.getName()).isEqualTo("toUpperCase");
+        
assertThat(function.getReturnType()).isEqualToIgnoringWhitespace("java.util.List");
+        
assertThat(function.getParameterTypes().get(0)).isEqualToIgnoringWhitespace("java.util.List<String>");
+        assertThat(function.getParameterNames().get(0)).isEqualTo("xs");
+        assertThat(function.getBody()).isEqualToIgnoringWhitespace("return 
xs.stream().map(String::toUpperCase).collect(java.util.stream.Collectors.toList());");
+    }
+
+    @Test
+    void functionWithStreamChainContainingLambda() {
+        // incubator-kie-issues#6891 : stream chain containing a lambda
+        final String text = "function long 
countLongNames(java.util.List<String> names) {\n" +
+                "    return names.stream().filter(n -> n.length() > 
3).count();\n" +
+                "}";
+        PackageDescr packageDescr = parseAndGetPackageDescr(text);
+
+        FunctionDescr function = packageDescr.getFunctions().get(0);
+
+        assertThat(function.getName()).isEqualTo("countLongNames");
+        
assertThat(function.getReturnType()).isEqualToIgnoringWhitespace("long");
+        
assertThat(function.getParameterTypes().get(0)).isEqualToIgnoringWhitespace("java.util.List<String>");
+        assertThat(function.getParameterNames().get(0)).isEqualTo("names");
+        assertThat(function.getBody()).isEqualToIgnoringWhitespace("return 
names.stream().filter(n -> n.length() > 3).count();");
+    }
+
     @Test
     void lhsPatternAnnotation() {
         final String text = "package org.drools\n" +
diff --git 
a/drools-drl/drools-drl-parser/src/main/antlr4/org/drools/drl/parser/antlr4/DRL10Parser.g4
 
b/drools-drl/drools-drl-parser/src/main/antlr4/org/drools/drl/parser/antlr4/DRL10Parser.g4
index 8532476f47a..894e3cf30bc 100644
--- 
a/drools-drl/drools-drl-parser/src/main/antlr4/org/drools/drl/parser/antlr4/DRL10Parser.g4
+++ 
b/drools-drl/drools-drl-parser/src/main/antlr4/org/drools/drl/parser/antlr4/DRL10Parser.g4
@@ -269,11 +269,16 @@ backReferenceExpression : (DOT DOT DIV)+  drlExpression ;
 
 
 /* extending JavaParser methodCall in order to accept drl keywords as method 
name */
-drlMethodCall
-    : drlIdentifier LPAREN expressionList? RPAREN
-    | THIS LPAREN expressionList? RPAREN
-    | SUPER LPAREN expressionList? RPAREN
-    ;
+  drlMethodCall
+      : drlIdentifier LPAREN drlExpressionList? RPAREN
+      | THIS LPAREN drlExpressionList? RPAREN
+      | SUPER LPAREN drlExpressionList? RPAREN
+      ;
+
+  drlExpressionList
+      : drlExpression (COMMA drlExpression)*
+      ;
+
 
 temporalOperator : DRL_NOT? bop=(DRL_AFTER | DRL_BEFORE | DRL_COINCIDES | 
DRL_DURING | DRL_INCLUDES | DRL_FINISHES | DRL_FINISHED_BY | DRL_MEETS | 
DRL_MET_BY | DRL_OVERLAPS | DRL_OVERLAPPED_BY | DRL_STARTS | DRL_STARTED_BY) 
timeAmount? ;
 
diff --git 
a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/FunctionsTest.java
 
b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/FunctionsTest.java
index 6fe46ceaf4c..a418db1bb01 100644
--- 
a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/FunctionsTest.java
+++ 
b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/FunctionsTest.java
@@ -18,6 +18,7 @@
  */
 package org.drools.model.codegen.execmodel;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
@@ -291,4 +292,66 @@ public class FunctionsTest extends BaseModelTest {
         assertThat(results.size()).isEqualTo(2);
         assertThat(results.iterator().next().getValue()).isEqualTo("whatever");
     }
+
+    @ParameterizedTest
+       @MethodSource("parameters")
+    public void testFunctionWithLambda(RUN_TYPE runType) {
+        // incubator-kie-issues#6891 : a lambda in a function body
+        String str =
+                "package com.sample\n" +
+                "import " + Person.class.getName() + ";\n" +
+                "global java.util.List results;\n" +
+                "function String upperCaseNames(java.util.List names) {\n" +
+                "    java.util.List out = new java.util.ArrayList();\n" +
+                "    names.forEach(n -> out.add(((String) 
n).toUpperCase()));\n" +
+                "    return out.toString();\n" +
+                "}\n" +
+                "rule R\n" +
+                "    when\n" +
+                "        $p : Person()\n" +
+                "    then\n" +
+                "        
results.add(upperCaseNames(java.util.Arrays.asList($p.getName())));\n" +
+                "end";
+
+        KieSession ksession = getKieSession(runType, str);
+        List<String> results = new ArrayList<>();
+        ksession.setGlobal("results", results);
+
+        ksession.insert(new Person("Mario", 40));
+        int rulesFired = ksession.fireAllRules();
+
+        assertThat(rulesFired).isEqualTo(1);
+        assertThat(results).containsExactly("[MARIO]");
+    }
+
+    @ParameterizedTest
+       @MethodSource("parameters")
+    public void testFunctionWithMethodReference(RUN_TYPE runType) {
+        // incubator-kie-issues#6891 : a method reference (obj::m) in a 
function body
+        String str =
+                "package com.sample\n" +
+                "import " + Person.class.getName() + ";\n" +
+                "global java.util.List results;\n" +
+                "function String collectNames(java.util.List names) {\n" +
+                "    java.util.List out = new java.util.ArrayList();\n" +
+                "    names.forEach(out::add);\n" +
+                "    return out.toString();\n" +
+                "}\n" +
+                "rule R\n" +
+                "    when\n" +
+                "        $p : Person()\n" +
+                "    then\n" +
+                "        
results.add(collectNames(java.util.Arrays.asList($p.getName())));\n" +
+                "end";
+
+        KieSession ksession = getKieSession(runType, str);
+        List<String> results = new ArrayList<>();
+        ksession.setGlobal("results", results);
+
+        ksession.insert(new Person("Mario", 40));
+        int rulesFired = ksession.fireAllRules();
+
+        assertThat(rulesFired).isEqualTo(1);
+        assertThat(results).containsExactly("[Mario]");
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to