package de.plushnikov.intellij.plugin.action.generate; import com.intellij.codeInsight.daemon.ImplicitUsageProvider; import com.intellij.codeInsight.generation.ClassMember; import com.intellij.codeInsight.generation.GenerateConstructorHandler; import com.intellij.codeInsight.generation.GenerationInfo; import com.intellij.codeInsight.generation.PsiFieldMember; import com.intellij.codeInsight.generation.PsiGenerationInfo; import com.intellij.openapi.extensions.Extensions; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiField; import com.intellij.psi.PsiMember; import com.intellij.psi.PsiModifier; import com.intellij.util.IncorrectOperationException; import de.plushnikov.intellij.plugin.provider.LombokImplicitUsageProvider; import de.plushnikov.intellij.plugin.psi.LombokLightMethodBuilder; import org.jetbrains.annotations.NotNull; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.List; public class LombokGenerateConstructorHandler extends GenerateConstructorHandler { @Override protected ClassMember[] getAllOriginalMembers(PsiClass aClass) { PsiField[] fields = aClass.getFields(); ArrayList<ClassMember> array = new ArrayList<ClassMember>(); ImplicitUsageProvider[] implicitUsageProviders = Extensions.getExtensions(ImplicitUsageProvider.EP_NAME); fieldLoop: for (PsiField field : fields) { if (field.hasModifierProperty(PsiModifier.STATIC)) { continue; } if (field.hasModifierProperty(PsiModifier.FINAL) && field.getInitializer() != null) { continue; } for (ImplicitUsageProvider provider : implicitUsageProviders) { if (!(provider instanceof LombokImplicitUsageProvider) && provider.isImplicitWrite(field)) { continue fieldLoop; } } array.add(new PsiFieldMember(field)); } return array.toArray(new ClassMember[array.size()]); } @Override @NotNull protected List<? extends GenerationInfo> generateMemberPrototypes(PsiClass aClass, ClassMember[] members) throws IncorrectOperationException { final PsiClass proxyClass = proxying(aClass, PsiClass.class); final List<? extends GenerationInfo> memberPrototypes = super.generateMemberPrototypes(proxyClass, members); final List<GenerationInfo> result = new ArrayList<GenerationInfo>(); for (GenerationInfo memberPrototype : memberPrototypes) { result.add(new PsiGenerationInfo<PsiMember>(memberPrototype.getPsiMember(), false)); } return result; } @SuppressWarnings("unchecked") private <T> T proxying(final T target, final Class<T> iface) { return (T) Proxy.newProxyInstance( iface.getClassLoader(), new Class<?>[]{iface}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { final Object originalResult = method.invoke(target, args); if (method.getName().equals("findMethodBySignature")) { if (originalResult instanceof LombokLightMethodBuilder) { return null; } } return originalResult; } }); } }