From 0b4694bb4f94d609d2fea5405f92c762b907e277 Mon Sep 17 00:00:00 2001 From: Michail Plushnikov Date: Sat, 2 Sep 2023 17:59:34 +0200 Subject: [PATCH] [lombok] IDEA-329808 Fix invalid error about missing final modifier for subclass of sealed class annotated with Lombok's @Value GitOrigin-RevId: 63fba57e020ae076219a100458b9d35e07fdabbb --- .../modifier/ValueModifierProcessor.java | 2 +- .../lomboktest/LombokHighlightingTest.java | 58 ++++++++++--------- .../plugin/AbstractLombokParsingTestCase.java | 19 +++--- .../intellij/plugin/LombokTestUtil.java | 1 + .../highlighting/ValueSealedInterface.java | 22 +++++++ 5 files changed, 65 insertions(+), 37 deletions(-) create mode 100644 plugins/lombok/testData/highlighting/ValueSealedInterface.java diff --git a/plugins/lombok/src/main/java/de/plushnikov/intellij/plugin/processor/modifier/ValueModifierProcessor.java b/plugins/lombok/src/main/java/de/plushnikov/intellij/plugin/processor/modifier/ValueModifierProcessor.java index 2777c63f1bf7..8030ead64ab7 100644 --- a/plugins/lombok/src/main/java/de/plushnikov/intellij/plugin/processor/modifier/ValueModifierProcessor.java +++ b/plugins/lombok/src/main/java/de/plushnikov/intellij/plugin/processor/modifier/ValueModifierProcessor.java @@ -30,7 +30,7 @@ public class ValueModifierProcessor implements ModifierProcessor { @Override public void transformModifiers(@NotNull PsiModifierList modifierList, @NotNull final Set modifiers) { - if (modifiers.contains(PsiModifier.STATIC)) { + if (modifiers.contains(PsiModifier.STATIC) && modifierList.getParent() instanceof PsiField) { return; // skip static fields } diff --git a/plugins/lombok/src/test/java/com/intellij/java/lomboktest/LombokHighlightingTest.java b/plugins/lombok/src/test/java/com/intellij/java/lomboktest/LombokHighlightingTest.java index 3745f0b82b25..6c20af6dc573 100644 --- a/plugins/lombok/src/test/java/com/intellij/java/lomboktest/LombokHighlightingTest.java +++ b/plugins/lombok/src/test/java/com/intellij/java/lomboktest/LombokHighlightingTest.java @@ -22,32 +22,6 @@ import org.jetbrains.annotations.NotNull; public class LombokHighlightingTest extends LightDaemonAnalyzerTestCase { - @Override - protected void setUp() throws Exception { - super.setUp(); - enableInspectionTool(new UnusedDeclarationInspection(true)); - setWarningLevel(new ObjectEqualityInspection()); - } - - private void setWarningLevel(LocalInspectionTool inspection) { - final HighlightDisplayKey displayKey = HighlightDisplayKey.find(inspection.getShortName()); - final InspectionProfileImpl currentProfile = ProjectInspectionProfileManager.getInstance(getProject()).getCurrentProfile(); - currentProfile.setErrorLevel(displayKey, HighlightDisplayLevel.WARNING, getProject()); - } - - @Override - protected LocalInspectionTool @NotNull [] configureLocalInspectionTools() { - return new LocalInspectionTool[]{ - new ObjectToStringInspection(), - new ObjectEqualityInspection(), - new DataFlowInspection(), - new DefUseInspection(), - new FieldMayBeFinalInspection(), - new FieldCanBeLocalInspection(), - new DefaultAnnotationParamInspection() - }; - } - public void testLombokBasics() { doTest(); } public void testLombokStaticVars() { @@ -74,10 +48,40 @@ public class LombokHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testValueSealedInterface() { + doTest(); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + enableInspectionTool(new UnusedDeclarationInspection(true)); + setWarningLevel(new ObjectEqualityInspection()); + } + + private void setWarningLevel(LocalInspectionTool inspection) { + final HighlightDisplayKey displayKey = HighlightDisplayKey.find(inspection.getShortName()); + final InspectionProfileImpl currentProfile = ProjectInspectionProfileManager.getInstance(getProject()).getCurrentProfile(); + currentProfile.setErrorLevel(displayKey, HighlightDisplayLevel.WARNING, getProject()); + } + + @Override + protected LocalInspectionTool @NotNull [] configureLocalInspectionTools() { + return new LocalInspectionTool[]{ + new ObjectToStringInspection(), + new ObjectEqualityInspection(), + new DataFlowInspection(), + new DefUseInspection(), + new FieldMayBeFinalInspection(), + new FieldCanBeLocalInspection(), + new DefaultAnnotationParamInspection() + }; + } + @NotNull @Override protected LightProjectDescriptor getProjectDescriptor() { - return LombokTestUtil.LOMBOK_DESCRIPTOR; + return LombokTestUtil.LOMBOK_NEW_DESCRIPTOR; } private void doTest() { diff --git a/plugins/lombok/src/test/java/de/plushnikov/intellij/plugin/AbstractLombokParsingTestCase.java b/plugins/lombok/src/test/java/de/plushnikov/intellij/plugin/AbstractLombokParsingTestCase.java index 42a89fa35ad4..cb804b0492e5 100644 --- a/plugins/lombok/src/test/java/de/plushnikov/intellij/plugin/AbstractLombokParsingTestCase.java +++ b/plugins/lombok/src/test/java/de/plushnikov/intellij/plugin/AbstractLombokParsingTestCase.java @@ -32,7 +32,7 @@ public abstract class AbstractLombokParsingTestCase extends AbstractLombokLightC } protected Collection annotationsToIgnoreList() { - return Set.of("java.lang.SuppressWarnings", "java.lang.Override","com.fasterxml.jackson.databind.annotation.JsonDeserialize"); + return Set.of("java.lang.SuppressWarnings", "java.lang.Override", "com.fasterxml.jackson.databind.annotation.JsonDeserialize"); } protected boolean shouldCompareCodeBlocks() { @@ -101,7 +101,9 @@ public abstract class AbstractLombokParsingTestCase extends AbstractLombokLightC PsiModifierList afterFieldModifierList = afterClass.getModifierList(); compareContainingClasses(beforeClass, afterClass); - compareModifiers(beforeFieldModifierList, afterFieldModifierList); + if (beforeFieldModifierList != null && afterFieldModifierList != null) { + compareModifiers(beforeFieldModifierList, afterFieldModifierList); + } compareFields(beforeClass, afterClass); compareMethods(beforeClass, afterClass); compareConstructors(beforeClass, afterClass); @@ -127,7 +129,9 @@ public abstract class AbstractLombokParsingTestCase extends AbstractLombokLightC if (Objects.equal(afterField.getName(), beforeField.getName())) { final PsiModifierList beforeFieldModifierList = beforeField.getModifierList(); - compareModifiers(beforeFieldModifierList, afterFieldModifierList); + if (beforeFieldModifierList != null && afterFieldModifierList != null) { + compareModifiers(beforeFieldModifierList, afterFieldModifierList); + } compareType(beforeField.getType(), afterField.getType(), afterField); compareInitializers(beforeField.getInitializer(), afterField.getInitializer()); compared = true; @@ -155,10 +159,7 @@ public abstract class AbstractLombokParsingTestCase extends AbstractLombokLightC return StringUtil.trimStart(canonicalText, "java.lang."); } - private void compareModifiers(PsiModifierList beforeModifierList, PsiModifierList afterModifierList) { - assertNotNull(beforeModifierList); - assertNotNull(afterModifierList); - + private void compareModifiers(@NotNull PsiModifierList beforeModifierList, @NotNull PsiModifierList afterModifierList) { for (String modifier : PsiModifier.MODIFIERS) { boolean haveSameModifiers = afterModifierList.hasModifierProperty(modifier) == beforeModifierList.hasModifierProperty(modifier); if (!haveSameModifiers) { @@ -207,9 +208,9 @@ public abstract class AbstractLombokParsingTestCase extends AbstractLombokLightC PsiAnnotation afterAnnotation = afterModifierList.findAnnotation(qualifiedName); if (null != afterAnnotation) { Map beforeParameter = Stream.of(beforeAnnotation.getParameterList().getAttributes()) - .collect(Collectors.toMap(PsiNameValuePair::getAttributeName, p->p.getValue().getText())); + .collect(Collectors.toMap(PsiNameValuePair::getAttributeName, p -> p.getValue().getText())); Map afterParameter = Stream.of(afterAnnotation.getParameterList().getAttributes()) - .collect(Collectors.toMap(PsiNameValuePair::getAttributeName, p->p.getValue().getText())); + .collect(Collectors.toMap(PsiNameValuePair::getAttributeName, p -> p.getValue().getText())); assertEquals("Annotation parameter are not same for " + qualifiedName, afterParameter, beforeParameter); } } diff --git a/plugins/lombok/src/test/java/de/plushnikov/intellij/plugin/LombokTestUtil.java b/plugins/lombok/src/test/java/de/plushnikov/intellij/plugin/LombokTestUtil.java index 2a19d1bb91d4..663f8d03afda 100644 --- a/plugins/lombok/src/test/java/de/plushnikov/intellij/plugin/LombokTestUtil.java +++ b/plugins/lombok/src/test/java/de/plushnikov/intellij/plugin/LombokTestUtil.java @@ -37,6 +37,7 @@ public final class LombokTestUtil { public void configureModule(@NotNull Module module, @NotNull ModifiableRootModel model, @NotNull ContentEntry contentEntry) { MavenDependencyUtil.addFromMaven(model, LOMBOK_MAVEN_COORDINATES); MavenDependencyUtil.addFromMaven(model, JACKSON_MAVEN_COORDINATES); + MavenDependencyUtil.addFromMaven(model, "org.slf4j:slf4j-api:1.7.30"); model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.HIGHEST); } }; diff --git a/plugins/lombok/testData/highlighting/ValueSealedInterface.java b/plugins/lombok/testData/highlighting/ValueSealedInterface.java new file mode 100644 index 000000000000..9fa78d584ee4 --- /dev/null +++ b/plugins/lombok/testData/highlighting/ValueSealedInterface.java @@ -0,0 +1,22 @@ +import lombok.Value; + +sealed interface Sealed permits ValueSealedInterface, ValueSealedInterface.A, ValueSealedInterface.B, ValueSealedInterface.C { +} + +@Value +public class ValueSealedInterface implements Sealed { + + static final class A implements Sealed { + + } + + @Value + static class B implements Sealed { + // should not report: "sealed, non-sealed or final modifiers expected" even though class is final + } + + @Value + static final class C implements Sealed { + + } +} \ No newline at end of file