/** * 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; // Visitor to find the closest node that spans a given offset that satisfies a given condition. // // @author Jason Morrison public class ClosestSpanningNodeLocator extends AbstractNodeLocator { private Node locatedNode; private int offset; private INodeAcceptor acceptor; // Finds the closest spanning node given offset that is accepted by the acceptor. // // +rootNode+ // Root Node that contains all nodes to search. // +offset+ // Offset to search for // +acceptor+ // block returning boolean on whether node fulfills conditions to be able to be selected public Node find(Node root_node, int offset, INodeAcceptor acceptor) { if (root_node == null) { return null; } this.locatedNode = null; this.offset = offset; this.acceptor = acceptor; root_node.accept(this); // Return the match return this.locatedNode; } @Override protected Object handleNode(Node node) { if (this.acceptor.accepts(node)) { if (spansOffset(node, this.offset) && (this.locatedNode == null || (spanLength(node) <= spanLength(this.locatedNode)))) { this.locatedNode = node; } } return super.handleNode(node); } }