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]