package org.rubypeople.rdt.internal.ti.util;
import java.util.List;
import org.jruby.ast.Node;
import org.rubypeople.rdt.internal.core.parser.InOrderVisitor;
/**
* Provides basic functionality available to all node locator visitors.
* @author Jason
*
*/
public class NodeLocator extends InOrderVisitor {
/** Stack of names of types (Class/Module) enclosing the visitor cursor as we traverse */
protected List<String> typeNameStack;
/**
* Determines whether the node spans the specified source offset.
* @param node Node to test.
* @param offset Offset to test.
* @return Wthether the node spans the specified offset.
*/
protected boolean nodeDoesSpanOffset(Node node, int offset) {
if (node == null) return false;
if (node.getPosition() == null) return false;
return (node.getPosition().getStartOffset() <= offset)
&& (node.getPosition().getEndOffset() > offset);
}
/**
* Determines the length of the node's span in the source
* @param node Node to test.
* @return Number of characters the specified node spans.
*/
protected int nodeSpanLength(Node node) {
if ( node == null || node.getPosition() == null )
{
return 0;
}
else
{
return node.getPosition().getEndOffset() - node.getPosition().getStartOffset();
}
}
protected void pushType(String typeName) {
typeNameStack.add( 0, typeName );
}
protected void popType() {
if (typeNameStack.isEmpty())
return;
typeNameStack.remove(0);
}
protected String peekType() {
if (typeNameStack.isEmpty())
return null;
return typeNameStack.get(0);
}
}