diff --git a/plugins/lombok/src/main/java/de/plushnikov/intellij/plugin/processor/handler/SuperBuilderHandler.java b/plugins/lombok/src/main/java/de/plushnikov/intellij/plugin/processor/handler/SuperBuilderHandler.java index 6f9bfa4bbe50..d028ebc9995c 100644 --- a/plugins/lombok/src/main/java/de/plushnikov/intellij/plugin/processor/handler/SuperBuilderHandler.java +++ b/plugins/lombok/src/main/java/de/plushnikov/intellij/plugin/processor/handler/SuperBuilderHandler.java @@ -9,6 +9,7 @@ import de.plushnikov.intellij.plugin.problem.ProblemSink; import de.plushnikov.intellij.plugin.processor.clazz.ToStringProcessor; import de.plushnikov.intellij.plugin.psi.LombokLightClassBuilder; import de.plushnikov.intellij.plugin.psi.LombokLightMethodBuilder; +import de.plushnikov.intellij.plugin.quickfix.PsiQuickFixFactory; import de.plushnikov.intellij.plugin.util.PsiAnnotationSearchUtil; import de.plushnikov.intellij.plugin.util.PsiAnnotationUtil; import de.plushnikov.intellij.plugin.util.PsiClassUtil; @@ -41,20 +42,22 @@ public class SuperBuilderHandler extends BuilderHandler { public boolean validateExistingBuilderClass(@NotNull String builderClassName, @NotNull PsiClass psiClass, @NotNull ProblemSink problemSink) { - final Optional existingInnerBuilderClass = PsiClassUtil.getInnerClassInternByName(psiClass, builderClassName); + final Optional existingInnerBuilderClassOptional = PsiClassUtil.getInnerClassInternByName(psiClass, builderClassName); - if (existingInnerBuilderClass.isPresent()) { + if (existingInnerBuilderClassOptional.isPresent()) { - if (!validateInvalidAnnotationsOnBuilderClass(existingInnerBuilderClass.get(), problemSink)) { + final PsiClass existingInnerBuilderClass = existingInnerBuilderClassOptional.get(); + if (!validateInvalidAnnotationsOnBuilderClass(existingInnerBuilderClass, problemSink)) { return false; } - final Optional isStaticAndAbstract = existingInnerBuilderClass - .filter(psiInnerClass -> psiInnerClass.hasModifierProperty(PsiModifier.STATIC)) - .filter(psiInnerClass -> psiInnerClass.hasModifierProperty(PsiModifier.ABSTRACT)); + final boolean isStaticAndAbstract = existingInnerBuilderClass.hasModifierProperty(PsiModifier.STATIC) && + existingInnerBuilderClass.hasModifierProperty(PsiModifier.ABSTRACT); - if (isStaticAndAbstract.isEmpty()) { - problemSink.addErrorMessage("inspection.message.existing.builder.must.be.abstract.static.inner.class"); + if (!isStaticAndAbstract) { + problemSink.addErrorMessage("inspection.message.existing.builder.must.be.abstract.static.inner.class") + .withLocalQuickFixes(() -> PsiQuickFixFactory.createModifierListFix(existingInnerBuilderClass, PsiModifier.ABSTRACT, true, false), + () -> PsiQuickFixFactory.createModifierListFix(existingInnerBuilderClass, PsiModifier.STATIC, true, false)); return false; } } @@ -333,7 +336,8 @@ public class SuperBuilderHandler extends BuilderHandler { final String callSuperCode = "super." + FILL_VALUES_METHOD_NAME + "(" + INSTANCE_VARIABLE_NAME + ");\n"; final String codeBlockText = String.format("%s%s.%s(%s, this);\nreturn self();", forceCallSuper ? callSuperCode : "", - baseClassBuilder.getQualifiedName(), STATIC_FILL_VALUES_METHOD_NAME, INSTANCE_VARIABLE_NAME); + baseClassBuilder.getQualifiedName(), STATIC_FILL_VALUES_METHOD_NAME, + INSTANCE_VARIABLE_NAME); methodBuilder.withBodyText(codeBlockText); result.add(methodBuilder); diff --git a/plugins/lombok/src/test/java/de/plushnikov/intellij/plugin/inspection/SuperBuilderQuickFixTest.java b/plugins/lombok/src/test/java/de/plushnikov/intellij/plugin/inspection/SuperBuilderQuickFixTest.java new file mode 100644 index 000000000000..d64f5f55c6c6 --- /dev/null +++ b/plugins/lombok/src/test/java/de/plushnikov/intellij/plugin/inspection/SuperBuilderQuickFixTest.java @@ -0,0 +1,51 @@ +package de.plushnikov.intellij.plugin.inspection; + +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.ide.highlighter.JavaFileType; +import com.intellij.openapi.editor.Editor; +import com.intellij.psi.PsiFile; +import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl; +import com.intellij.util.containers.ContainerUtil; +import de.plushnikov.intellij.plugin.AbstractLombokLightCodeInsightTestCase; + +import java.util.List; + +public class SuperBuilderQuickFixTest extends AbstractLombokLightCodeInsightTestCase { + + public void testAddModifiersAbstractStaticOnInnerBuilderClass() { + myFixture.configureByText(JavaFileType.INSTANCE, """ + import lombok.experimental.SuperBuilder; + + @SuperBuilder + class DeltaComponentWithSalesAndTechComponentId { + } + + @SuperBuilder + public class DeltaOfferComponent extends DeltaComponentWithSalesAndTechComponentId { + + Integer max; + + public class DeltaOfferComponentBuilder { + public DeltaOfferComponentBuilder max(Integer max) { + this.max = max; + return this; + } + } + } + """); + + assertTrue(hasActionWithText("Make 'DeltaOfferComponentBuilder' abstract")); + assertTrue(hasActionWithText("Make 'DeltaOfferComponentBuilder' static")); + } + + private boolean hasActionWithText(String text) { + myFixture.enableInspections(LombokInspection.class); + + final Editor editor = getEditor(); + final PsiFile file = getFile(); + CodeInsightTestFixtureImpl.instantiateAndRun(file, editor, new int[0], false); + final List availableActions = CodeInsightTestFixtureImpl.getAvailableIntentions(editor, file); + + return ContainerUtil.exists(availableActions, action -> action.getText().contains(text)); + } +}