package ru.naumen.gintonic.utils;
import java.util.List;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jdt.core.dom.*;
import ru.naumen.gintonic.guice.GuiceConstants;
public class ASTNodeUtils {
public static boolean isAssistedAnnotation(ASTNode node) {
return isMarkerAnnotationAnnotatedWith(node, GuiceConstants.ANNOTATION_ASSISTED);
}
/**
* Resolves the {@link ITypeBinding} for the Ast node.
*
* @param coveringNode
* the ast node.
* @return the type binding or null if the node does not represent a guice
* module.
*/
public static ITypeBinding getTypeBindingIfGuiceModuleCovered(ASTNode node) {
if (node instanceof Name) {
Name name = (Name) node;
ITypeBinding guiceModuleSource = name.resolveTypeBinding();
boolean isGuiceModule = ITypeBindingUtils.isGuiceAbstractModuleType(guiceModuleSource);
if (isGuiceModule) {
return guiceModuleSource;
}
}
return null;
}
/**
* Resolves the {@link ITypeBinding} for the Ast node if the node is a
* {@link Name} and the type is <b>not</b> a Guice module.
*
* @param coveringNode
* the ast node.
* @return the type binding or null if the node does represent a guice
* module.
*/
public static ITypeBinding getTypeBindingIfNotAGuiceModule(ASTNode node) {
if (node instanceof Name) {
Name name = (Name) node;
ITypeBinding guiceModuleSource = name.resolveTypeBinding();
boolean isGuiceModule = ITypeBindingUtils.isGuiceAbstractModuleType(guiceModuleSource);
if (!isGuiceModule) {
return guiceModuleSource;
}
}
return null;
}
public static AnnotationList getAnnotationList(List<ASTNode> modifiers) {
List<Annotation> annotations = ListUtils.newArrayListWithCapacity(modifiers.size());
for (ASTNode modifier : modifiers) {
if (modifier instanceof Annotation) {
annotations.add((Annotation) modifier);
}
}
return new AnnotationList(annotations);
}
private static final class FindMethodByName extends ASTVisitor {
private final String fieldAsSetter;
private List<MethodDeclaration> methodDeclarations = ListUtils.newArrayList();
private FindMethodByName(String fieldAsSetter) {
super(false);
this.fieldAsSetter = fieldAsSetter;
}
@Override
public boolean visit(MethodDeclaration node) {
SimpleName name = node.getName();
String fullyQualifiedName = name.getFullyQualifiedName();
if (fullyQualifiedName.equals(fieldAsSetter)) {
methodDeclarations.add(node);
}
return false;
}
}
/**
* Returns true if the given node is a {@link MarkerAnnotation} and the
* qualified name of its type is equal to the given one.
*
* @param node
* the node
* @param annotationFullyQualified
* the annotation name we compare
*
* @return true if it is annotated with the given type otherwise false.
*/
private static boolean isMarkerAnnotationAnnotatedWith(ASTNode node, String annotationFullyQualified) {
if (node instanceof MarkerAnnotation) {
MarkerAnnotation markerAnnotation = (MarkerAnnotation) node;
ITypeBinding typeBinding = markerAnnotation.resolveTypeBinding();
String qualifiedName = typeBinding.getQualifiedName();
if (qualifiedName.equals(annotationFullyQualified)) {
return true;
}
}
return false;
}
/**
* Checks if the given node is an identifier of a {@link FieldDeclaration}.
* If it is then it is returned, otherwise null is returned.
*
* @param astNode
* the node
* @return the field declaration or null.
*/
public static FieldDeclaration getFieldDeclaration(ASTNode astNode) {
if (!(astNode instanceof Name)) {
return null;
}
Name name = (Name) astNode;
ASTNode parentNode = name.getParent();
if (!(parentNode.getNodeType() == ASTNode.VARIABLE_DECLARATION_FRAGMENT)) {
return null;
}
VariableDeclarationFragment declarationFragment = (VariableDeclarationFragment) parentNode;
ASTNode parentParentNode = declarationFragment.getParent();
if (parentParentNode instanceof FieldDeclaration) {
FieldDeclaration fieldDeclaration = (FieldDeclaration) parentParentNode;
return fieldDeclaration;
}
return null;
}
/**
* Returns the parent of the given node if it is a {@link TypeDeclaration},
* otherwise null.
*/
public static TypeDeclaration getTypeDeclaration(ASTNode astNode) {
ASTNode parentNode = astNode.getParent();
if (parentNode instanceof TypeDeclaration) {
TypeDeclaration typeDeclaration = (TypeDeclaration) parentNode;
return typeDeclaration;
}
return null;
}
public static List<MethodDeclaration> getMethodByName(CompilationUnit astRoot, final String methodName) {
FindMethodByName methodByName = new FindMethodByName(methodName);
astRoot.accept(methodByName);
List<MethodDeclaration> methodDeclarations = methodByName.methodDeclarations;
return methodDeclarations;
}
public static MethodDeclaration getMethodByNameExpectSingleMethod(CompilationUnit astRoot, final String methodName) {
List<MethodDeclaration> methodByName = getMethodByName(astRoot, methodName);
if (methodByName.size() > 0) {
MethodDeclaration methodDeclaration = methodByName.get(0);
return methodDeclaration;
}
return null;
}
@SuppressWarnings("unchecked")
public static boolean isProviderMethod(ASTNode astNode) {
if (astNode instanceof MethodDeclaration) {
MethodDeclaration methodDeclaration = (MethodDeclaration) astNode;
List<ASTNode> modifiers = methodDeclaration.modifiers();
AnnotationList markerAnnotationList = ASTNodeUtils.getAnnotationList(modifiers);
if (markerAnnotationList.containsProvidesAnnotation()) {
return true;
}
}
return false;
}
/**
* @param simpleName
* the not <code>null</code> {@link SimpleName}
*
* @return {@link IVariableBinding} or <code>null</code> for given
* {@link SimpleName}.
*/
public static IVariableBinding getVariableBinding(ASTNode node) {
Assert.isNotNull(node);
// try to get binding from property (copy of binding added by
// DesignerAST)
{
IVariableBinding binding = (IVariableBinding) node.getProperty("VARIABLE_BINDING");
if (binding != null) {
return binding;
}
}
// VariableDeclaration
if (node instanceof VariableDeclaration) {
VariableDeclaration variableDeclaration = (VariableDeclaration) node;
IVariableBinding binding = variableDeclaration.resolveBinding();
if (binding != null) {
return binding;
}
}
// check for SimpleName
if (node instanceof SimpleName) {
SimpleName simpleName = (SimpleName) node;
// get standard binding
{
IBinding binding = simpleName.resolveBinding();
if (binding instanceof IVariableBinding) {
return (IVariableBinding) binding;
}
}
}
// check for FieldAccess
if (node instanceof FieldAccess) {
FieldAccess fieldAccess = (FieldAccess) node;
return fieldAccess.resolveFieldBinding();
}
// not a variable
return null;
}
}