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 bd189735a6ec526ab82d47591bcdd5c849d61c25
Author: Toshiya Kobayashi <[email protected]>
AuthorDate: Wed May 11 00:41:17 2022 +0900

    Enhance test/grammar coverage. function import, global, exists, not (#6)
---
 .../src/main/antlr4/org/drools/parser/DRLLexer.g4  |   2 +
 .../src/main/antlr4/org/drools/parser/DRLParser.g4 |  38 +++-
 .../java/org/drools/parser/DRLParserHelper.java    |  26 +++
 .../java/org/drools/parser/DRLParserWrapper.java   |   5 +
 .../java/org/drools/parser/DRLVisitorImpl.java     |  97 ++++++++-
 .../main/java/org/drools/parser/StringUtils.java   |  20 ++
 .../java/org/drools/parser/MiscDRLParserTest.java  | 237 ++++++++++++++++++++-
 .../test/resources/org/drools/parser/globals.drl   |  28 +++
 .../org/drools/parser/test_FunctionImport.drl      |  27 +++
 9 files changed, 462 insertions(+), 18 deletions(-)

diff --git 
a/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRLLexer.g4 
b/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRLLexer.g4
index 732a0d3bcc..0f4ee3cc48 100644
--- 
a/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRLLexer.g4
+++ 
b/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRLLexer.g4
@@ -32,8 +32,10 @@ WHEN : 'when';
 THEN : 'then';
 END : 'end';
 
+EXISTS : 'exists';
 NOT : 'not';
 IN : 'in';
+FROM : 'from';
 
 SALIENCE : 'salience';
 ENABLED : 'enabled';
diff --git 
a/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRLParser.g4 
b/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRLParser.g4
index 31bf8c80ee..2818590bd5 100644
--- 
a/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRLParser.g4
+++ 
b/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRLParser.g4
@@ -33,7 +33,11 @@ lhsUnary : ( lhsExists namedConsequence?
            ) SEMI? ;
 */
 
-lhsUnary : lhsPatternBind ;
+lhsUnary : (
+           lhsExists
+           | lhsNot
+           | lhsPatternBind
+           ) ;
 lhsPatternBind : label? ( LPAREN lhsPattern (OR lhsPattern)* RPAREN | 
lhsPattern ) ;
 
 /*
@@ -41,7 +45,7 @@ lhsPattern : xpathPrimary (OVER patternFilter)? |
              ( QUESTION? qualifiedIdentifier LPAREN positionalConstraints? 
constraints? RPAREN (OVER patternFilter)? (FROM patternSource)? ) ;
 */
 
-lhsPattern : QUESTION? objectType=qualifiedName LPAREN positionalConstraints? 
constraints? RPAREN ;
+lhsPattern : QUESTION? objectType=qualifiedName LPAREN (positionalConstraints? 
constraints? ) RPAREN (FROM patternSource)? ;
 positionalConstraints : constraint (COMMA constraint)* SEMI ;
 constraints : constraint (COMMA constraint)* ;
 constraint : label? ( nestedConstraint | conditionalOrExpression ) ;
@@ -60,6 +64,34 @@ drlExpression : conditionalExpression ( 
op=assignmentOperator right=drlExpressio
 conditionalExpression : left=conditionalOrExpression ternaryExpression? ;
 ternaryExpression : QUESTION ts=drlExpression COLON fs=drlExpression ;
 
+/*
+ patternSource := FROM
+                ( fromAccumulate
+                | fromCollect
+                | fromEntryPoint
+                | fromWindow
+                | fromExpression )
+*/
+patternSource : fromExpression ;
+fromExpression : conditionalOrExpression ;
+
+/*
+ lhsExists := EXISTS
+           ( (LEFT_PAREN (or_key|and_key))=> lhsOr  // prevents '((' for 
prefixed and/or
+           | LEFT_PAREN lhsOr RIGHT_PAREN
+           | lhsPatternBind
+           )
+*/
+lhsExists : EXISTS lhsPatternBind ;
+/*
+ lhsNot := NOT
+           ( (LEFT_PAREN (or_key|and_key))=> lhsOr  // prevents '((' for 
prefixed and/or
+           | LEFT_PAREN lhsOr RIGHT_PAREN
+           | lhsPatternBind
+           )
+*/
+lhsNot : NOT lhsPatternBind ;
+
 rhs : blockStatement+ ;
 
 stringId : ( IDENTIFIER | STRING_LITERAL ) ;
@@ -76,7 +108,7 @@ drlAnnotation : AT name=qualifiedName drlArguments? ;
 
 attributes : attribute ( COMMA? attribute )* ;
 attribute : ( 'salience' DECIMAL_LITERAL )
-          | ( 'enabled' | 'no-loop' | 'auto-focus' | 'lock-on-active' | 
'refract' | 'direct' ) BOOLEAN?
+          | ( 'enabled' | 'no-loop' | 'auto-focus' | 'lock-on-active' | 
'refract' | 'direct' ) BOOL_LITERAL?
           | ( 'agenda-group' | 'activation-group' | 'ruleflow-group' | 
'date-effective' | 'date-expires' | 'dialect' ) STRING_LITERAL
           |   'calendars' STRING_LITERAL ( COMMA STRING_LITERAL )*
           |   'timer' ( DECIMAL_LITERAL | TEXT )
diff --git 
a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserHelper.java
 
b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserHelper.java
index 6c39a73323..feabbe3920 100644
--- 
a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserHelper.java
+++ 
b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserHelper.java
@@ -3,8 +3,11 @@ package org.drools.parser;
 import org.antlr.v4.runtime.CharStream;
 import org.antlr.v4.runtime.CharStreams;
 import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.RuleContext;
 import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.tree.ErrorNode;
 import org.antlr.v4.runtime.tree.ParseTree;
+import org.antlr.v4.runtime.tree.TerminalNode;
 import org.drools.drl.ast.descr.PackageDescr;
 
 public class DRLParserHelper {
@@ -46,4 +49,27 @@ public class DRLParserHelper {
         }
         return null;
     }
+
+    /**
+     * RuleContext.getText() connects all nodes including ErrorNode. This 
method appends texts only from valid nodes
+     */
+    public static String getTextWithoutErrorNode(ParseTree tree) {
+        if (tree.getChildCount() == 0) {
+            return "";
+        }
+
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < tree.getChildCount(); i++) {
+            ParseTree child = tree.getChild(i);
+            if (!(child instanceof ErrorNode)) {
+                if (child instanceof TerminalNode) {
+                    builder.append(child.getText());
+                } else {
+                    builder.append(getTextWithoutErrorNode(child));
+                }
+            }
+        }
+
+        return builder.toString();
+    }
 }
diff --git 
a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserWrapper.java
 
b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserWrapper.java
index 4b948cffca..251c918190 100644
--- 
a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserWrapper.java
+++ 
b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserWrapper.java
@@ -2,6 +2,7 @@ package org.drools.parser;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.drools.drl.ast.descr.PackageDescr;
@@ -39,6 +40,10 @@ public class DRLParserWrapper {
         return errors;
     }
 
+    public List<String> getErrorMessages() {
+        return 
errors.stream().map(DRLParserError::getMessage).collect(Collectors.toList());
+    }
+
     public boolean hasErrors() {
         return !errors.isEmpty();
     }
diff --git 
a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLVisitorImpl.java
 
b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLVisitorImpl.java
index 4c81640688..d93c707abe 100644
--- 
a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLVisitorImpl.java
+++ 
b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLVisitorImpl.java
@@ -1,18 +1,25 @@
 package org.drools.parser;
 
+import java.util.ArrayDeque;
+import java.util.Deque;
 import java.util.Objects;
 import java.util.stream.Collectors;
 
+import org.antlr.v4.runtime.ParserRuleContext;
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.antlr.v4.runtime.tree.TerminalNode;
 import org.drools.drl.ast.descr.*;
 
+import static org.drools.parser.DRLParserHelper.getTextWithoutErrorNode;
+import static org.drools.parser.StringUtils.safeStripStringDelimiters;
+
 public class DRLVisitorImpl extends DRLParserBaseVisitor<Object> {
 
     private final PackageDescr packageDescr = new PackageDescr();
 
     private RuleDescr currentRule;
     private PatternDescr currentPattern;
+    private Deque<ConditionalElementDescr> currentConstructStack = new 
ArrayDeque<>(); // e.g. whole LHS, not, exist
 
     @Override
     public Object visitCompilationUnit(DRLParser.CompilationUnitContext ctx) {
@@ -21,7 +28,7 @@ public class DRLVisitorImpl extends 
DRLParserBaseVisitor<Object> {
 
     @Override
     public Object visitPackagedef(DRLParser.PackagedefContext ctx) {
-        packageDescr.setName(ctx.name.getText());
+        packageDescr.setName(getTextWithoutErrorNode(ctx.name));
         return super.visitPackagedef(ctx);
     }
 
@@ -33,20 +40,32 @@ public class DRLVisitorImpl extends 
DRLParserBaseVisitor<Object> {
 
     @Override
     public Object visitGlobaldef(DRLParser.GlobaldefContext ctx) {
-        packageDescr.addGlobal(new GlobalDescr(ctx.IDENTIFIER().getText(), 
ctx.type().getText()));
+        GlobalDescr globalDescr = new GlobalDescr(ctx.IDENTIFIER().getText(), 
ctx.type().getText());
+        populateStartEnd(globalDescr, ctx);
+        packageDescr.addGlobal(globalDescr);
         return super.visitGlobaldef(ctx);
     }
 
     @Override
     public Object visitImportdef(DRLParser.ImportdefContext ctx) {
-        String imp = ctx.qualifiedName().getText() + (ctx.MUL() != null ? ".*" 
: "");
-        packageDescr.addImport(new ImportDescr(imp));
+        String target = ctx.qualifiedName().getText() + (ctx.MUL() != null ? 
".*" : "");
+        if (ctx.FUNCTION() != null || ctx.STATIC() != null) {
+            FunctionImportDescr functionImportDescr = new 
FunctionImportDescr();
+            functionImportDescr.setTarget(target);
+            populateStartEnd(functionImportDescr, ctx);
+            packageDescr.addFunctionImport(functionImportDescr);
+        } else {
+            ImportDescr importDescr = new ImportDescr();
+            importDescr.setTarget(target);
+            populateStartEnd(importDescr, ctx);
+            packageDescr.addImport(importDescr);
+        }
         return super.visitImportdef(ctx);
     }
 
     @Override
     public Object visitRuledef(DRLParser.RuledefContext ctx) {
-        currentRule = new RuleDescr(ctx.name.getText());
+        currentRule = new 
RuleDescr(safeStripStringDelimiters(ctx.name.getText()));
         currentRule.setConsequence(ctx.rhs().getText());
         packageDescr.addRule(currentRule);
 
@@ -55,14 +74,33 @@ public class DRLVisitorImpl extends 
DRLParserBaseVisitor<Object> {
         return result;
     }
 
+    @Override
+    public Object visitLhs(DRLParser.LhsContext ctx) {
+        currentConstructStack.push(currentRule.getLhs());
+        try {
+            return super.visitLhs(ctx);
+        } finally {
+            currentConstructStack.pop();
+        }
+    }
+
     @Override
     public Object visitLhsPatternBind(DRLParser.LhsPatternBindContext ctx) {
+        // TODO: this logic will likely be split to visitLhsPattern
         if (ctx.lhsPattern().size() == 1) {
-            currentPattern = new 
PatternDescr(ctx.lhsPattern(0).objectType.getText());
+            DRLParser.LhsPatternContext lhsPatternCtx = ctx.lhsPattern(0);
+            currentPattern = new 
PatternDescr(lhsPatternCtx.objectType.getText());
             if (ctx.label() != null) {
                 
currentPattern.setIdentifier(ctx.label().IDENTIFIER().getText());
             }
-            currentRule.getLhs().addDescr(currentPattern);
+            if (lhsPatternCtx.patternSource() != null) {
+                String expression = lhsPatternCtx.patternSource().getText();
+                FromDescr from = new FromDescr();
+                from.setDataSource(new MVELExprDescr(expression));
+                from.setResource(currentPattern.getResource());
+                currentPattern.setSource(from);
+            }
+            currentConstructStack.peek().addDescr(currentPattern);
         }
         Object result = super.visitLhsPatternBind(ctx);
         currentPattern = null;
@@ -72,9 +110,11 @@ public class DRLVisitorImpl extends 
DRLParserBaseVisitor<Object> {
     @Override
     public Object visitConstraint(DRLParser.ConstraintContext ctx) {
         Object constraint = super.visitConstraint(ctx);
-        ExprConstraintDescr constr = new ExprConstraintDescr( 
constraint.toString() );
-        constr.setType( ExprConstraintDescr.Type.NAMED );
-        currentPattern.addConstraint( constr );
+        if (constraint != null) {
+            ExprConstraintDescr constr = new 
ExprConstraintDescr(constraint.toString());
+            constr.setType(ExprConstraintDescr.Type.NAMED);
+            currentPattern.addConstraint(constr);
+        }
         return null;
     }
 
@@ -89,7 +129,11 @@ public class DRLVisitorImpl extends 
DRLParserBaseVisitor<Object> {
 
     @Override
     public Object visitIdentifier(DRLParser.IdentifierContext ctx) {
-        return ctx.IDENTIFIER().getText();
+        if (ctx.IDENTIFIER() == null) {
+            return "";
+        } else {
+            return ctx.IDENTIFIER().getText();
+        }
     }
 
     @Override
@@ -124,7 +168,38 @@ public class DRLVisitorImpl extends 
DRLParserBaseVisitor<Object> {
         return super.visitAttribute(ctx);
     }
 
+    @Override
+    public Object visitLhsExists(DRLParser.LhsExistsContext ctx) {
+        ExistsDescr existsDescr = new ExistsDescr();
+        currentConstructStack.peek().addDescr(existsDescr);
+        currentConstructStack.push(existsDescr);
+        try {
+            return super.visitLhsExists(ctx);
+        } finally {
+            currentConstructStack.pop();
+        }
+    }
+
+    @Override
+    public Object visitLhsNot(DRLParser.LhsNotContext ctx) {
+        NotDescr notDescr = new NotDescr();
+        currentConstructStack.peek().addDescr(notDescr);
+        currentConstructStack.push(notDescr);
+        try {
+            return super.visitLhsNot(ctx);
+        } finally {
+            currentConstructStack.pop();
+        }
+    }
+
     public PackageDescr getPackageDescr() {
         return packageDescr;
     }
+
+    private void populateStartEnd(BaseDescr descr, ParserRuleContext ctx) {
+        descr.setStartCharacter(ctx.getStart().getStartIndex());
+        // TODO: Current DRL6Parser adds +1 for EndCharacter but it doesn't 
look reasonable. At the moment, I don't add. Instead, I fix unit tests.
+        //       I will revisit if this is the right approach.
+        descr.setEndCharacter(ctx.getStop().getStopIndex());
+    }
 }
diff --git 
a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/StringUtils.java
 
b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/StringUtils.java
new file mode 100644
index 0000000000..22f8adf4c8
--- /dev/null
+++ 
b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/StringUtils.java
@@ -0,0 +1,20 @@
+package org.drools.parser;
+
+/**
+ * will be merged in drools-util
+ */
+public class StringUtils {
+
+    private StringUtils() {
+    }
+
+    public static String safeStripStringDelimiters(String value) {
+        if (value != null) {
+            value = value.trim();
+            if (value.length() >= 2 && value.startsWith("\"") && 
value.endsWith("\"")) {
+                value = value.substring(1, value.length() - 1);
+            }
+        }
+        return value;
+    }
+}
diff --git 
a/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/MiscDRLParserTest.java
 
b/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/MiscDRLParserTest.java
index 9a6b31f2b7..caabed1592 100644
--- 
a/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/MiscDRLParserTest.java
+++ 
b/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/MiscDRLParserTest.java
@@ -1,7 +1,23 @@
 package org.drools.parser;
 
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
 import junit.framework.TestCase;
+import org.drools.drl.ast.descr.FromDescr;
+import org.drools.drl.ast.descr.FunctionImportDescr;
+import org.drools.drl.ast.descr.GlobalDescr;
+import org.drools.drl.ast.descr.ImportDescr;
+import org.drools.drl.ast.descr.NotDescr;
 import org.drools.drl.ast.descr.PackageDescr;
+import org.drools.drl.ast.descr.PatternDescr;
+import org.drools.drl.ast.descr.RuleDescr;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -24,6 +40,19 @@ public class MiscDRLParserTest extends TestCase {
         super.tearDown();
     }
 
+    private PackageDescr parseResource(final String filename) throws Exception 
{
+        Path path = Paths.get(getClass().getResource(filename).toURI());
+        final StringBuilder sb = new StringBuilder();
+        try (BufferedReader br = Files.newBufferedReader(path, 
StandardCharsets.UTF_8)) {
+            for (String line; (line = br.readLine()) != null; ) {
+                sb.append(line + "\n");
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return parser.parse(sb.toString());
+    }
+
     @Test
     public void testPackage() throws Exception {
         final String source = "package foo.bar.baz";
@@ -36,8 +65,7 @@ public class MiscDRLParserTest extends TestCase {
         final String source = "package 12 foo.bar.baz";
         final PackageDescr pkg = parser.parse(source);
         assertTrue(parser.hasErrors());
-        // getText() combines an ErrorNode "12" so the result is different 
from DRL6Parser.
-        assertEquals("12foo.bar.baz", pkg.getName());
+        assertEquals("foo.bar.baz", pkg.getName());
     }
 
     @Test
@@ -45,7 +73,208 @@ public class MiscDRLParserTest extends TestCase {
         final String source = "package 12 12312 231";
         final PackageDescr pkg = parser.parse(source);
         assertTrue(parser.hasErrors());
-        // NPE inside DRLVisitorImpl.visitIdentifier(). So pkg is null. 
Different from DRL6Parser.
-        assertNull(pkg);
+        assertEquals("", pkg.getName());
+    }
+
+    @Test
+    public void testCompilationUnit() throws Exception {
+        final String source = "package foo; import com.foo.Bar; import 
com.foo.Baz;";
+        PackageDescr pkg = parser.parse(source);
+        assertFalse(parser.getErrors().toString(),
+                    parser.hasErrors());
+        assertEquals("foo",
+                     pkg.getName());
+        assertEquals(2,
+                     pkg.getImports().size());
+        ImportDescr impdescr = pkg.getImports().get(0);
+        assertEquals("com.foo.Bar",
+                     impdescr.getTarget());
+        assertEquals(source.indexOf("import " + impdescr.getTarget()),
+                     impdescr.getStartCharacter());
+        assertEquals(source.indexOf("import " + impdescr.getTarget()) + 
("import " + impdescr.getTarget()).length(),
+                     impdescr.getEndCharacter());
+
+        impdescr = pkg.getImports().get(1);
+        assertEquals("com.foo.Baz",
+                     impdescr.getTarget());
+        assertEquals(source.indexOf("import " + impdescr.getTarget()),
+                     impdescr.getStartCharacter());
+        assertEquals(source.indexOf("import " + impdescr.getTarget()) + 
("import " + impdescr.getTarget()).length(),
+                     impdescr.getEndCharacter());
+    }
+
+    @Test
+    public void testFunctionImport() throws Exception {
+        final String source = "package foo\n" +
+                "import function java.lang.Math.max\n" +
+                "import function java.lang.Math.min;\n" +
+                "import foo.bar.*\n" +
+                "import baz.Baz";
+        PackageDescr pkg = parser.parse(source);
+        assertFalse(parser.getErrors().toString(),
+                    parser.hasErrors());
+        assertEquals("foo",
+                     pkg.getName());
+        assertEquals(2,
+                     pkg.getImports().size());
+        ImportDescr impdescr = pkg.getImports().get(0);
+        assertEquals("foo.bar.*",
+                     impdescr.getTarget());
+        assertEquals(source.indexOf("import " + impdescr.getTarget()),
+                     impdescr.getStartCharacter());
+
+        assertEquals(source.indexOf("import " + impdescr.getTarget()) + 
("import " + impdescr.getTarget()).length() - 1,
+                     impdescr.getEndCharacter());
+
+        impdescr = pkg.getImports().get(1);
+        assertEquals("baz.Baz",
+                     impdescr.getTarget());
+        assertEquals(source.indexOf("import " + impdescr.getTarget()),
+                     impdescr.getStartCharacter());
+        assertEquals(source.indexOf("import " + impdescr.getTarget()) + 
("import " + impdescr.getTarget()).length() - 1,
+                     impdescr.getEndCharacter());
+
+        assertEquals(2,
+                     pkg.getFunctionImports().size());
+        impdescr = pkg.getFunctionImports().get(0);
+        assertEquals("java.lang.Math.max",
+                     impdescr.getTarget());
+        assertEquals(source.indexOf("import function " + impdescr.getTarget()),
+                     impdescr.getStartCharacter());
+        assertEquals(source.indexOf("import function " + impdescr.getTarget()) 
+ ("import function " + impdescr.getTarget()).length() - 1,
+                     impdescr.getEndCharacter());
+
+        impdescr = pkg.getFunctionImports().get(1);
+        assertEquals("java.lang.Math.min",
+                     impdescr.getTarget());
+        assertEquals(source.indexOf("import function " + impdescr.getTarget()),
+                     impdescr.getStartCharacter());
+        assertEquals(source.indexOf("import function " + impdescr.getTarget()) 
+ ("import function " + impdescr.getTarget()).length(),
+                     impdescr.getEndCharacter());
+    }
+
+    @Test
+    public void testGlobalWithComplexType() throws Exception {
+        final String source = "package foo.bar.baz\n" +
+                "import com.foo.Bar\n" +
+                "global java.util.List<java.util.Map<String,Integer>> 
aList;\n" +
+                "global Integer aNumber";
+        PackageDescr pkg = parser.parse(source);
+        assertFalse(parser.getErrors().toString(),
+                    parser.hasErrors());
+        assertEquals("foo.bar.baz",
+                     pkg.getName());
+        assertEquals(1,
+                     pkg.getImports().size());
+
+        ImportDescr impdescr = pkg.getImports().get(0);
+        assertEquals("com.foo.Bar",
+                     impdescr.getTarget());
+        assertEquals(source.indexOf("import " + impdescr.getTarget()),
+                     impdescr.getStartCharacter());
+        assertEquals(source.indexOf("import " + impdescr.getTarget()) + 
("import " + impdescr.getTarget()).length() - 1,
+                     impdescr.getEndCharacter());
+
+        assertEquals(2,
+                     pkg.getGlobals().size());
+
+        GlobalDescr global = pkg.getGlobals().get(0);
+        assertEquals("java.util.List<java.util.Map<String,Integer>>",
+                     global.getType());
+        assertEquals("aList",
+                     global.getIdentifier());
+        assertEquals(source.indexOf("global " + global.getType()),
+                     global.getStartCharacter());
+        assertEquals(source.indexOf("global " + global.getType() + " " + 
global.getIdentifier()) +
+                             ("global " + global.getType() + " " + 
global.getIdentifier()).length(),
+                     global.getEndCharacter());
+
+        global = pkg.getGlobals().get(1);
+        assertEquals("Integer",
+                     global.getType());
+        assertEquals("aNumber",
+                     global.getIdentifier());
+        assertEquals(source.indexOf("global " + global.getType()),
+                     global.getStartCharacter());
+        assertEquals(source.indexOf("global " + global.getType() + " " + 
global.getIdentifier()) +
+                             ("global " + global.getType() + " " + 
global.getIdentifier()).length() - 1,
+                     global.getEndCharacter());
+    }
+
+    @Test
+    public void testGlobalWithOrWithoutSemi() throws Exception {
+        PackageDescr pack = parseResource("globals.drl");
+
+        assertEquals(1,
+                     pack.getRules().size());
+
+        final RuleDescr rule = (RuleDescr) pack.getRules().get(0);
+        assertEquals(1,
+                     rule.getLhs().getDescrs().size());
+
+        assertEquals(1,
+                     pack.getImports().size());
+        assertEquals(2,
+                     pack.getGlobals().size());
+
+        final GlobalDescr foo = (GlobalDescr) pack.getGlobals().get(0);
+        assertEquals("java.lang.String",
+                     foo.getType());
+        assertEquals("foo",
+                     foo.getIdentifier());
+        final GlobalDescr bar = (GlobalDescr) pack.getGlobals().get(1);
+        assertEquals("java.lang.Integer",
+                     bar.getType());
+        assertEquals("bar",
+                     bar.getIdentifier());
+    }
+
+    @Test
+    public void testFunctionImportWithNotExist() throws Exception {
+        PackageDescr pkg = (PackageDescr) 
parseResource("test_FunctionImport.drl");
+
+        assertEquals(2,
+                     pkg.getFunctionImports().size());
+
+        assertEquals("abd.def.x",
+                     ((FunctionImportDescr) 
pkg.getFunctionImports().get(0)).getTarget());
+        assertFalse(((FunctionImportDescr) 
pkg.getFunctionImports().get(0)).getStartCharacter() == -1);
+        assertFalse(((FunctionImportDescr) 
pkg.getFunctionImports().get(0)).getEndCharacter() == -1);
+        assertEquals("qed.wah.*",
+                     ((FunctionImportDescr) 
pkg.getFunctionImports().get(1)).getTarget());
+        assertFalse(((FunctionImportDescr) 
pkg.getFunctionImports().get(1)).getStartCharacter() == -1);
+        assertFalse(((FunctionImportDescr) 
pkg.getFunctionImports().get(1)).getEndCharacter() == -1);
+    }
+
+    @Test
+    public void testFromComplexAcessor() throws Exception {
+        String source = "rule \"Invalid customer id\" ruleflow-group 
\"validate\" lock-on-active true \n" +
+                " when \n" +
+                "     o: Order( ) \n" +
+                "     not( Customer( ) from 
customerService.getCustomer(o.getCustomerId()) ) \n" +
+                " then \n" +
+                "     System.err.println(\"Invalid customer id found!\"); " +
+                "\n" +
+                "     o.addError(\"Invalid customer id\"); \n" +
+                "end \n";
+        PackageDescr pkg = parser.parse(source);
+
+        assertFalse(parser.getErrorMessages().toString(),
+                    parser.hasErrors());
+
+        RuleDescr rule = (RuleDescr) pkg.getRules().get(0);
+        assertEquals("Invalid customer id",
+                     rule.getName());
+
+        assertEquals(2,
+                     rule.getLhs().getDescrs().size());
+
+        NotDescr not = (NotDescr) rule.getLhs().getDescrs().get(1);
+        PatternDescr customer = (PatternDescr) not.getDescrs().get(0);
+
+        assertEquals("Customer",
+                     customer.getObjectType());
+        assertEquals("customerService.getCustomer(o.getCustomerId())",
+                     ((FromDescr) 
customer.getSource()).getDataSource().getText());
     }
 }
diff --git 
a/drools-drl/drools-drl10-parser/src/test/resources/org/drools/parser/globals.drl
 
b/drools-drl/drools-drl10-parser/src/test/resources/org/drools/parser/globals.drl
new file mode 100644
index 0000000000..bc352c77f4
--- /dev/null
+++ 
b/drools-drl/drools-drl10-parser/src/test/resources/org/drools/parser/globals.drl
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2015 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ *      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.compiler.test;
+
+import org.drools.compiler.Cheese;
+
+global java.lang.String foo
+global java.lang.Integer bar;
+
+rule baz
+    when
+        Cheese( )
+    then
+
+end
diff --git 
a/drools-drl/drools-drl10-parser/src/test/resources/org/drools/parser/test_FunctionImport.drl
 
b/drools-drl/drools-drl10-parser/src/test/resources/org/drools/parser/test_FunctionImport.drl
new file mode 100644
index 0000000000..a548a7b4c2
--- /dev/null
+++ 
b/drools-drl/drools-drl10-parser/src/test/resources/org/drools/parser/test_FunctionImport.drl
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2015 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 
+ *      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 HR1
+
+import function abd.def.x
+import function qed.wah.*
+
+rule simple_rule 
+  when
+      not ( Cheese(type == "stilton") )
+      exists ( Foo() )
+  then
+    funky();
+end


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

Reply via email to