package de.plushnikov.intellij.plugin.processor.clazz.builder; import com.intellij.ide.util.PropertiesComponent; import com.intellij.psi.PsiAnnotation; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import de.plushnikov.intellij.plugin.problem.LombokProblem; import de.plushnikov.intellij.plugin.problem.ProblemBuilder; import de.plushnikov.intellij.plugin.processor.clazz.AbstractClassProcessor; import de.plushnikov.intellij.plugin.processor.handler.BuilderHandler; import de.plushnikov.intellij.plugin.psi.LombokLightClassBuilder; import de.plushnikov.intellij.plugin.settings.ProjectSettings; import de.plushnikov.intellij.plugin.util.PsiAnnotationSearchUtil; import de.plushnikov.intellij.plugin.util.PsiClassUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; public abstract class AbstractBuilderPreDefinedInnerClassProcessor extends AbstractClassProcessor { protected final BuilderHandler builderHandler; AbstractBuilderPreDefinedInnerClassProcessor(@NotNull BuilderHandler builderHandler, @NotNull Class<? extends PsiElement> supportedClass, @NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class<? extends Annotation>... equivalentAnnotationClasses) { super(supportedClass, supportedAnnotationClass, equivalentAnnotationClasses); this.builderHandler = builderHandler; } @Override public boolean isEnabled(@NotNull PropertiesComponent propertiesComponent) { return ProjectSettings.isEnabled(propertiesComponent, ProjectSettings.IS_BUILDER_ENABLED); } @NotNull @Override public List<? super PsiElement> process(@NotNull PsiClass psiClass) { List<? super PsiElement> result = Collections.emptyList(); final PsiElement parentElement = psiClass.getParent(); if (parentElement instanceof PsiClass && !(parentElement instanceof LombokLightClassBuilder)) { result = new ArrayList<PsiElement>(); final PsiClass psiParentClass = (PsiClass) parentElement; PsiAnnotation psiAnnotation = PsiAnnotationSearchUtil.findAnnotation(psiParentClass, getSupportedAnnotationClasses()); if (null == psiAnnotation) { final Collection<PsiMethod> psiMethods = PsiClassUtil.collectClassMethodsIntern(psiParentClass); for (PsiMethod psiMethod : psiMethods) { psiAnnotation = PsiAnnotationSearchUtil.findAnnotation(psiMethod, getSupportedAnnotationClasses()); if (null != psiAnnotation) { processMethodAnnotation(result, psiMethod, psiAnnotation, psiClass, psiParentClass); } } } else { processMethodAnnotation(result, null, psiAnnotation, psiClass, psiParentClass); } } return result; } private void processMethodAnnotation(List<? super PsiElement> result, PsiMethod psiParentMethod, PsiAnnotation psiAnnotation, @NotNull PsiClass psiClass, PsiClass psiParentClass) { // use parent class as source! final String builderClassName = builderHandler.getBuilderClassName(psiParentClass, psiAnnotation, psiParentMethod); // apply only to inner BuilderClass if (builderClassName.equals(psiClass.getName())) { generatePsiElements(psiParentClass, psiParentMethod, psiClass, psiAnnotation, result); } } protected abstract void generatePsiElements(@NotNull PsiClass psiParentClass, @Nullable PsiMethod psiParentMethod, @NotNull PsiClass psiBuilderClass, @NotNull PsiAnnotation psiAnnotation, @NotNull List<? super PsiElement> target); @NotNull @Override public Collection<LombokProblem> verifyAnnotation(@NotNull PsiAnnotation psiAnnotation) { //do nothing return Collections.emptySet(); } @Override protected boolean validate(@NotNull PsiAnnotation psiAnnotation, @NotNull PsiClass psiClass, @NotNull ProblemBuilder builder) { //do nothing return true; } @Override protected void generatePsiElements(@NotNull PsiClass psiClass, @NotNull PsiAnnotation psiAnnotation, @NotNull List<? super PsiElement> target) { //do nothing } }