/**
* Aptana Studio
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the GNU Public License (GPL) v3 (with exceptions).
* Please see the license.html included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
package com.aptana.ruby.core.ast;
import org.jrubyparser.ast.Node;
public class FirstPrecursorNodeLocator extends AbstractNodeLocator
{
private int offset;
private INodeAcceptor acceptor;
private Node locatedNode;
// Finds the first node preceding the given offset that is accepted by the acceptor.
// +param+ rootNode
// Root Node that contains all nodes to search.
// +param+ offset
// Offset to search backwards from; returned node must occur strictly before this (i.e. end before offset.)
// +param+ acceptor
// block defining the condition which the desired node fulfills.
// @return First precursor or nil.
public Node find(Node root_node, int offset, INodeAcceptor acceptor)
{
this.locatedNode = null;
this.offset = offset;
this.acceptor = acceptor;
// Traverse to find closest precursor
root_node.accept(this);
// Return the match
return this.locatedNode;
}
@Override
protected Object handleNode(Node node)
{
// TODO This will include nodes that envelop nodeStart, not only those starting strictly before it.
// If this behavior is unwanted, remove the || (node.position.start_offset <= offset)
// in the conditional
if ((node.getPosition().getEndOffset() <= this.offset) || (node.getPosition().getStartOffset() <= this.offset))
{
if (acceptor.accepts(node))
{
this.locatedNode = node;
}
}
return super.handleNode(node);
}
}