/** * Return a list of all ancestors of this node. The first node of list is the root and the last is * the parent of this node. * * @param <T> * @param t * @return */ @NonNull public static List<? extends ParseTree> getAncestors(@NonNull ParseTree t) { if (t.getParent() == null) { return Collections.emptyList(); } List<ParseTree> ancestors = new ArrayList<>(); t = t.getParent(); while (t != null) { ancestors.add(0, t); // insert at start t = t.getParent(); } return ancestors; }
/** * Converts ParseTree (that is generated by ANTLRv4) to DetailNode tree. * * @param parseTreeNode root node of ParseTree * @return root of DetailNode tree */ private DetailNode convertParseTreeToDetailNode(ParseTree parseTreeNode) { final JavadocNodeImpl rootJavadocNode = createRootJavadocNode(parseTreeNode); JavadocNodeImpl currentJavadocParent = rootJavadocNode; ParseTree parseTreeParent = parseTreeNode; while (currentJavadocParent != null) { // remove unnecessary children tokens if (currentJavadocParent.getType() == JavadocTokenTypes.TEXT) { currentJavadocParent.setChildren((DetailNode[]) JavadocNodeImpl.EMPTY_DETAIL_NODE_ARRAY); } final JavadocNodeImpl[] children = (JavadocNodeImpl[]) currentJavadocParent.getChildren(); insertChildrenNodes(children, parseTreeParent); if (children.length > 0) { currentJavadocParent = children[0]; parseTreeParent = parseTreeParent.getChild(0); } else { JavadocNodeImpl nextJavadocSibling = (JavadocNodeImpl) JavadocUtils.getNextSibling(currentJavadocParent); ParseTree nextParseTreeSibling = getNextSibling(parseTreeParent); if (nextJavadocSibling == null) { JavadocNodeImpl tempJavadocParent = (JavadocNodeImpl) currentJavadocParent.getParent(); ParseTree tempParseTreeParent = parseTreeParent.getParent(); while (nextJavadocSibling == null && tempJavadocParent != null) { nextJavadocSibling = (JavadocNodeImpl) JavadocUtils.getNextSibling(tempJavadocParent); nextParseTreeSibling = getNextSibling(tempParseTreeParent); tempJavadocParent = (JavadocNodeImpl) tempJavadocParent.getParent(); tempParseTreeParent = tempParseTreeParent.getParent(); } } currentJavadocParent = nextJavadocSibling; parseTreeParent = nextParseTreeSibling; } } return rootJavadocNode; }
/** * Gets whether or not {@code a} is an ancestor of or equal to {@code b}. * * @param a The first tree. * @param b The second tree. * @return {@code true} if {@code a} is an ancestor of or is equal to {@code b}, otherwise {@code * false}. */ public static boolean isAncestorOf(@NonNull ParseTree a, @NonNull ParseTree b) { for (ParseTree current = b; current != null; current = current.getParent()) { if (current.equals(a)) { return true; } } return false; }
/** * Gets next sibling of ParseTree node. * * @param node ParseTree node * @return next sibling of ParseTree node. */ private static ParseTree getNextSibling(ParseTree node) { ParseTree nextSibling = null; if (node.getParent() != null) { final ParseTree parent = node.getParent(); final int childCount = parent.getChildCount(); int index = 0; while (true) { final ParseTree currentNode = parent.getChild(index); if (currentNode.equals(node)) { if (index != childCount - 1) { nextSibling = parent.getChild(index + 1); } break; } index++; } } return nextSibling; }
@CheckForNull public static RuleNode findAncestor(@NonNull ParseTree tree, int ruleIndex) { for (ParseTree current = tree; current != null; current = current.getParent()) { if (!(current instanceof RuleNode)) { continue; } RuleNode ruleNode = (RuleNode) current; if (ruleNode.getRuleContext().getRuleIndex() == ruleIndex) { return ruleNode; } } return null; }
@CheckForNull public static <ContextClass> ContextClass findAncestor( @NonNull ParseTree tree, @NonNull Class<ContextClass> nodeType) { for (ParseTree current = tree; current != null; current = current.getParent()) { if (!(current instanceof RuleNode)) { continue; } RuleNode ruleNode = (RuleNode) current; RuleContext ruleContext = ruleNode.getRuleContext(); if (nodeType.isInstance(ruleContext)) { return nodeType.cast(ruleContext); } } return null; }