This is an automated email from the ASF dual-hosted git repository.

mariofusco pushed a commit to branch dev-new-parser
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git

commit be33de7844572a601e5aee66de7af52cac38a28e
Author: Jiří Locker <[email protected]>
AuthorDate: Wed Feb 7 08:38:40 2024 +0100

    Add DescrDumperTest and fix the expression parser grammar (#48)
    
    * Add DescrDumperTest
    
    * Fix it
---
 drools-drl/drools-drl10-parser/pom.xml             |  12 +
 .../antlr4/org/drools/parser/DRL6Expressions.g4    |  11 +-
 .../java/org/drools/parser/DescrDumperTest.java    | 367 +++++++++++++++++++++
 3 files changed, 384 insertions(+), 6 deletions(-)

diff --git a/drools-drl/drools-drl10-parser/pom.xml 
b/drools-drl/drools-drl10-parser/pom.xml
index 49aee297f5..57ed8f85ca 100644
--- a/drools-drl/drools-drl10-parser/pom.xml
+++ b/drools-drl/drools-drl10-parser/pom.xml
@@ -75,6 +75,18 @@
       <version>${version.ch.qos.logback}</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.drools</groupId>
+      <artifactId>drools-compiler</artifactId>
+      <version>${version.org.drools}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.drools</groupId>
+      <artifactId>drools-mvel</artifactId>
+      <version>${version.org.drools}</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>
diff --git 
a/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRL6Expressions.g4
 
b/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRL6Expressions.g4
index 9b15991027..ef6e098267 100644
--- 
a/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRL6Expressions.g4
+++ 
b/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRL6Expressions.g4
@@ -99,6 +99,7 @@ catch (RecognitionException re) {
 // --------------------------------------------------------
 literal
     :  STRING_LITERAL  {       helper.emit($STRING_LITERAL, 
DroolsEditorType.STRING_CONST);    }
+    |  DRL_STRING_LITERAL  {   helper.emit($DRL_STRING_LITERAL, 
DroolsEditorType.STRING_CONST);        }
     |  DECIMAL_LITERAL {       helper.emit($DECIMAL_LITERAL, 
DroolsEditorType.NUMERIC_CONST);  }
     |  HEX_LITERAL     {       helper.emit($HEX_LITERAL, 
DroolsEditorType.NUMERIC_CONST);      }
     |  FLOAT_LITERAL   {       helper.emit($FLOAT_LITERAL, 
DroolsEditorType.NUMERIC_CONST);    }
@@ -731,9 +732,6 @@ selector
 
 superSuffix
     :  arguments
-    // TODO syntactic predicates in the form of `(x) => x` can be safely 
removed but
-    //  there was originally `DOT ID ((LEFT_PAREN) => arguments)?`.
-    //  Not sure if removing `(LEFT_PAREN) =>` is correct.
     |          DOT IDENTIFIER (arguments)?
     ;
 
@@ -832,15 +830,16 @@ new_key
     ;
 
 not_key
-    :      {(helper.validateIdentifierKey(DroolsSoftKeywords.NOT))}? 
id=IDENTIFIER { helper.emit($id, DroolsEditorType.KEYWORD); }
+    :      {(helper.validateIdentifierKey(DroolsSoftKeywords.NOT))}? 
id=DRL_NOT { helper.emit($id, DroolsEditorType.KEYWORD); }
     ;
 
 in_key
-  :      {(helper.validateIdentifierKey(DroolsSoftKeywords.IN))}? 
id=IDENTIFIER { helper.emit($id, DroolsEditorType.KEYWORD); }
+  :      {(helper.validateIdentifierKey(DroolsSoftKeywords.IN))}? id=DRL_IN { 
helper.emit($id, DroolsEditorType.KEYWORD); }
   ;
 
 operator_key
-  :      {(helper.isPluggableEvaluator(false))}? id=IDENTIFIER { 
helper.emit($id, DroolsEditorType.KEYWORD); }
+  // TODO get rid of the DRL_MATCHES token or introduce DRL_CONTAINS etc. for 
consistency.
+  :      {(helper.isPluggableEvaluator(false))}? id=(IDENTIFIER|DRL_MATCHES) { 
helper.emit($id, DroolsEditorType.KEYWORD); }
   ;
 
 neg_operator_key
diff --git 
a/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/DescrDumperTest.java
 
b/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/DescrDumperTest.java
new file mode 100644
index 0000000000..d0a18797c1
--- /dev/null
+++ 
b/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/DescrDumperTest.java
@@ -0,0 +1,367 @@
+/**
+ * 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.parser;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.drools.compiler.lang.DescrDumper;
+import org.drools.compiler.lang.DumperContext;
+import org.drools.drl.ast.descr.AtomicExprDescr;
+import org.drools.drl.ast.descr.BindingDescr;
+import org.drools.drl.ast.descr.ConstraintConnectiveDescr;
+import org.drools.mvel.evaluators.MatchesEvaluatorsDefinition;
+import org.drools.mvel.evaluators.SetEvaluatorsDefinition;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.kie.internal.builder.conf.LanguageLevelOption;
+
+public class DescrDumperTest {
+
+    private DescrDumper dumper;
+
+    @BeforeEach
+    public void setUp() throws Exception {
+        // configure operators
+        new SetEvaluatorsDefinition();
+        new MatchesEvaluatorsDefinition();
+
+        dumper = new DescrDumper();
+    }
+
+    @Test
+    public void testDump() throws Exception {
+        String input = "price > 10 && < 20 || == $val || == 30";
+        String expected = "( price > 10 && price < 20 || price == $val || 
price == 30 )";
+
+        ConstraintConnectiveDescr descr = parse( input );
+        String result = dumper.dump( descr );
+
+        assertThat(result).isEqualTo(expected);
+    }
+
+    @Test
+    public void testDumpMatches() throws Exception {
+        String input = "type.toString matches \"something\\swith\\tsingle 
escapes\"";
+        String expected = "type.toString ~= \"something\\swith\\tsingle 
escapes\"";
+
+        ConstraintConnectiveDescr descr = parse( input );
+        String result = dumper.dump( descr );
+
+        assertThat(result).isEqualTo(expected);
+    }
+
+    @Test
+    public void testDumpMatches2() throws Exception {
+        String input = "type.toString matches 'something\\swith\\tsingle 
escapes'";
+        String expected = "type.toString ~= \"something\\swith\\tsingle 
escapes\"";
+
+        ConstraintConnectiveDescr descr = parse( input );
+        String result = dumper.dump( descr );
+
+        assertThat(result).isEqualTo(expected);
+    }
+
+    @Test
+    public void testDumpMatches3() throws Exception {
+        String input = "this[\"content\"] matches \"hello ;=\"";
+        String expected = "this[\"content\"] ~= \"hello ;=\"";
+
+        ConstraintConnectiveDescr descr = parse( input );
+        String result = dumper.dump( descr );
+
+        assertThat(result).isEqualTo(expected);
+    }
+
+    @Test
+    public void testDumpContains() throws Exception {
+        String input = "list contains \"b\"";
+        String expected = "list contains \"b\"";
+
+        ConstraintConnectiveDescr descr = parse( input );
+        String result = dumper.dump( descr );
+
+        assertThat(result).isEqualTo(expected);
+    }
+
+    @Test
+    public void testDumpContains2() throws Exception {
+        String input = "list not contains \"b\"";
+        String expected = "!( list contains \"b\" )";
+
+        ConstraintConnectiveDescr descr = parse( input );
+        String result = dumper.dump( descr );
+
+        assertThat(result).isEqualTo(expected);
+    }
+
+    @Test
+    public void testDumpExcludes() throws Exception {
+        String input = "list excludes \"b\"";
+        String expected = "!( list contains \"b\" )";
+
+        ConstraintConnectiveDescr descr = parse( input );
+        String result = dumper.dump( descr );
+
+        assertThat(result).isEqualTo(expected);
+    }
+
+    @Test
+    public void testDumpExcludes2() throws Exception {
+        String input = "list not excludes \"b\"";
+        String expected = "list contains \"b\"";
+
+        ConstraintConnectiveDescr descr = parse( input );
+        String result = dumper.dump( descr );
+
+        assertThat(result).isEqualTo(expected);
+    }
+
+    @Test @Disabled
+    public void testDumpWithDateAttr() throws Exception {
+        String input = "son.birthDate == \"01-jan-2000\"";
+        String expected = "son.birthDate == 
org.drools.util.DateUtils.parseDate( \"01-jan-2000\" )";
+
+        ConstraintConnectiveDescr descr = parse( input );
+        String result = dumper.dump( descr );
+
+        assertThat(result).isEqualTo(expected);
+    }
+
+    @Test
+    public void testDumpComplex() throws Exception {
+        String input = "a ( > 60 && < 70 ) || ( > 50 && < 55 ) && a3 == 
\"black\" || a == 40 && a3 == \"pink\" || a == 12 && a3 == \"yellow\" || a3 == 
\"blue\"";
+        String expected = "( ( a > 60 && a < 70 || a > 50 && a < 55 ) && a3 == 
\"black\" || a == 40 && a3 == \"pink\" || a == 12 && a3 == \"yellow\" || a3 == 
\"blue\" )";
+
+        ConstraintConnectiveDescr descr = parse( input );
+        String result = dumper.dump( descr );
+
+        assertThat(result).isEqualTo(expected);
+    }
+
+    @Test
+    public void testDumpBindings() throws Exception {
+        String input = "$x : property > value";
+        String expected = "property > value";
+
+        ConstraintConnectiveDescr descr = parse( input );
+        DumperContext ctx = new DumperContext();
+        String result = dumper.dump( descr,
+                                     ctx );
+
+        assertThat(result).isEqualTo(expected);
+        assertThat(ctx.getBindings().size()).isEqualTo(1);
+        BindingDescr bind = ctx.getBindings().get( 0 );
+        assertThat(bind.getVariable()).isEqualTo("$x");
+        assertThat(bind.getExpression()).isEqualTo("property");
+    }
+
+    @Test
+    public void testDumpBindings2() throws Exception {
+        String input = "( $a : a > $b : b[10].prop || 10 != 20 ) && $x : 
someMethod(10) == 20";
+        String expected = "( a > b[10].prop || 10 != 20 ) && someMethod(10) == 
20";
+
+        ConstraintConnectiveDescr descr = parse( input );
+        DumperContext ctx = new DumperContext();
+        String result = dumper.dump( descr,
+                                     ctx );
+
+        assertThat(result).isEqualTo(expected);
+        assertThat(ctx.getBindings().size()).isEqualTo(3);
+        BindingDescr bind = ctx.getBindings().get( 0 );
+        assertThat(bind.getVariable()).isEqualTo("$a");
+        assertThat(bind.getExpression()).isEqualTo("a");
+        bind = ctx.getBindings().get( 1 );
+        assertThat(bind.getVariable()).isEqualTo("$b");
+        assertThat(bind.getExpression()).isEqualTo("b[10].prop");
+        bind = ctx.getBindings().get( 2 );
+        assertThat(bind.getVariable()).isEqualTo("$x");
+        assertThat(bind.getExpression()).isEqualTo("someMethod(10)");
+    }
+
+    @Test
+    public void testDumpBindings3() throws Exception {
+        String input = "( $a : a > $b : b[10].prop || 10 != 20 ) && $x : 
someMethod(10)";
+        String expected = "( a > b[10].prop || 10 != 20 )";
+
+        ConstraintConnectiveDescr descr = parse( input );
+        String result = dumper.dump( descr );
+
+        assertThat(result).isEqualTo(expected);
+    }
+
+    @Test
+    public void testDumpBindings4() throws Exception {
+        String input = "( $a : a > $b : b[10].prop || $x : someMethod(10) ) && 
10 != 20";
+        String expected = "( a > b[10].prop ) && 10 != 20";
+
+        ConstraintConnectiveDescr descr = parse( input );
+        String result = dumper.dump( descr );
+
+        assertThat(result).isEqualTo(expected);
+    }
+
+    @Test
+    public void testDumpBindingsWithRestriction() throws Exception {
+        String input = "$x : age > 10 && < 20 || > 30";
+        String expected = "( age > 10 && age < 20 || age > 30 )";
+
+        ConstraintConnectiveDescr descr = parse( input );
+        DumperContext ctx = new DumperContext();
+        String result = dumper.dump( descr,
+                                     ctx );
+
+        assertThat(result).isEqualTo(expected);
+        assertThat(ctx.getBindings().size()).isEqualTo(1);
+        BindingDescr bind = ctx.getBindings().get( 0 );
+        assertThat(bind.getVariable()).isEqualTo("$x");
+        assertThat(bind.getExpression()).isEqualTo("age");
+    }
+
+    @Test
+    public void testDumpBindingsComplexOp() throws Exception {
+        String input = "$x : age in (10, 20, $someVal)";
+        String expected = "( age == 10 || age == 20 || age == $someVal )";
+
+        ConstraintConnectiveDescr descr = parse( input );
+        DumperContext ctx = new DumperContext();
+        String result = dumper.dump( descr,
+                                     ctx );
+
+        assertThat(result).isEqualTo(expected);
+        assertThat(ctx.getBindings().size()).isEqualTo(1);
+        BindingDescr bind = ctx.getBindings().get( 0 );
+        assertThat(bind.getVariable()).isEqualTo("$x");
+        assertThat(bind.getExpression()).isEqualTo("age");
+    }
+
+    @Test
+    public void testDumpBindingsComplexOp2() throws Exception {
+        String input = "$x : age not in (10, 20, $someVal)";
+        String expected = "age != 10 && age != 20 && age != $someVal";
+
+        ConstraintConnectiveDescr descr = parse( input );
+        DumperContext ctx = new DumperContext();
+        String result = dumper.dump( descr,
+                                     ctx );
+
+        assertThat(result).isEqualTo(expected);
+        assertThat(ctx.getBindings().size()).isEqualTo(1);
+        BindingDescr bind = ctx.getBindings().get( 0 );
+        assertThat(bind.getVariable()).isEqualTo("$x");
+        assertThat(bind.getExpression()).isEqualTo("age");
+    }
+
+    @Test
+    public void testProcessInlineCast() throws Exception {
+        String expr = "field1#Class.field2";
+        String expectedInstanceof = "field1 instanceof Class";
+        String expectedcasted = "((Class)field1).field2";
+        AtomicExprDescr atomicExpr = new AtomicExprDescr(expr);
+        ConstraintConnectiveDescr ccd = new ConstraintConnectiveDescr( );
+        ccd.addDescr( atomicExpr );
+        String[] instanceofAndCastedExpr = 
dumper.processImplicitConstraints(expr, atomicExpr, ccd, 
ccd.getDescrs().indexOf( atomicExpr ), null);
+        assertThat(ccd.getDescrs().size()).isEqualTo(2);
+        
assertThat(ccd.getDescrs().get(0).toString()).isEqualTo(expectedInstanceof);
+        
assertThat(atomicExpr.getRewrittenExpression()).isEqualTo(expectedcasted);
+
+        expr = "field1#Class1.field2#Class2.field3";
+        String expectedInstanceof1 = "field1 instanceof Class1";
+        String expectedInstanceof2 = "((Class1)field1).field2 instanceof 
Class2";
+        expectedcasted = "((Class2)((Class1)field1).field2).field3";
+        atomicExpr = new AtomicExprDescr(expr);
+        ccd = new ConstraintConnectiveDescr( );
+        instanceofAndCastedExpr = dumper.processImplicitConstraints(expr, 
atomicExpr, ccd, ccd.getDescrs().indexOf( atomicExpr ), null);
+        
assertThat(ccd.getDescrs().get(0).toString()).isEqualTo(expectedInstanceof1);
+        
assertThat(ccd.getDescrs().get(1).toString()).isEqualTo(expectedInstanceof2);
+        assertThat(instanceofAndCastedExpr[1]).isEqualTo(expectedcasted);
+        
assertThat(atomicExpr.getRewrittenExpression()).isEqualTo(expectedcasted);
+    }
+
+    @Test
+    public void testProcessNullSafeDereferencing() throws Exception {
+        String expr = "field1!.field2";
+        String expectedNullCheck = "field1 != null";
+        String expectedExpr = "field1.field2";
+        AtomicExprDescr atomicExpr = new AtomicExprDescr(expr);
+        ConstraintConnectiveDescr ccd = new ConstraintConnectiveDescr( );
+        String[] nullCheckAndExpr = dumper.processImplicitConstraints( expr, 
atomicExpr, ccd, ccd.getDescrs().indexOf( atomicExpr ), null );
+        
assertThat(ccd.getDescrs().get(0).toString()).isEqualTo(expectedNullCheck);
+        assertThat(nullCheckAndExpr[1]).isEqualTo(expectedExpr);
+        
assertThat(atomicExpr.getRewrittenExpression()).isEqualTo(expectedExpr);
+
+        expr = "field1!.field2!.field3";
+        String expectedNullCheck1 = "field1 != null";
+        String expectedNullCheck2 = "field1.field2 != null";
+        expectedExpr = "field1.field2.field3";
+        atomicExpr = new AtomicExprDescr(expr);
+        ccd = new ConstraintConnectiveDescr( );
+        nullCheckAndExpr = dumper.processImplicitConstraints( expr, 
atomicExpr, ccd, ccd.getDescrs().indexOf( atomicExpr ), null );
+        
assertThat(ccd.getDescrs().get(0).toString()).isEqualTo(expectedNullCheck1);
+        
assertThat(ccd.getDescrs().get(1).toString()).isEqualTo(expectedNullCheck2);
+        assertThat(nullCheckAndExpr[1]).isEqualTo(expectedExpr);
+        
assertThat(atomicExpr.getRewrittenExpression()).isEqualTo(expectedExpr);
+    }
+
+    @Test
+    public void testProcessImplicitConstraints() throws Exception {
+        String expr = "field1#Class!.field2";
+        String expectedConstraints = "field1 instanceof Class";
+        String expectedExpr = "((Class)field1).field2";
+        AtomicExprDescr atomicExpr = new AtomicExprDescr(expr);
+        ConstraintConnectiveDescr ccd = new ConstraintConnectiveDescr( );
+        String[] constraintsAndExpr = dumper.processImplicitConstraints( expr, 
atomicExpr, ccd, ccd.getDescrs().indexOf( atomicExpr ), null );
+        
assertThat(ccd.getDescrs().get(0).toString()).isEqualTo(expectedConstraints);
+        assertThat(constraintsAndExpr[1]).isEqualTo(expectedExpr);
+        
assertThat(atomicExpr.getRewrittenExpression()).isEqualTo(expectedExpr);
+
+        expr = "field1!.field2#Class.field3";
+        String expectedConstraints1 = "field1 != null";
+        String expectedConstraints2 = "field1.field2 instanceof Class";
+        expectedExpr = "((Class)field1.field2).field3";
+        atomicExpr = new AtomicExprDescr(expr);
+        ccd = new ConstraintConnectiveDescr( );
+        constraintsAndExpr = dumper.processImplicitConstraints( expr, 
atomicExpr, ccd, ccd.getDescrs().indexOf( atomicExpr ), null );
+        
assertThat(ccd.getDescrs().get(0).toString()).isEqualTo(expectedConstraints1);
+        
assertThat(ccd.getDescrs().get(1).toString()).isEqualTo(expectedConstraints2);
+        assertThat(constraintsAndExpr[1]).isEqualTo(expectedExpr);
+        
assertThat(atomicExpr.getRewrittenExpression()).isEqualTo(expectedExpr);
+
+        expr = "field1#Class.field2!.field3";
+        expectedConstraints1 = "field1 instanceof Class";
+        expectedConstraints2 = "((Class)field1).field2 != null";
+        expectedExpr = "((Class)field1).field2.field3";
+        atomicExpr = new AtomicExprDescr(expr);
+        ccd = new ConstraintConnectiveDescr( );
+        constraintsAndExpr = dumper.processImplicitConstraints( expr, 
atomicExpr, ccd, ccd.getDescrs().indexOf( atomicExpr ), null );
+        
assertThat(ccd.getDescrs().get(0).toString()).isEqualTo(expectedConstraints1);
+        
assertThat(ccd.getDescrs().get(1).toString()).isEqualTo(expectedConstraints2);
+        assertThat(constraintsAndExpr[1]).isEqualTo(expectedExpr);
+        
assertThat(atomicExpr.getRewrittenExpression()).isEqualTo(expectedExpr);
+    }
+
+    public ConstraintConnectiveDescr parse( final String constraint ) {
+        DrlExprParser parser = new DrlExprParser(LanguageLevelOption.DRL6);
+        ConstraintConnectiveDescr result = parser.parse( constraint );
+        
assertThat(parser.hasErrors()).as(parser.getErrors().toString()).isFalse();
+
+        return result;
+    }
+
+}


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

Reply via email to