// =====================================================================
//
// Copyright (C) 2012 - 2016, Philip Graf
//
// 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
//
// =====================================================================
package ch.acanda.eclipse.pmd.java.resolution;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jface.text.Position;
import com.google.common.base.Optional;
/**
* Searches an AST for a node that has the provided type and lies within the provided position. If more than one node
* fit the criteria, the one with the smallest distance to the root is returned.
*/
class NodeWithinPositionNodeFinder<R extends ASTNode, N extends ASTNode> extends ASTVisitor implements NodeFinder<R, N> {
private final int start;
private final int end;
private final Class<? extends N> nodeType;
private N node;
public NodeWithinPositionNodeFinder(final Position position, final Class<? extends N> nodeType) {
start = position.getOffset();
end = start + position.getLength();
this.nodeType = nodeType;
}
@Override
public boolean preVisit2(final ASTNode node) {
if (this.node != null) {
return false;
}
final int nodeStart = node.getStartPosition();
final int nodeEnd = nodeStart + node.getLength();
if (start <= nodeStart && nodeEnd <= end) {
if (nodeType.isAssignableFrom(node.getClass())) {
this.node = nodeType.cast(node);
return false;
}
return true;
}
return nodeStart <= start && end <= nodeEnd;
}
@Override
public Optional<N> findNode(final R ast) {
node = null;
ast.accept(this);
return Optional.fromNullable(node);
}
}