mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-04 23:39:07 +07:00
[lombok] IDEA-366441 Fix Intellij warnings for Lombok @With annotation functionality on class
GitOrigin-RevId: 3eeeeeeff7b4c510bcfd835a1b6eec7037a6fcc5
This commit is contained in:
committed by
intellij-monorepo-bot
parent
4a760237af
commit
5640847303
@@ -11,6 +11,7 @@ import de.plushnikov.intellij.plugin.thirdparty.LombokUtils;
|
||||
import de.plushnikov.intellij.plugin.util.LombokProcessorUtil;
|
||||
import de.plushnikov.intellij.plugin.util.PsiAnnotationSearchUtil;
|
||||
import de.plushnikov.intellij.plugin.util.PsiClassUtil;
|
||||
import de.plushnikov.intellij.plugin.util.PsiMethodUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -101,9 +102,9 @@ public final class WitherProcessor extends AbstractClassProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
private static @NotNull Collection<PsiMethod> createFieldWithers(@NotNull PsiClass psiClass,
|
||||
@NotNull String methodModifier,
|
||||
@NotNull AccessorsInfo accessors) {
|
||||
private @NotNull Collection<PsiMethod> createFieldWithers(@NotNull PsiClass psiClass,
|
||||
@NotNull String methodModifier,
|
||||
@NotNull AccessorsInfo accessors) {
|
||||
Collection<PsiMethod> result = new ArrayList<>();
|
||||
|
||||
final Collection<PsiField> witherFields = getWitherFields(psiClass);
|
||||
@@ -118,18 +119,21 @@ public final class WitherProcessor extends AbstractClassProcessor {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static @NotNull Collection<PsiField> getWitherFields(@NotNull PsiClass psiClass) {
|
||||
private @NotNull Collection<PsiField> getWitherFields(@NotNull PsiClass psiClass) {
|
||||
Collection<PsiField> witherFields = new ArrayList<>();
|
||||
|
||||
final AccessorsInfo.AccessorsValues classAccessorsValues = AccessorsInfo.getAccessorsValues(psiClass);
|
||||
final Collection<PsiMethod> existingMethods = filterToleratedElements(PsiClassUtil.collectClassMethodsIntern(psiClass));
|
||||
for (PsiField psiField : psiClass.getFields()) {
|
||||
if (shouldGenerateWither(psiField)) {
|
||||
if (shouldGenerateWither(psiField, classAccessorsValues, existingMethods)) {
|
||||
witherFields.add(psiField);
|
||||
}
|
||||
}
|
||||
return witherFields;
|
||||
}
|
||||
|
||||
private static boolean shouldGenerateWither(@NotNull PsiField psiField) {
|
||||
private static boolean shouldGenerateWither(@NotNull PsiField psiField, @NotNull AccessorsInfo.AccessorsValues classAccessorsValues,
|
||||
@NotNull Collection<PsiMethod> existingMethods) {
|
||||
boolean createWither = true;
|
||||
PsiModifierList modifierList = psiField.getModifierList();
|
||||
if (null != modifierList) {
|
||||
@@ -142,16 +146,39 @@ public final class WitherProcessor extends AbstractClassProcessor {
|
||||
createWither &= !psiField.getName().startsWith(LombokUtils.LOMBOK_INTERN_FIELD_MARKER);
|
||||
// Skip fields having Wither annotation already
|
||||
createWither &= !PsiAnnotationSearchUtil.isAnnotatedWith(psiField, LombokClassNames.WITHER, LombokClassNames.WITH);
|
||||
final AccessorsInfo accessorsInfo = AccessorsInfo.buildFor(psiField).withFluent(false);
|
||||
|
||||
final AccessorsInfo accessorsInfo = AccessorsInfo.buildFor(psiField, classAccessorsValues).withFluent(false);
|
||||
createWither &= accessorsInfo.acceptsFieldName(psiField.getName());
|
||||
|
||||
if (createWither) {
|
||||
createWither = isWitherMethodUnique(psiField, accessorsInfo, existingMethods);
|
||||
}
|
||||
}
|
||||
return createWither;
|
||||
}
|
||||
|
||||
private static boolean isWitherMethodUnique(@NotNull PsiField psiField, @NotNull AccessorsInfo accessorsInfo,
|
||||
@NotNull Collection<PsiMethod> existingMethods) {
|
||||
final Collection<String> possibleWitherNames =
|
||||
LombokUtils.toAllWitherNames(accessorsInfo, psiField.getName(), PsiTypes.booleanType().equals(psiField.getType()));
|
||||
for (String witherName : possibleWitherNames) {
|
||||
if (PsiMethodUtil.hasSimilarMethod(existingMethods, witherName, 1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LombokPsiElementUsage checkFieldUsage(@NotNull PsiField psiField, @NotNull PsiAnnotation psiAnnotation) {
|
||||
if (shouldGenerateWither(psiField)) {
|
||||
return LombokPsiElementUsage.READ_WRITE;
|
||||
final PsiClass containingClass = psiField.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
final AccessorsInfo.AccessorsValues classAccessorsValues = AccessorsInfo.getAccessorsValues(containingClass);
|
||||
final Collection<PsiMethod> existingMethods = filterToleratedElements(PsiClassUtil.collectClassMethodsIntern(containingClass));
|
||||
|
||||
if (shouldGenerateWither(psiField, classAccessorsValues, existingMethods)) {
|
||||
return LombokPsiElementUsage.READ_WRITE;
|
||||
}
|
||||
}
|
||||
return LombokPsiElementUsage.NONE;
|
||||
}
|
||||
|
||||
@@ -47,15 +47,20 @@ public final class WitherFieldProcessor extends AbstractFieldProcessor {
|
||||
protected boolean validate(@NotNull PsiAnnotation psiAnnotation, @NotNull PsiField psiField, @NotNull ProblemSink builder) {
|
||||
validateOnXAnnotations(psiAnnotation, psiField, builder, "onParam");
|
||||
|
||||
boolean valid = validateVisibility(psiAnnotation);
|
||||
final PsiClass containingClass = psiField.getContainingClass();
|
||||
|
||||
boolean valid = null != containingClass;
|
||||
valid &= validateVisibility(psiAnnotation);
|
||||
valid &= validName(psiField, builder);
|
||||
valid &= validNonStatic(psiField, builder);
|
||||
valid &= validNonFinalInitialized(psiField, builder);
|
||||
valid &= validIsWitherUnique(psiField, builder);
|
||||
|
||||
final PsiClass containingClass = psiField.getContainingClass();
|
||||
valid &=
|
||||
null != containingClass && (containingClass.hasModifierProperty(PsiModifier.ABSTRACT) || validConstructor(containingClass, builder));
|
||||
if (valid) {
|
||||
valid = validIsWitherUnique(psiField, builder,
|
||||
filterToleratedElements(PsiClassUtil.collectClassMethodsIntern(containingClass)));
|
||||
|
||||
valid &= containingClass.hasModifierProperty(PsiModifier.ABSTRACT) || validConstructor(containingClass, builder);
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
@@ -90,7 +95,7 @@ public final class WitherFieldProcessor extends AbstractFieldProcessor {
|
||||
private static boolean validNonStatic(@NotNull PsiField psiField, final @NotNull ProblemSink builder) {
|
||||
if (psiField.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
builder.addWarningMessage("inspection.message.not.generating.wither")
|
||||
.withLocalQuickFixes(()->PsiQuickFixFactory.createModifierListFix(psiField, PsiModifier.STATIC, false, false));
|
||||
.withLocalQuickFixes(() -> PsiQuickFixFactory.createModifierListFix(psiField, PsiModifier.STATIC, false, false));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -102,26 +107,21 @@ public final class WitherFieldProcessor extends AbstractFieldProcessor {
|
||||
psiField.hasModifierProperty(PsiModifier.FINAL) && !PsiAnnotationSearchUtil.isAnnotatedWith(psiClass, LombokClassNames.VALUE) &&
|
||||
psiField.hasInitializer() && !PsiAnnotationSearchUtil.isAnnotatedWith(psiField, LombokClassNames.BUILDER_DEFAULT)) {
|
||||
builder.addWarningMessage("inspection.message.not.generating.wither.for.this.field.withers.cannot.be.generated")
|
||||
.withLocalQuickFixes(()->PsiQuickFixFactory.createModifierListFix(psiField, PsiModifier.FINAL, false, false));
|
||||
.withLocalQuickFixes(() -> PsiQuickFixFactory.createModifierListFix(psiField, PsiModifier.FINAL, false, false));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean validIsWitherUnique(@NotNull PsiField psiField, final @NotNull ProblemSink builder) {
|
||||
final PsiClass fieldContainingClass = psiField.getContainingClass();
|
||||
if (fieldContainingClass != null) {
|
||||
final Collection<PsiMethod> classMethods = filterToleratedElements(PsiClassUtil.collectClassMethodsIntern(fieldContainingClass));
|
||||
|
||||
final AccessorsInfo accessorsInfo = buildAccessorsInfo(psiField);
|
||||
final String psiFieldName = psiField.getName();
|
||||
final Collection<String> possibleWitherNames =
|
||||
LombokUtils.toAllWitherNames(accessorsInfo, psiFieldName, PsiTypes.booleanType().equals(psiField.getType()));
|
||||
for (String witherName : possibleWitherNames) {
|
||||
if (PsiMethodUtil.hasSimilarMethod(classMethods, witherName, 1)) {
|
||||
builder.addWarningMessage("inspection.message.not.generating.s.method.with.that.name.already.exists", witherName);
|
||||
return false;
|
||||
}
|
||||
private static boolean validIsWitherUnique(@NotNull PsiField psiField, @NotNull ProblemSink builder,
|
||||
@NotNull Collection<PsiMethod> existingMethods) {
|
||||
final AccessorsInfo accessorsInfo = buildAccessorsInfo(psiField);
|
||||
final Collection<String> possibleWitherNames =
|
||||
LombokUtils.toAllWitherNames(accessorsInfo, psiField.getName(), PsiTypes.booleanType().equals(psiField.getType()));
|
||||
for (String witherName : possibleWitherNames) {
|
||||
if (PsiMethodUtil.hasSimilarMethod(existingMethods, witherName, 1)) {
|
||||
builder.addWarningMessage("inspection.message.not.generating.s.method.with.that.name.already.exists", witherName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -182,7 +182,9 @@ public final class WitherFieldProcessor extends AbstractFieldProcessor {
|
||||
return result;
|
||||
}
|
||||
|
||||
public @Nullable PsiMethod createWitherMethod(@NotNull PsiField psiField, @NotNull String methodModifier, @NotNull AccessorsInfo accessorsInfo) {
|
||||
public @Nullable PsiMethod createWitherMethod(@NotNull PsiField psiField,
|
||||
@NotNull String methodModifier,
|
||||
@NotNull AccessorsInfo accessorsInfo) {
|
||||
LombokLightMethodBuilder methodBuilder = null;
|
||||
final PsiClass psiFieldContainingClass = psiField.getContainingClass();
|
||||
if (psiFieldContainingClass != null) {
|
||||
|
||||
@@ -11,4 +11,8 @@ public class WithHighlightTest extends AbstractLombokHighlightsTest {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testWitherExample() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
47
plugins/lombok/testData/highlights/with/WitherExample.java
Normal file
47
plugins/lombok/testData/highlights/with/WitherExample.java
Normal file
@@ -0,0 +1,47 @@
|
||||
import lombok.Getter;
|
||||
import lombok.With;
|
||||
|
||||
@With
|
||||
@Getter
|
||||
public class WitherExample {
|
||||
|
||||
private String matchingTypeParameter;
|
||||
private String differentTypeParameter;
|
||||
|
||||
public WitherExample() {
|
||||
this.matchingTypeParameter = null;
|
||||
this.differentTypeParameter = null;
|
||||
}
|
||||
|
||||
public WitherExample(String matchingTypeParameter, String differentTypeParameter) {
|
||||
this.matchingTypeParameter = matchingTypeParameter;
|
||||
this.differentTypeParameter = differentTypeParameter;
|
||||
}
|
||||
|
||||
/*
|
||||
* Intellij GUI displays a compilation warning for this method when it should not.
|
||||
* The warning states that the same method signature is already defined in the class (Lombok @With),
|
||||
* however this is not the case when actually compiled.
|
||||
* The method `withMatchingTypeParameter(String matchingTypeParameter)` is never generated by Lombok as the below method is defined with the same name.
|
||||
*/
|
||||
public WitherExample withMatchingTypeParameter(String matchingTypeParameter) {
|
||||
this.matchingTypeParameter = matchingTypeParameter;
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* When calling this method Intellij GUI displays two options when it should only display one
|
||||
* An option is given for `withDifferentTypeParameter(String differentTypeParameter)`,
|
||||
* however that method is never generated by Lombok as the below method is defined with the same name.
|
||||
*/
|
||||
public WitherExample withDifferentTypeParameter(int differentTypeParameter) {
|
||||
this.differentTypeParameter = String.valueOf(differentTypeParameter);
|
||||
return this;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
WitherExample underTest = new WitherExample("value", "123");
|
||||
underTest.withDifferentTypeParameter(1);
|
||||
underTest.withDifferentTypeParameter<error descr="'withDifferentTypeParameter(int)' in 'WitherExample' cannot be applied to '(java.lang.String)'">("not valid")</error>;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user