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 b2c4b45b7d41827a7728c2f37f1edf51965d88e0
Author: mariofusco <[email protected]>
AuthorDate: Thu Jan 27 14:01:07 2022 +0100

    improve node position discovery
---
 .../java/org/drools/parser/DRLParserHelper.java    | 54 ++++++++++++++++++++--
 .../test/java/org/drools/parser/DRLParserTest.java | 42 ++++++++---------
 2 files changed, 71 insertions(+), 25 deletions(-)

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 826517a0c2..421624010c 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
@@ -31,18 +31,43 @@ public class DRLParserHelper {
     }
 
     public static ParseTree findNodeAtPosition(ParseTree root, int row, int 
col) {
+        ParseTree lastChild = null;
         for (int i = 0; i < root.getChildCount(); i++) {
             ParseTree child = root.getChild(i);
-            Token stopToken = child instanceof TerminalNode ? 
((TerminalNode)child).getSymbol() : ((ParserRuleContext)child).getStop();
 
-            if (endsAfter(stopToken, row, col)) {
+            if (i > 0 && startsAfter(child, row, col)) {
+                return findNodeAtPosition(lastChild, row, col);
+            }
+
+            if (endsAfter(child, row, col)) {
                 return findNodeAtPosition(child, row, col);
             }
+
+            lastChild = child;
         }
         return root;
     }
 
-    private static boolean endsAfter(Token token, int row, int col) {
+    public static Token getStartToken(ParseTree child) {
+        return child instanceof TerminalNode ? ((TerminalNode) 
child).getSymbol() : ((ParserRuleContext) child).getStart();
+    }
+
+    public static Token getStopToken(ParseTree child) {
+        return child instanceof TerminalNode ? ((TerminalNode) 
child).getSymbol() : ((ParserRuleContext) child).getStop();
+    }
+
+    private static boolean endsBefore(ParseTree node, int row, int col) {
+        Token token = getStopToken(node);
+        if (token.getLine() != row) {
+            return token.getLine() < row;
+        }
+        int tokenLength = (token.getStopIndex() - token.getStartIndex()) + 1;
+        int lastTokenPosition = token.getCharPositionInLine() + tokenLength;
+        return lastTokenPosition < col;
+    }
+
+    private static boolean endsAfter(ParseTree node, int row, int col) {
+        Token token = getStopToken(node);
         if (token.getLine() != row) {
             return token.getLine() > row;
         }
@@ -51,6 +76,14 @@ public class DRLParserHelper {
         return lastTokenPosition >= col;
     }
 
+    private static boolean startsAfter(ParseTree node, int row, int col) {
+        Token token = getStartToken(node);
+        if (token.getLine() != row) {
+            return token.getLine() > row;
+        }
+        return token.getCharPositionInLine() > col;
+    }
+
     public static boolean hasParentOfType(ParseTree leaf, int type) {
         return findParentOfType(leaf, type) != null;
     }
@@ -61,4 +94,19 @@ public class DRLParserHelper {
         }
         return findParentOfType(leaf.getParent(), type);
     }
+
+    public static int symbolType(ParseTree node) {
+        if (node instanceof TerminalNode) {
+            return ((TerminalNode) node).getSymbol().getType();
+        }
+        return -1;
+    }
+
+    public static boolean isSymbol(ParseTree node, int symbol) {
+        return symbolType(node) == symbol;
+    }
+
+    public static boolean isAfterSymbol(ParseTree node, int symbol, int row, 
int col) {
+        return isSymbol(node, symbol) && endsBefore(node, row, col);
+    }
 }
diff --git 
a/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/DRLParserTest.java
 
b/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/DRLParserTest.java
index 4e4e27e8d7..fc99fc644c 100644
--- 
a/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/DRLParserTest.java
+++ 
b/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/DRLParserTest.java
@@ -8,22 +8,24 @@ import org.junit.Test;
 import static org.drools.parser.DRLParserHelper.createParseTree;
 import static org.drools.parser.DRLParserHelper.findNodeAtPosition;
 import static org.drools.parser.DRLParserHelper.findParentOfType;
+import static org.drools.parser.DRLParserHelper.isAfterSymbol;
 import static org.drools.parser.DRLParserHelper.parse;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 public class DRLParserTest {
 
+    private static final String drl =
+            "package org.test;\n" +
+            "import org.test.model.Person;\n" +
+            "rule TestRule when \n" +
+            "  $p:Person()\n" +
+            "then\n" +
+            "  System.out.println($p.getName());\n" +
+            "end\n";
+
     @Test
     public void testParse() {
-        String drl =
-                "package org.test;\n" +
-                "import org.test.model.Person;\n" +
-                "rule TestRule when\n" +
-                "  $p:Person()\n" +
-                "then\n" +
-                "  System.out.println($p.getName());\n" +
-                "end\n";
-
         PackageDescr packageDescr = parse(drl);
         assertEquals("org.test", packageDescr.getName());
 
@@ -37,23 +39,19 @@ public class DRLParserTest {
 
     @Test
     public void testCursorPosition() {
-        String drl =
-                "package org.test;\n" +
-                "import org.test.model.Person;\n" +
-                "rule TestRule when\n" +
-                "  $p:Person()\n" +
-                "then\n" +
-                "  System.out.println($p.getName());\n" +
-                "end\n";
-
-        int row = 4;
-        int col = 7;
-
         ParseTree parseTree = createParseTree(drl);
-        ParseTree node = findNodeAtPosition(parseTree, row, col);
+        ParseTree node = findNodeAtPosition(parseTree, 4, 7);
         assertEquals("Person", node.getText());
         ParseTree lhs = findParentOfType(node, DRLParser.RULE_lhs);
         assertEquals(DRLParser.RULE_lhs, ((RuleContext) lhs).getRuleIndex());
         assertEquals("$p:Person()", lhs.getText());
     }
+
+    @Test
+    public void testCursorPosition2() {
+        ParseTree parseTree = createParseTree(drl);
+        ParseTree node = findNodeAtPosition(parseTree, 3, 19);
+        assertEquals("when", node.getText());
+        assertTrue(isAfterSymbol(node, DRLParser.WHEN, 3, 19));
+    }
 }


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

Reply via email to