org.bndtools.builder.utils.MemberValuePairLocationRetriever Maven / Gradle / Ivy
package org.bndtools.builder.utils;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.SourceRange;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.IAnnotationBinding;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.osgi.util.function.Predicate;
/**
* Visitor that will "visit" an ASTNode and its children until it finds the expected MemberValue pair to retain its
* location in the compilation unit source code
*/
public class MemberValuePairLocationRetriever extends ASTVisitor {
private final IAnnotation javaAnnotation;
private final Predicate annotationNameMatch;
private final String memberName;
private ISourceRange locatedSourceRange = null;
/**
* Constructor
*/
public MemberValuePairLocationRetriever(final IAnnotation javaAnnotation, final Predicate annotationNameMatch, final String memberName) {
this.javaAnnotation = javaAnnotation;
this.annotationNameMatch = annotationNameMatch;
this.memberName = memberName;
}
public ISourceRange getMemberValuePairSourceRange() {
return locatedSourceRange;
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeDeclaration)
*/
@Override
public boolean visit(AnnotationTypeDeclaration node) {
final IJavaElement ancestor = javaAnnotation.getAncestor(IJavaElement.TYPE);
if (ancestor != null && ancestor.exists() && ancestor.getElementName()
.equals(node.getName()
.getFullyQualifiedName())) {
// keep searching
return true;
}
// wrong path, stop searching from this branch of the AST
return false;
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeDeclaration)
*/
@Override
public boolean visit(TypeDeclaration node) {
final IJavaElement ancestor = javaAnnotation.getAncestor(IJavaElement.TYPE);
if (ancestor != null && ancestor.exists() && ancestor.getElementName()
.equals(node.getName()
.getFullyQualifiedName())) {
// keep searching
return true;
}
// wrong path, stop searching from this branch of the AST
return false;
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.FieldDeclaration)
*/
@Override
public boolean visit(VariableDeclarationFragment node) {
final IJavaElement ancestor = javaAnnotation.getAncestor(IJavaElement.FIELD);
if (ancestor != null && ancestor.exists() && ancestor.getElementName()
.equals(node.getName()
.getFullyQualifiedName())) {
// keep searching
return true;
}
// wrong path, stop searching from this branch of the AST
return false;
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodInvocation)
*/
@Override
public boolean visit(MethodDeclaration node) {
final IJavaElement ancestor = javaAnnotation.getAncestor(IJavaElement.METHOD);
if (ancestor != null && ancestor.exists() && ancestor.getElementName()
.equals(node.getName()
.getFullyQualifiedName())) {
// keep searching
return true;
}
// wrong path, stop searching from this branch of the AST
return false;
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SingleMemberAnnotation)
*/
@Override
public boolean visit(SingleMemberAnnotation node) {
final IAnnotationBinding annotationBinding = node.resolveAnnotationBinding();
if (annotationBinding != null) {
final String nodeName = annotationBinding.getAnnotationType()
.getQualifiedName();
boolean match;
try {
match = this.annotationNameMatch.test(nodeName);
} catch (Exception e) {
match = false;
}
if (match) {
this.locatedSourceRange = new SourceRange(node.getValue()
.getStartPosition(),
node.getValue()
.getLength());
}
}
return false;
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.NormalAnnotation)
*/
@Override
public boolean visit(NormalAnnotation node) {
final IJavaElement ancestor = javaAnnotation.getAncestor(IJavaElement.ANNOTATION);
if (ancestor != null && ancestor.exists() && ancestor.getElementName()
.equals(node.getTypeName()
.getFullyQualifiedName())) {
// keep searching
return true;
}
// wrong path, stop searching from this branch of the AST
return false;
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MemberValuePair)
*/
@Override
public boolean visit(MemberValuePair node) {
if (node.getName()
.getFullyQualifiedName()
.equals(memberName)) {
this.locatedSourceRange = new SourceRange(node.getStartPosition(), node.getLength());
}
// no need to drill down from here anyway
return false;
}
}