FortranNode.java

/**
 * 
 */
package fortran.ofp.parser.java;

import java.util.ArrayList;
import java.util.List;

import org.antlr.runtime.Token;

/**
 * @author Wenhao Wu
 *
 */
public class FortranNode {

	private static boolean TEXT_ONLY = true;

	private static long COUNT = 0;

	private long id;

	private int index;

	private int childIndex;

	private Token[] tokens;

	private int rule;

	private String nodeName;

	private FortranNode parent;

	private ArrayList<FortranNode> children;

	// Constructor
	public FortranNode(int rule, String name, Token... tokens) {
		id = COUNT++;
		index = -1;
		childIndex = -1;
		this.tokens = tokens;
		this.rule = rule;
		this.nodeName = name;
		parent = null;
		children = new ArrayList<FortranNode>();
	}

	// Functions:
	public long COUNT() {
		return COUNT;
	}

	public long id() {
		return id;
	}

	public int index() {
		return index;
	}

	public void setIndex(int index) {
		this.index = index;
	}

	public int childIndex() {
		return childIndex;
	}

	public void setChildIndex(int newIndex) {
		childIndex = newIndex;
	}

	public Token[] tokens() {
		return tokens;
	}

	public int rule() {
		return rule;
	}

	public void setRule(int rule) {
		this.rule = rule;
	}

	public String nodeName() {
		return nodeName;
	}

	public void setNodeName(String nodeName) {
		this.nodeName = nodeName;
	}

	public FortranNode parent() {
		return parent;
	}

	public void setParent(FortranNode parent) {
		this.parent = parent;
	}

	public Iterable<FortranNode> children() {
		return children;
	}

	public int numChildren() {
		return children.size();
	}

	public void addChild(int index, FortranNode newChild) {
		assert newChild != null;
		assert newChild.parent == null;
		assert index >= 0 && index <= children.size();

		newChild.parent = this;
		newChild.childIndex = index;
		children.add(index, newChild);
		index++;
		while (index < children.size()) {
			children.get(index).childIndex++;
			index++;
		}
	}

	public int addChild(FortranNode newChild) {
		assert newChild != null;
		assert newChild.parent == null;

		int index = children.size();

		newChild.parent = this;
		newChild.childIndex = index;
		children.add(newChild);

		return index;
	}

	public FortranNode setChild(int index, FortranNode newChild) {
		assert newChild != null;
		assert newChild.parent == null;

		FortranNode oldChild = null;
		int numChildren = children.size();

		assert index >= 0 && index < numChildren;
		index = Math.min(index, numChildren - 1);
		index = Math.max(index, 0);
		oldChild = children.get(index);
		oldChild.parent = null;
		oldChild.childIndex = -1;
		newChild.parent = this;
		newChild.childIndex = index;
		children.set(index, newChild);
		return oldChild;
	}

	public void insertChildrenAt(int start,
			List<? extends FortranNode> newChildren) {
		int i = 0;
		int oldSize = children.size();
		int numNewChildren = newChildren.size();
		int newSize = oldSize + numNewChildren;

		assert start >= 0 && start <= oldSize;
		children.addAll(start, newChildren);
		for (i = start; i < start + numNewChildren; i++) {
			FortranNode newChild = children.get(i);

			assert newChild != null;
			assert newChild.parent == null;
			newChild.parent = this;
			newChild.childIndex = i;
		}
		for (; i < newSize; i++) {
			FortranNode child = children.get(i);

			assert child != null;
			child.childIndex = i;
		}
	}

	public void remove() {
		if (children != null)
			parent.removeChild(childIndex);
	}

	public FortranNode removeChild(int index) {
		int numChildren = children.size();
		FortranNode oldChild = null;

		assert index >= 0 && index < numChildren;
		oldChild = children.get(index);
		assert oldChild != null;
		oldChild.parent = null;
		oldChild.childIndex = -1;
		children.remove(index);
		return oldChild;
	}

	public FortranNode getChildByIndex(int index) {
		return children.get(index);
	}

	public String toString() {
		String result = "";

		FortranNode temp = this;
		while (temp.parent != null) {
			temp = temp.parent;
			result += "| ";
		}

		result += "{";
		// result += "(ID:" + id + ")";
		if (parent == null) {
			result += "Root";
		} else if (parent.childIndex < 0) {
			// result += "R";
			result += "[" + childIndex + "]";
		} else {
			// result += parent.childIndex;
			result += "[" + childIndex + "]";
			// result += parent.nodeKind;
		}
		result += ": ";
		result += this.id;
		result += "[" + nodeName + "]";
		if (tokens != null && tokens.length > 0) {
			result += "<";
			for (Token t : tokens) {
				if (t != null) {
					if (TEXT_ONLY) {
						result += t.getText();
					} else {
						result += t.toString();
					}
				} else {
					result += "null";
				}
			}
			result += ">";
		}
		result += "}\n";
		if (numChildren() > 0) {
			for (FortranNode i : children) {
				if (i != null)
					result += i.toString();
			}
		}
		return result;
	}

	public void printNode() {
		System.out.print(this.toString());
	}
}