/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.ast;
import net.sourceforge.pmd.lang.ast.AbstractNode;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.SourceCodePositioner;
import apex.jorje.data.Loc;
import apex.jorje.data.Loc.RealLoc;
import apex.jorje.semantic.ast.AstNode;
import apex.jorje.semantic.exception.UnexpectedCodePathException;
public abstract class AbstractApexNode<T extends AstNode> extends AbstractNode implements ApexNode<T> {
protected final T node;
public AbstractApexNode(T node) {
super(node.getClass().hashCode());
this.node = node;
}
void calculateLineNumbers(SourceCodePositioner positioner) {
if (!hasRealLoc()) {
return;
}
RealLoc loc = (RealLoc) node.getLoc();
int startOffset = loc.startIndex;
int endOffset = loc.endIndex;
// end column will be interpreted as inclusive, while endOffset/endIndex
// is exclusive
endOffset -= 1;
this.beginLine = positioner.lineNumberFromOffset(startOffset);
this.beginColumn = positioner.columnFromOffset(this.beginLine, startOffset);
this.endLine = positioner.lineNumberFromOffset(endOffset);
this.endColumn = positioner.columnFromOffset(this.endLine, endOffset);
if (this.endColumn < 0) {
this.endColumn = 0;
}
}
@Override
public int getBeginLine() {
if (this.beginLine > 0) {
return this.beginLine;
}
Node parent = jjtGetParent();
if (parent != null) {
return parent.getBeginLine();
}
throw new RuntimeException("Unable to determine beginning line of Node.");
}
@Override
public int getBeginColumn() {
if (this.beginColumn > 0) {
return this.beginColumn;
}
Node parent = jjtGetParent();
if (parent != null) {
return parent.getBeginColumn();
}
throw new RuntimeException("Unable to determine beginning column of Node.");
}
@Override
public int getEndLine() {
if (this.endLine > 0) {
return this.endLine;
}
Node parent = jjtGetParent();
if (parent != null) {
return parent.getEndLine();
}
throw new RuntimeException("Unable to determine ending line of Node.");
}
@Override
public int getEndColumn() {
if (this.endColumn > 0) {
return this.endColumn;
}
Node parent = jjtGetParent();
if (parent != null) {
return parent.getEndColumn();
}
throw new RuntimeException("Unable to determine ending column of Node.");
}
/**
* Accept the visitor. *
*/
public Object childrenAccept(ApexParserVisitor visitor, Object data) {
if (children != null) {
for (int i = 0; i < children.length; ++i) {
@SuppressWarnings("unchecked")
// we know that the children here are all ApexNodes
ApexNode<T> apexNode = (ApexNode<T>) children[i];
apexNode.jjtAccept(visitor, data);
}
}
return data;
}
public T getNode() {
return node;
}
protected boolean hasRealLoc() {
try {
Loc loc = node.getLoc();
return loc instanceof RealLoc;
} catch (UnexpectedCodePathException e) {
return false;
} catch (IndexOutOfBoundsException e) {
// bug in apex-jorje? happens on some ReferenceExpression nodes
return false;
} catch (NullPointerException e) {
// bug in apex-jorje?
return false;
}
}
@Override
public String toString() {
return this.getClass().getSimpleName().replaceFirst("^AST", "");
}
public String getLocation() {
if (hasRealLoc()) {
return String.valueOf(node.getLoc());
} else {
return "no location";
}
}
}