package com.sleekbyte.tailor.utils;

import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ParseTree;

/**
 * Utils for traversing Parse Trees.
 */
public final class ParseTreeUtil {

    /**
     * Return parent `nval` levels above ctx.
     *
     * @param ctx Child node.
     * @param nval 'n' value, number of levels to go up the tree.
     * @return Parent node or null if parent does not exist.
     */
    public static ParserRuleContext getNthParent(ParserRuleContext ctx, int nval) {
        if (ctx == null) {
            return null;
        }
        while (nval != 0) {
            nval--;
            ctx = ctx.getParent();
            if (ctx == null) {
                return null;
            }
        }
        return ctx;
    }

    /**
     * Returns node's index with in its parent's child array.
     *
     * @param node A child node.
     * @return Node's index or -1 if node is null or doesn't have a parent.
     */
    public static int getNodeIndex(ParseTree node) {
        if (node == null || node.getParent() == null) {
            return -1;
        }
        ParseTree parent = node.getParent();
        for (int i = 0; i < parent.getChildCount(); i++) {
            if (parent.getChild(i) == node) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Gets left sibling of a parse tree node.
     *
     * @param ctx A node.
     * @return Left sibling of a node, or null if no sibling is found.
     */
    public static ParseTree getLeftSibling(ParseTree ctx) {
        int index = ParseTreeUtil.getNodeIndex(ctx);
        if (index < 1) {
            return null;
        }
        return ctx.getParent().getChild(index - 1);
    }

    /**
     * Gets right sibling of a parse tree node.
     *
     * @param ctx A node.
     * @return Right sibling of a node, or null if no sibling is found.
     */
    public static ParseTree getRightSibling(ParseTree ctx) {
        int index = ParseTreeUtil.getNodeIndex(ctx);
        ParseTree parent = ctx.getParent();
        if (index < 0 || index >= parent.getChildCount() - 1) {
            return null;
        }
        return parent.getChild(index + 1);
    }

    /**
     * Gets last child of a parse tree node.
     *
     * @param ctx A node.
     * @return Last child of a node, or null if node has no children.
     */
    public static ParseTree getLastChild(ParseTree ctx) {
        if (ctx.getChildCount() == 0) {
            return null;
        }
        return ctx.getChild(ctx.getChildCount() - 1);
    }
}

@@ -284,33 +284,32 @@
 m ctx Child node
-.
 %0A     * @param n
@@ -357,17 +357,16 @@
 the tree
-.
 %0A     * 
@@ -417,17 +417,16 @@
 ot exist
-.
 %0A     */
@@ -870,25 +870,24 @@
 A child node
-.
 %0A     * @ret
@@ -949,17 +949,16 @@
 a parent
-.
 %0A     */
@@ -1404,33 +1404,32 @@
 param ctx A node
-.
 %0A     * @return 
@@ -1474,33 +1474,32 @@
 sibling is found
-.
 %0A     */%0A    pub
@@ -1802,33 +1802,32 @@
 param ctx A node
-.
 %0A     * @return 
@@ -1881,17 +1881,16 @@
 is found
-.
 %0A     */
@@ -2277,25 +2277,24 @@
 m ctx A node
-.
 %0A     * @ret
@@ -2350,17 +2350,16 @@
 children
-.
 %0A     */

Remove redundant periods