/*******************************************************************************
* Copyright (c) 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Zend Technologies
*******************************************************************************/
package org2.eclipse.php.internal.core.ast.locator;
import java.util.List;
import org2.eclipse.php.internal.core.ast.nodes.ASTNode;
import org2.eclipse.php.internal.core.ast.nodes.Program;
import org2.eclipse.php.internal.core.ast.nodes.Statement;
import org2.eclipse.php.internal.core.ast.visitor.ApplyAll;
/**
* Helps finding an AST node for a specific offset
*
* <pre>
* USAGE:
* Statement statement = NodeLocator.locateStatement(program, offset);
* ASTNode node = NodeLocator.locateNode(statement, offset).getLast();
* </pre>
*
* @author Roy, 2007
*/
public class Locator extends ApplyAll {
/**
* @param program
* @param offset
* @return the statement at offset or null if not found
* @throws IllegalArgumentException
* if out of bound
*/
public static Statement locateStatement(Program program, int offset) {
// assert for validty
if (program == null || offset < 0 || program.getLength() < offset) {
throw new IllegalArgumentException();
}
// visit the nodes
List<Statement> statements = program.statements();
for (Statement statement : statements) {
if (inNode(statement, offset)) {
return statement;
}
}
return null;
}
/**
* returns the path to the needed node
*
* @param program
* @param offset
* @return the statement at offset or null if not found
* @throws IllegalArgumentException
* if out of bound
*/
public static synchronized ASTNode locateNode(Program program, int offset) {
// assert for validty
if (program == null || !inNode(program, offset)) {
throw new IllegalArgumentException();
}
final Locator pathLocator = new Locator(offset);
// do the search
program.accept(pathLocator);
// return the result node
return pathLocator.currentNode;
}
private int offset;
private ASTNode currentNode;
private Locator(int offset) {
this.offset = offset;
}
private static final boolean inNode(final ASTNode node, final int offset) {
return offset >= node.getStart()
&& (node.getStart() + node.getLength() > offset);
}
/**
* @param ASTNode
* the node Checks if the node is in the offset if true then
* assign the node to the children' nodes
*/
public boolean apply(ASTNode node) {
assert node != null;
if (inNode(node, offset)) {
this.currentNode = node;
return true;
}
return false;
}
}