mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[lombok] IDEA-375529 False positive warning by "Lombok annotations" inspection regarding @Data
GitOrigin-RevId: 68e68e3ac175b44d8b5b066c138e97c721936b71
This commit is contained in:
committed by
intellij-monorepo-bot
parent
83d4ecc4a6
commit
012fe6bfde
+2
-2
@@ -60,8 +60,8 @@ public abstract class AbstractProcessor implements Processor {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected @Unmodifiable @NotNull <T extends PsiModifierListOwner> Collection<T> filterToleratedElements(@NotNull @Unmodifiable Collection<? extends T> definedMethods) {
|
||||
return ContainerUtil.filter(definedMethods, definedMethod -> !PsiAnnotationSearchUtil.isAnnotatedWith(definedMethod, LombokClassNames.TOLERATE));
|
||||
protected static @Unmodifiable @NotNull <T extends PsiModifierListOwner> Collection<T> filterToleratedElements(@NotNull @Unmodifiable Collection<? extends T> definedMethods) {
|
||||
return ContainerUtil.filter(definedMethods, definedMethod -> PsiAnnotationSearchUtil.isNotAnnotatedWith(definedMethod, LombokClassNames.TOLERATE));
|
||||
}
|
||||
|
||||
protected boolean readAnnotationOrConfigProperty(@NotNull PsiAnnotation psiAnnotation, @NotNull PsiClass psiClass,
|
||||
|
||||
+19
@@ -199,4 +199,23 @@ public abstract class AbstractClassProcessor extends AbstractProcessor implement
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected static boolean isAnyConstructorDefined(@NotNull PsiClass psiClass) {
|
||||
return !filterToleratedElements(PsiClassUtil.collectClassConstructorIntern(psiClass)).isEmpty();
|
||||
}
|
||||
|
||||
protected static boolean shouldGenerateConstructor(@NotNull PsiClass psiClass) {
|
||||
// create the required constructor only if there are no other constructor annotations
|
||||
if (!hasLombokConstructorAnnotations(psiClass)) {
|
||||
return !isAnyConstructorDefined(psiClass);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static boolean hasLombokConstructorAnnotations(@NotNull PsiClass psiClass) {
|
||||
return PsiAnnotationSearchUtil.isAnnotatedWith(psiClass, LombokClassNames.NO_ARGS_CONSTRUCTOR,
|
||||
LombokClassNames.REQUIRED_ARGS_CONSTRUCTOR,
|
||||
LombokClassNames.ALL_ARGS_CONSTRUCTOR,
|
||||
LombokClassNames.BUILDER);
|
||||
}
|
||||
}
|
||||
|
||||
+8
-31
@@ -3,7 +3,6 @@ package de.plushnikov.intellij.plugin.processor.clazz;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import de.plushnikov.intellij.plugin.LombokClassNames;
|
||||
import de.plushnikov.intellij.plugin.problem.ProblemProcessingSink;
|
||||
import de.plushnikov.intellij.plugin.problem.ProblemSink;
|
||||
import de.plushnikov.intellij.plugin.processor.LombokProcessorManager;
|
||||
import de.plushnikov.intellij.plugin.processor.LombokPsiElementUsage;
|
||||
@@ -19,7 +18,6 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static de.plushnikov.intellij.plugin.LombokClassNames.DATA;
|
||||
|
||||
/**
|
||||
* @author Plushnikov Michail
|
||||
@@ -98,8 +96,7 @@ public final class DataProcessor extends AbstractClassProcessor {
|
||||
getEqualsAndHashCodeProcessor().validateCallSuperParamExtern(psiAnnotation, psiClass, builder);
|
||||
}
|
||||
|
||||
final String staticName = getStaticConstructorNameValue(psiAnnotation);
|
||||
if (shouldGenerateRequiredArgsConstructor(psiClass, staticName)) {
|
||||
if (shouldGenerateConstructor(psiClass)) {
|
||||
getRequiredArgsConstructorProcessor().validateBaseClassConstructor(psiClass, builder);
|
||||
}
|
||||
}
|
||||
@@ -109,7 +106,7 @@ public final class DataProcessor extends AbstractClassProcessor {
|
||||
private static void validateAnnotationOnRightType(@NotNull PsiClass psiClass, @NotNull ProblemSink builder) {
|
||||
if (psiClass.isAnnotationType() || psiClass.isInterface() || psiClass.isEnum() || psiClass.isRecord()) {
|
||||
builder.addErrorMessage("inspection.message.data.only.supported.on.class.type")
|
||||
.withLocalQuickFixes(() -> PsiQuickFixFactory.createDeleteAnnotationFix(psiClass, DATA));
|
||||
.withLocalQuickFixes(() -> PsiQuickFixFactory.createDeleteAnnotationFix(psiClass, LombokClassNames.DATA));
|
||||
builder.markFailed();
|
||||
}
|
||||
}
|
||||
@@ -117,7 +114,8 @@ public final class DataProcessor extends AbstractClassProcessor {
|
||||
@Override
|
||||
protected void generatePsiElements(@NotNull PsiClass psiClass,
|
||||
@NotNull PsiAnnotation psiAnnotation,
|
||||
@NotNull List<? super PsiElement> target, @Nullable String nameHint) {
|
||||
@NotNull List<? super PsiElement> target,
|
||||
@Nullable String nameHint) {
|
||||
if (PsiAnnotationSearchUtil.isNotAnnotatedWith(psiClass, LombokClassNames.GETTER)) {
|
||||
target.addAll(getGetterProcessor().createFieldGetters(psiClass, PsiModifier.PUBLIC, nameHint));
|
||||
}
|
||||
@@ -133,43 +131,22 @@ public final class DataProcessor extends AbstractClassProcessor {
|
||||
target.addAll(getToStringProcessor().createToStringMethod(psiClass, psiAnnotation));
|
||||
}
|
||||
|
||||
final boolean hasConstructorWithoutParameters;
|
||||
boolean hasConstructorWithoutParameters = false;
|
||||
final String staticName = getStaticConstructorNameValue(psiAnnotation);
|
||||
if (nameHint != null && !nameHint.equals(staticName) && !nameHint.equals(psiClass.getName())) return;
|
||||
if (shouldGenerateRequiredArgsConstructor(psiClass, staticName)) {
|
||||
|
||||
if (!hasLombokConstructorAnnotations(psiClass) && PsiAnnotationSearchUtil.isNotAnnotatedWith(psiClass, LombokClassNames.SUPER_BUILDER)) {
|
||||
target.addAll(
|
||||
getRequiredArgsConstructorProcessor().createRequiredArgsConstructor(psiClass, PsiModifier.PUBLIC, psiAnnotation, staticName, true));
|
||||
// if there are no required field, it will already have a default constructor without parameters
|
||||
// if there are no required fields, it will already have a default constructor without parameters
|
||||
hasConstructorWithoutParameters = getRequiredArgsConstructorProcessor().getRequiredFields(psiClass).isEmpty();
|
||||
}
|
||||
else {
|
||||
hasConstructorWithoutParameters = false;
|
||||
}
|
||||
|
||||
if (!hasConstructorWithoutParameters && shouldGenerateExtraNoArgsConstructor(psiClass)) {
|
||||
target.addAll(getNoArgsConstructorProcessor().createNoArgsConstructor(psiClass, PsiModifier.PRIVATE, psiAnnotation, true));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shouldGenerateRequiredArgsConstructor(@NotNull PsiClass psiClass, @Nullable String staticName) {
|
||||
boolean result = false;
|
||||
// create required constructor only if there are no other constructor annotations
|
||||
final boolean notAnnotatedWith = PsiAnnotationSearchUtil.isNotAnnotatedWith(psiClass,
|
||||
LombokClassNames.NO_ARGS_CONSTRUCTOR,
|
||||
LombokClassNames.REQUIRED_ARGS_CONSTRUCTOR,
|
||||
LombokClassNames.ALL_ARGS_CONSTRUCTOR,
|
||||
LombokClassNames.BUILDER,
|
||||
LombokClassNames.SUPER_BUILDER);
|
||||
if (notAnnotatedWith) {
|
||||
final RequiredArgsConstructorProcessor requiredArgsConstructorProcessor = getRequiredArgsConstructorProcessor();
|
||||
final Collection<PsiField> requiredFields = requiredArgsConstructorProcessor.getRequiredFields(psiClass);
|
||||
|
||||
result = requiredArgsConstructorProcessor.validateIsConstructorNotDefined(
|
||||
psiClass, staticName, requiredFields, new ProblemProcessingSink());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LombokPsiElementUsage checkFieldUsage(@NotNull PsiField psiField, @NotNull PsiAnnotation psiAnnotation) {
|
||||
return LombokPsiElementUsage.READ_WRITE;
|
||||
|
||||
+16
-20
@@ -3,7 +3,6 @@ package de.plushnikov.intellij.plugin.processor.clazz;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import de.plushnikov.intellij.plugin.LombokClassNames;
|
||||
import de.plushnikov.intellij.plugin.problem.ProblemProcessingSink;
|
||||
import de.plushnikov.intellij.plugin.problem.ProblemSink;
|
||||
import de.plushnikov.intellij.plugin.processor.LombokProcessorManager;
|
||||
import de.plushnikov.intellij.plugin.processor.LombokPsiElementUsage;
|
||||
@@ -13,7 +12,6 @@ import de.plushnikov.intellij.plugin.processor.clazz.constructor.NoArgsConstruct
|
||||
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;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -21,8 +19,6 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static de.plushnikov.intellij.plugin.LombokClassNames.VALUE;
|
||||
|
||||
/**
|
||||
* @author twillouer
|
||||
*/
|
||||
@@ -91,6 +87,10 @@ public final class ValueProcessor extends AbstractClassProcessor {
|
||||
if (PsiAnnotationSearchUtil.isNotAnnotatedWith(psiClass, LombokClassNames.EQUALS_AND_HASHCODE)) {
|
||||
getEqualsAndHashCodeProcessor().validateCallSuperParamExtern(psiAnnotation, psiClass, builder);
|
||||
}
|
||||
|
||||
if (shouldGenerateConstructor(psiClass)) {
|
||||
getAllArgsConstructorProcessor().validateBaseClassConstructor(psiClass, builder);
|
||||
}
|
||||
}
|
||||
return builder.success();
|
||||
}
|
||||
@@ -98,7 +98,7 @@ public final class ValueProcessor extends AbstractClassProcessor {
|
||||
private static void validateAnnotationOnRightType(@NotNull PsiClass psiClass, @NotNull ProblemSink builder) {
|
||||
if (psiClass.isAnnotationType() || psiClass.isInterface() || psiClass.isEnum() || psiClass.isRecord()) {
|
||||
builder.addErrorMessage("inspection.message.value.only.supported.on.class.type")
|
||||
.withLocalQuickFixes(() -> PsiQuickFixFactory.createDeleteAnnotationFix(psiClass, VALUE));
|
||||
.withLocalQuickFixes(() -> PsiQuickFixFactory.createDeleteAnnotationFix(psiClass, LombokClassNames.VALUE));
|
||||
builder.markFailed();
|
||||
}
|
||||
}
|
||||
@@ -111,27 +111,23 @@ public final class ValueProcessor extends AbstractClassProcessor {
|
||||
if (PsiAnnotationSearchUtil.isNotAnnotatedWith(psiClass, LombokClassNames.GETTER)) {
|
||||
target.addAll(getGetterProcessor().createFieldGetters(psiClass, PsiModifier.PUBLIC, nameHint));
|
||||
}
|
||||
if (PsiAnnotationSearchUtil.isNotAnnotatedWith(psiClass, LombokClassNames.EQUALS_AND_HASHCODE)) {
|
||||
if (PsiAnnotationSearchUtil.isNotAnnotatedWith(psiClass, LombokClassNames.EQUALS_AND_HASHCODE) &&
|
||||
getEqualsAndHashCodeProcessor().noHintOrPossibleToGenerateElementNamed(nameHint, psiClass, psiAnnotation)) {
|
||||
target.addAll(getEqualsAndHashCodeProcessor().createEqualAndHashCode(psiClass, psiAnnotation));
|
||||
}
|
||||
if (PsiAnnotationSearchUtil.isNotAnnotatedWith(psiClass, LombokClassNames.TO_STRING)) {
|
||||
if (PsiAnnotationSearchUtil.isNotAnnotatedWith(psiClass, LombokClassNames.TO_STRING) &&
|
||||
getToStringProcessor().noHintOrPossibleToGenerateElementNamed(nameHint, psiClass, psiAnnotation)) {
|
||||
target.addAll(getToStringProcessor().createToStringMethod(psiClass, psiAnnotation));
|
||||
}
|
||||
// create required constructor only if there are no other constructor annotations
|
||||
if (PsiAnnotationSearchUtil.isNotAnnotatedWith(psiClass, LombokClassNames.NO_ARGS_CONSTRUCTOR,
|
||||
LombokClassNames.REQUIRED_ARGS_CONSTRUCTOR, LombokClassNames.ALL_ARGS_CONSTRUCTOR,
|
||||
LombokClassNames.BUILDER)) {
|
||||
PsiClassUtil.collectClassConstructorIntern(psiClass);
|
||||
|
||||
final String staticName = getStaticConstructorNameValue(psiAnnotation);
|
||||
final String staticName = getStaticConstructorNameValue(psiAnnotation);
|
||||
if (nameHint != null && !nameHint.equals(staticName) && !nameHint.equals(psiClass.getName())) return;
|
||||
|
||||
if (!hasLombokConstructorAnnotations(psiClass)) {
|
||||
final Collection<PsiField> requiredFields = AbstractConstructorClassProcessor.getAllFields(psiClass);
|
||||
|
||||
if (getAllArgsConstructorProcessor().validateIsConstructorNotDefined(psiClass, staticName, requiredFields,
|
||||
new ProblemProcessingSink())) {
|
||||
target.addAll(
|
||||
getAllArgsConstructorProcessor().createAllArgsConstructor(psiClass, PsiModifier.PUBLIC, psiAnnotation, staticName, requiredFields,
|
||||
true));
|
||||
}
|
||||
target.addAll(
|
||||
getAllArgsConstructorProcessor().createAllArgsConstructor(psiClass, PsiModifier.PUBLIC, psiAnnotation, staticName, requiredFields,
|
||||
true));
|
||||
}
|
||||
|
||||
if (shouldGenerateExtraNoArgsConstructor(psiClass)) {
|
||||
|
||||
+1
-7
@@ -300,7 +300,7 @@ public abstract class AbstractConstructorClassProcessor extends AbstractClassPro
|
||||
|
||||
final String constructorVisibility = staticConstructorRequired || psiClass.isEnum() ? PsiModifier.PRIVATE : methodModifier;
|
||||
|
||||
// check, if we should skip verification for presence of any (not Tolerated) constructors
|
||||
// check if we should skip verification for presence of any (not Tolerated) constructors
|
||||
if (!skipConstructorIfAnyConstructorExists || !isAnyConstructorDefined(psiClass)) {
|
||||
boolean hasConstructor = !validateIsConstructorNotDefined(psiClass,
|
||||
useJavaDefaults ? Collections.emptyList() : params,
|
||||
@@ -319,12 +319,6 @@ public abstract class AbstractConstructorClassProcessor extends AbstractClassPro
|
||||
return methods;
|
||||
}
|
||||
|
||||
private static boolean isAnyConstructorDefined(@NotNull PsiClass psiClass) {
|
||||
Collection<PsiMethod> constructors = PsiClassUtil.collectClassConstructorIntern(psiClass);
|
||||
return ContainerUtil.exists(constructors,
|
||||
psiMethod -> PsiAnnotationSearchUtil.isNotAnnotatedWith(psiMethod, LombokClassNames.TOLERATE));
|
||||
}
|
||||
|
||||
private PsiMethod createConstructor(@NotNull PsiClass psiClass, @PsiModifier.ModifierConstant @NotNull String modifier,
|
||||
boolean useJavaDefaults, @NotNull Collection<PsiField> params, @NotNull PsiAnnotation psiAnnotation) {
|
||||
LombokLightMethodBuilder constructorBuilder = new LombokLightMethodBuilder(psiClass.getManager(), getConstructorName(psiClass))
|
||||
|
||||
+2
-9
@@ -1,10 +1,10 @@
|
||||
package de.plushnikov.intellij.plugin.highlights;
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.siyeh.ig.LightJavaInspectionTestCase;
|
||||
import de.plushnikov.intellij.plugin.LombokTestUtil;
|
||||
import de.plushnikov.intellij.plugin.inspection.LombokInspection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
@@ -13,13 +13,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public abstract class AbstractLombokHighlightsTest extends LightJavaInspectionTestCase {
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
Registry.get("platform.random.idempotence.check.rate").setValue(1, getTestRootDisposable());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
@@ -33,7 +26,7 @@ public abstract class AbstractLombokHighlightsTest extends LightJavaInspectionTe
|
||||
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
return null;
|
||||
return new LombokInspection();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package de.plushnikov.intellij.plugin.highlights;
|
||||
|
||||
/**
|
||||
* Test for highlighting issues with @Data and @Value annotations in inheritance scenarios
|
||||
*/
|
||||
public class DataValueInheritanceHighlightTest extends AbstractLombokHighlightsTest {
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return super.getBasePath() + "/dataValueInheritance";
|
||||
}
|
||||
|
||||
public void testDataInheritanceHighlighting() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testValueInheritanceHighlighting() {
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
-8
@@ -1,8 +1,5 @@
|
||||
package de.plushnikov.intellij.plugin.highlights;
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import de.plushnikov.intellij.plugin.inspection.LombokInspection;
|
||||
|
||||
public class LombokInspectionHighlightTest extends AbstractLombokHighlightsTest {
|
||||
|
||||
@Override
|
||||
@@ -10,11 +7,6 @@ public class LombokInspectionHighlightTest extends AbstractLombokHighlightsTest
|
||||
return super.getBasePath() + "/builderDefault";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
return new LombokInspection();
|
||||
}
|
||||
|
||||
public void testBuilderDefaultWithoutBuilderAnnotation() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
-8
@@ -1,8 +1,5 @@
|
||||
package de.plushnikov.intellij.plugin.highlights;
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import de.plushnikov.intellij.plugin.inspection.LombokInspection;
|
||||
|
||||
public class RecordsHighlightTest extends AbstractLombokHighlightsTest {
|
||||
|
||||
@Override
|
||||
@@ -10,11 +7,6 @@ public class RecordsHighlightTest extends AbstractLombokHighlightsTest {
|
||||
return super.getBasePath() + "/onRecord";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
return new LombokInspection();
|
||||
}
|
||||
|
||||
public void testInvalidLombokAnnotationsOnRecord() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
-8
@@ -1,8 +1,5 @@
|
||||
package de.plushnikov.intellij.plugin.highlights;
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import de.plushnikov.intellij.plugin.inspection.LombokInspection;
|
||||
|
||||
public class SneakyThrowsHighlightTest extends AbstractLombokHighlightsTest {
|
||||
|
||||
@Override
|
||||
@@ -10,11 +7,6 @@ public class SneakyThrowsHighlightTest extends AbstractLombokHighlightsTest {
|
||||
return super.getBasePath() + "/sneakyThrows";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
return new LombokInspection();
|
||||
}
|
||||
|
||||
public void testSneakThrowsDoesntCatchCaughtException() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
-8
@@ -1,8 +1,5 @@
|
||||
package de.plushnikov.intellij.plugin.highlights;
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import de.plushnikov.intellij.plugin.inspection.LombokInspection;
|
||||
|
||||
public class SuperBuilderHighlightTest extends AbstractLombokHighlightsTest {
|
||||
|
||||
@Override
|
||||
@@ -10,11 +7,6 @@ public class SuperBuilderHighlightTest extends AbstractLombokHighlightsTest {
|
||||
return super.getBasePath() + "/superBuilder";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
return new LombokInspection();
|
||||
}
|
||||
|
||||
public void testSuperBuilderOnInnerClass() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
public class DataInheritanceHighlighting {
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
static class WithConstructor extends ParentWithNonDefaultConstructor {
|
||||
private String field;
|
||||
|
||||
// Explicitly define constructor to call parent constructor
|
||||
WithConstructor() {
|
||||
super("defaultValue");
|
||||
}
|
||||
}
|
||||
|
||||
<error descr="Lombok needs a default constructor in the base class">@Data</error>
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
static class WithoutConstructor extends ParentWithNonDefaultConstructor {
|
||||
private String field;
|
||||
// No constructor defined - should show error
|
||||
}
|
||||
|
||||
static class ParentWithNonDefaultConstructor {
|
||||
private final String requiredField;
|
||||
|
||||
ParentWithNonDefaultConstructor(String requiredField) {
|
||||
this.requiredField = requiredField;
|
||||
}
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
import lombok.Value;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
public class ValueInheritanceHighlighting {
|
||||
|
||||
@Value
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
static class WithConstructor extends ParentWithNonDefaultConstructor {
|
||||
String field;
|
||||
|
||||
// Explicitly define constructor to call parent constructor
|
||||
WithConstructor(String field) {
|
||||
super("defaultValue");
|
||||
this.field = field;
|
||||
}
|
||||
}
|
||||
|
||||
<error descr="Lombok needs a default constructor in the base class">@Value</error>
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
static class WithoutConstructor extends ParentWithNonDefaultConstructor {
|
||||
String field;
|
||||
// No constructor defined - should show error
|
||||
}
|
||||
|
||||
static class ParentWithNonDefaultConstructor {
|
||||
private final String requiredField;
|
||||
|
||||
ParentWithNonDefaultConstructor(String requiredField) {
|
||||
this.requiredField = requiredField;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user