Package de.plushnikov.intellij.lombok.processor.clazz

Source Code of de.plushnikov.intellij.lombok.processor.clazz.AutoGenMethodStubProcessor

package de.plushnikov.intellij.lombok.processor.clazz;

import com.intellij.codeInsight.generation.OverrideImplementUtil;
import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.PsiSubstitutor;
import com.intellij.psi.infos.CandidateInfo;
import de.plushnikov.intellij.lombok.ErrorMessages;
import de.plushnikov.intellij.lombok.problem.ProblemBuilder;
import de.plushnikov.intellij.lombok.psi.LombokLightMethodBuilder;
import de.plushnikov.intellij.lombok.psi.LombokPsiElementFactory;
import lombok.AutoGenMethodStub;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.List;

/**
* Inspect and validate @AutoGenMethodStub lombok-pg annotation on a class
* Creates methods for all of unimplemented methods of the annotated type and create method stubs for all of them
*
* @author Plushnikov Michail
*/
public class AutoGenMethodStubProcessor extends AbstractLombokClassProcessor {
  public AutoGenMethodStubProcessor() {
    super(AutoGenMethodStub.class, PsiMethod.class);
  }

  @Override
  protected boolean validate(@NotNull PsiAnnotation psiAnnotation, @NotNull PsiClass psiClass, @NotNull ProblemBuilder builder) {
    return validateAnnotationOnRightType(psiClass, builder);
  }

  protected boolean validateAnnotationOnRightType(@NotNull final PsiClass psiClass, @NotNull final ProblemBuilder builder) {
    boolean result = true;
    if (psiClass.isAnnotationType() || psiClass.isInterface()) {
      builder.addError(ErrorMessages.canBeUsedOnClassAndEnumOnly(getSupportedAnnotationClass()));
      result = false;
    }
    return result;
  }

  protected <Psi extends PsiElement> void processIntern(@NotNull final PsiClass psiClass, @NotNull final PsiAnnotation psiAnnotation, @NotNull final List<Psi> target) {
    //todo reimplement this to get it working
    final Collection<CandidateInfo> candidateInfos = OverrideImplementUtil.getMethodsToOverrideImplement(psiClass, true);
    for (CandidateInfo candidateInfo : candidateInfos) {

      PsiMethod implementedMethod = createImplementingMethod(candidateInfo, psiClass, psiAnnotation);

      if (null != implementedMethod) {
        target.add((Psi) implementedMethod);
      }
    }
  }

  private <Psi extends PsiElement> PsiMethod createImplementingMethod(CandidateInfo candidateInfo, PsiClass psiClass, PsiAnnotation psiAnnotation) {
    final PsiMethod methodToImplement = (PsiMethod) candidateInfo.getElement();
    final PsiSubstitutor substitutor = candidateInfo.getSubstitutor();
    if (null != methodToImplement && null != substitutor) {
      final LombokPsiElementFactory lombokPsiElementFactory = LombokPsiElementFactory.getInstance();
      final String methodName = methodToImplement.getName();
      LombokLightMethodBuilder method = lombokPsiElementFactory.createLightMethod(psiClass.getManager(), methodName)
          .withMethodReturnType(substitutor.substitute(methodToImplement.getReturnType()))
          .withContainingClass(psiClass)
          .withNavigationElement(psiAnnotation);
      addModifier(methodToImplement, method, PsiModifier.PUBLIC);
      addModifier(methodToImplement, method, PsiModifier.PACKAGE_LOCAL);
      addModifier(methodToImplement, method, PsiModifier.PROTECTED);

      for (PsiParameter psiParameter : methodToImplement.getParameterList().getParameters()) {
        method.withParameter(psiParameter.getName(), substitutor.substitute(psiParameter.getType()));
      }

      for (PsiClassType psiClassType : methodToImplement.getThrowsList().getReferencedTypes()) {
        method.withException(psiClassType);
      }

      return method;
    }
    return null;
  }

  private void addModifier(PsiMethod psiMethod, LombokLightMethodBuilder method, String modifier) {
    if (psiMethod.hasModifierProperty(modifier)) {
      method.withModifier(modifier);
    }
  }

}
TOP

Related Classes of de.plushnikov.intellij.lombok.processor.clazz.AutoGenMethodStubProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.