package de.plushnikov.intellij.plugin.processor.method;
import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.util.PsiTreeUtil;
import de.plushnikov.intellij.plugin.problem.LombokProblem;
import de.plushnikov.intellij.plugin.problem.ProblemBuilder;
import de.plushnikov.intellij.plugin.problem.ProblemEmptyBuilder;
import de.plushnikov.intellij.plugin.problem.ProblemNewBuilder;
import de.plushnikov.intellij.plugin.processor.AbstractProcessor;
import de.plushnikov.intellij.plugin.util.PsiAnnotationSearchUtil;
import de.plushnikov.intellij.plugin.util.PsiClassUtil;
import org.jetbrains.annotations.NotNull;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* Base lombok processor class for method annotations
*
* @author Tomasz KalkosiĆski
*/
public abstract class AbstractMethodProcessor extends AbstractProcessor implements MethodProcessor {
AbstractMethodProcessor(@NotNull Class<? extends PsiElement> supportedClass, @NotNull Class<? extends Annotation> supportedAnnotationClass, Class<? extends Annotation>... equivalentAnnotationClasses) {
super(supportedClass, supportedAnnotationClass, equivalentAnnotationClasses);
}
@NotNull
@Override
public List<? super PsiElement> process(@NotNull PsiClass psiClass) {
List<? super PsiElement> result = new ArrayList<PsiElement>();
for (PsiMethod psiMethod : PsiClassUtil.collectClassMethodsIntern(psiClass)) {
PsiAnnotation psiAnnotation = PsiAnnotationSearchUtil.findAnnotation(psiMethod, getSupportedAnnotationClasses());
if (null != psiAnnotation) {
if (validate(psiAnnotation, psiMethod, ProblemEmptyBuilder.getInstance())) {
processIntern(psiMethod, psiAnnotation, result);
}
}
}
return result;
}
@NotNull
public Collection<PsiAnnotation> collectProcessedAnnotations(@NotNull PsiClass psiClass) {
List<PsiAnnotation> result = new ArrayList<PsiAnnotation>();
for (PsiMethod psiMethod : PsiClassUtil.collectClassMethodsIntern(psiClass)) {
PsiAnnotation psiAnnotation = PsiAnnotationSearchUtil.findAnnotation(psiMethod, getSupportedAnnotationClasses());
if (null != psiAnnotation) {
result.add(psiAnnotation);
}
}
return result;
}
@NotNull
@Override
public Collection<LombokProblem> verifyAnnotation(@NotNull PsiAnnotation psiAnnotation) {
Collection<LombokProblem> result = Collections.emptyList();
PsiMethod psiMethod = PsiTreeUtil.getParentOfType(psiAnnotation, PsiMethod.class);
if (null != psiMethod) {
ProblemNewBuilder problemNewBuilder = new ProblemNewBuilder();
validate(psiAnnotation, psiMethod, problemNewBuilder);
result = problemNewBuilder.getProblems();
}
return result;
}
protected abstract boolean validate(@NotNull PsiAnnotation psiAnnotation, @NotNull PsiMethod psiMethod, @NotNull ProblemBuilder builder);
protected abstract void processIntern(PsiMethod psiMethod, PsiAnnotation psiAnnotation, List<? super PsiElement> target);
}