/*******************************************************************************
* Copyright (c) 2008, 2010 Wind River Systems, Inc. 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:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import org.eclipse.cdt.core.dom.ast.ASTGenericVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeSpecification;
/**
* Visitor to select nodes by image-location.
* @since 5.0
*/
public class FindNodeByImageLocation extends ASTGenericVisitor {
private final int fOffset;
private final int fLength;
private final ASTNodeSpecification<?> fNodeSpec;
public FindNodeByImageLocation(int offset, int length, ASTNodeSpecification<?> nodeSpec) {
super(!nodeSpec.requiresClass(IASTName.class));
fNodeSpec= nodeSpec;
fOffset = offset;
fLength = length;
shouldVisitNames = true;
shouldVisitDeclarations= true;
}
@Override
protected int genericVisit(IASTNode node) {
return processNode(node);
}
private int processNode(IASTNode node) {
if (node instanceof ASTNode) {
final ASTNode astNode = (ASTNode) node;
if (astNode.getOffset() > fOffset+fLength || astNode.getOffset() + astNode.getLength() < fOffset) {
return PROCESS_SKIP;
}
if (fNodeSpec.isAcceptableNode(astNode)) {
IASTImageLocation imageLocation= astNode.getImageLocation();
if (imageLocation != null && imageLocation.getLocationKind() == IASTImageLocation.ARGUMENT_TO_MACRO_EXPANSION) {
fNodeSpec.visit(astNode, imageLocation);
}
}
}
return PROCESS_CONTINUE;
}
@Override
public int visit(IASTDeclaration declaration) {
// use declarations to determine if the search has gone past the
// offset (i.e. don't know the order the visitor visits the nodes)
if (declaration instanceof ASTNode && ((ASTNode) declaration).getOffset() > fOffset + fLength)
return PROCESS_ABORT;
return processNode(declaration);
}
@Override
public int visit(IASTName name) {
if (name.toString() != null)
return processNode(name);
return PROCESS_CONTINUE;
}
}