/*
* LinkedListTree.java
*
* Copyright (c) 2006 David Holroyd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package uk.co.badgersinfoil.metaas.impl.antlr;
import org.antlr.runtime.Token;
import org.antlr.runtime.tree.BaseTree;
import org.antlr.runtime.tree.Tree;
public class LinkedListTree extends BaseTree {
public Token token;
private LinkedListTree parent = null;
private LinkedListToken startToken;
private LinkedListToken stopToken;
protected LinkedListToken initialInsertionAfter;
protected LinkedListToken initialInsertionBefore;
private TreeTokenListUpdateDelegate tokenListUpdater;
public LinkedListTree() { }
public LinkedListTree(LinkedListTree node) {
super(node);
this.token = node.token;
}
public LinkedListTree(Token t) {
this.token = t;
}
public TreeTokenListUpdateDelegate getTokenListUpdater() {
return tokenListUpdater;
}
public void setTokenListUpdater(TreeTokenListUpdateDelegate tokenListUpdater) {
this.tokenListUpdater = tokenListUpdater;
}
public void setParent(LinkedListTree parent) {
this.parent = parent;
}
public LinkedListTree getParent() {
return parent;
}
public Tree dupNode() {
return new LinkedListTree(this);
}
public int getType() {
if (token == null) {
return 0;
}
return token.getType();
}
public String getText() {
return toString();
}
public boolean isNil() {
return token==null;
}
public Token getToken() {
return token;
}
public int getLine() {
if (token==null || token.getLine()==0) {
if (getChildCount() > 0) {
return getChild(0).getLine();
}
return 0;
}
return token.getLine();
}
public int getCharPositionInLine() {
if (token==null || token.getCharPositionInLine()==-1) {
if (getChildCount() > 0) {
return getChild(0).getCharPositionInLine();
}
return 0;
}
return token.getCharPositionInLine();
}
public String toString() {
if ( isNil() ) {
return "nil";
}
return token.getText();
}
public LinkedListTree getFirstChild() {
if (getChildCount() == 0) {
return null;
}
return (LinkedListTree)getChild(0);
}
public LinkedListTree getLastChild() {
int c = getChildCount();
if (c == 0) {
return null;
}
return (LinkedListTree)getChild(c-1);
}
public int getIndexOfChild(LinkedListTree child) {
return children.indexOf(child);
}
/**
* Adds the given child node to the end of the list of children
* maintanined by the given parent node, and inserts the tokens
* belonging to child into the tokenlist of parent just after the
* stop-token of the previous last child.
*/
public void addChildWithTokens(LinkedListTree child) {
addChild(child);
tokenListUpdater.addedChild(this, child);
}
public void setChildWithTokens(int index, LinkedListTree child) {
LinkedListTree oldChild = (LinkedListTree)getChild(index);
setChild(index, child);
tokenListUpdater.replacedChild(this, index, child, oldChild);
}
public void addChildWithTokens(int index, LinkedListTree child) {
if (children == null) {
createChildrenList();
}
children.add(index, child);
if (child != null) {
child.setParent(this);
}
tokenListUpdater.addedChild(this, index, child);
}
/**
* @deprecated use #addChildWithTokens(LinkedListTree), damnit
*/
public void addChild(Tree child) {
super.addChild(child);
if (child != null) {
((LinkedListTree)child).setParent(this);
}
}
/**
* @deprecated use #setChildWithTokens(int,LinkedListTree), damnit
*/
public void setChild(int index, BaseTree child) {
super.setChild(index, child);
((LinkedListTree)child).setParent(this);
}
public BaseTree deleteChild(int index) {
LinkedListTree result = (LinkedListTree)super.deleteChild(index);
tokenListUpdater.deletedChild(this, index, result);
result.setParent(null);
return result;
}
public void appendToken(LinkedListToken append) {
tokenListUpdater.appendToken(this, append);
}
public void addToken(int index, LinkedListToken append) {
tokenListUpdater.addToken(this, index, append);
}
public void setInitialInsertionAfter(LinkedListToken insert) {
initialInsertionAfter = insert;
}
public void setInitialInsertionBefore(LinkedListToken insert) {
initialInsertionBefore = insert;
}
public LinkedListToken getInitialInsertionAfter() {
return initialInsertionAfter;
}
public LinkedListToken getInitialInsertionBefore() {
return initialInsertionBefore;
}
public void setStartToken(LinkedListToken startToken) {
if (parent != null) {
parent.notifyChildStartTokenChange(this, startToken);
}
this.startToken = startToken;
}
public LinkedListToken getStartToken() {
return startToken;
}
public LinkedListToken setStopToken(LinkedListToken stopToken) {
if (parent != null) {
parent.notifyChildStopTokenChange(this, stopToken);
}
return this.stopToken = stopToken;
}
public LinkedListToken getStopToken() {
return stopToken;
}
/**
* called when one of this node's children updates it's start-token,
* so that this node can potentially take action; maybe by setting
* the same start-token IF the child was the very-first in this node's
* list of children.
*/
private void notifyChildStartTokenChange(LinkedListTree child, LinkedListToken newStart) {
// TODO: maybe move to delegates
if (isFirst(child) && isSameStartToken(child)) {
setStartToken(newStart);
}
}
private boolean isSameStartToken(LinkedListTree child) {
return child.getStartToken() == getStartToken();
}
private boolean isFirst(LinkedListTree child) {
return child == getFirstChild();
}
/**
* called when one of this node's children updates it's stop-token,
* so that this node can potentially take action; maybe by setting
* the same stop-token IF the child was the very-last in this node's
* list of children.
*/
private void notifyChildStopTokenChange(LinkedListTree child, LinkedListToken newStop) {
// TODO: maybe move to delegates
if (isLast(child) && (isSameStopToken(child) || isNoStopToken(child))) {
setStopToken(newStop);
}
}
private boolean isNoStopToken(LinkedListTree child) {
return child.getStopToken() == null;
}
private boolean isSameStopToken(LinkedListTree child) {
return child.getStopToken() == getStopToken();
}
private boolean isLast(LinkedListTree child) {
return child == getLastChild();
}
public int getTokenStartIndex() {
throw new Error("unimplemented");
}
public int getTokenStopIndex() {
throw new Error("unimplemented");
}
public void setTokenStartIndex(int arg0) {
throw new Error("unimplemented");
}
public void setTokenStopIndex(int arg0) {
throw new Error("unimplemented");
}
}