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]
