package org.pdtextensions.core.ast.util;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.Assert;
import org.eclipse.php.core.ast.match.ASTMatcher;
import org.eclipse.php.core.ast.nodes.ASTNode;
import org.eclipse.php.core.ast.nodes.Block;
import org.eclipse.php.core.ast.nodes.ReturnType;
public class BlockContainsFinder extends GenericVisitor {
private Block fStartNode;
private ASTNode[] fToSearch;
private int fIndex;
private Match fMatch;
private ASTMatcher fMatcher;
private List<Match> fResult;
public static class Match {
private List<ASTNode> fNodes;
public Match() {
fNodes= new ArrayList<ASTNode>();
}
public void add(ASTNode node) {
fNodes.add(node);
}
public ASTNode[] getNodes() {
return fNodes.toArray(new ASTNode[fNodes.size()]);
}
public boolean isEmpty() {
return fNodes.isEmpty();
}
}
public BlockContainsFinder(Block coveringNode, ASTNode[] toSearchIsomorphic)
{
Assert.isNotNull(coveringNode);
Assert.isLegal(toSearchIsomorphic.length > 0);
fStartNode = coveringNode;
fToSearch = toSearchIsomorphic;
}
public void perform()
{
fResult = new ArrayList<Match>();
fMatcher = new ASTMatcher();
reset();
fStartNode.accept(this);
}
protected boolean visitNode(ASTNode node)
{
// check whether the node matches
if(matches(node)) {
return false;
// if the node did not match and it wasn't the first
// to search node, then reset and try to match again.
} else if(!isResetted()) {
reset();
if(matches(node)) {
return false;
}
}
return true;
}
private boolean isResetted() {
return fIndex == 0 && fMatch.isEmpty();
}
private boolean matches(ASTNode node) {
if (fToSearch[fIndex].subtreeMatch(fMatcher, node) ) {
fMatch.add(node);
fIndex++;
// all search nodes found, add it to result and
// reset, s.t we can search for the next nodes...
if (fIndex == fToSearch.length) {
fResult.add(fMatch);
reset();
}
return true;
}
return false;
}
private void reset()
{
fIndex = 0;
fMatch = new Match();
}
public List<Match> getMatches()
{
return fResult;
}
}