[lombok] IDEA-352970 IDEA-355936 Improve @Setter can be used inspection

GitOrigin-RevId: 8e5968de01c8ecc43fedc98cd0ff3df5eb1390be
This commit is contained in:
Michail Plushnikov
2024-09-10 19:54:19 +02:00
committed by intellij-monorepo-bot
parent eaf8c3f891
commit 88bf89d55f
5 changed files with 88 additions and 12 deletions

View File

@@ -36,11 +36,11 @@ public abstract class LombokGetterOrSetterMayBeUsedInspection extends LombokJava
private class LombokGetterOrSetterMayBeUsedVisitor extends JavaElementVisitor {
private final @Nullable ProblemsHolder myHolder;
private final @Nullable LombokGetterOrSetterMayBeUsedInspection.LombokGetterOrSetterMayBeUsedFix myLombokGetterOrSetterMayBeUsedFix;
private final @Nullable LombokGetterOrSetterMayBeUsedFix myLombokGetterOrSetterMayBeUsedFix;
private LombokGetterOrSetterMayBeUsedVisitor(
@Nullable ProblemsHolder holder,
@Nullable LombokGetterOrSetterMayBeUsedInspection.LombokGetterOrSetterMayBeUsedFix lombokGetterOrSetterMayBeUsedFix
@Nullable LombokGetterOrSetterMayBeUsedFix lombokGetterOrSetterMayBeUsedFix
) {
this.myHolder = holder;
this.myLombokGetterOrSetterMayBeUsedFix = lombokGetterOrSetterMayBeUsedFix;

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package de.plushnikov.intellij.plugin.inspection;
import com.intellij.lang.jvm.JvmMethod;
import com.intellij.lang.jvm.JvmModifier;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
@@ -92,6 +93,26 @@ public final class LombokSetterMayBeUsedInspection extends LombokGetterOrSetterM
return false;
}
final PsiClass containingClass = method.getContainingClass();
if (containingClass == null) {
return false;
}
// skip setter candidates if multiple methods with the same name (and without @Tolerate) exist (lombok would skip generation)
final PsiMethod[] methods = containingClass.findMethodsByName(methodName, false);
if (methods.length > 1) {
boolean skipMethod = false;
for (PsiMethod psiMethod : methods) {
if (!psiMethod.hasAnnotation(LombokClassNames.TOLERATE) && !psiMethod.equals(method)) {
skipMethod = true;
break;
}
}
if (skipMethod) {
return false;
}
}
final String fieldName = StringUtil.getPropertyName(methodName);
if (StringUtil.isEmpty(fieldName)) {
return false;
@@ -100,7 +121,8 @@ public final class LombokSetterMayBeUsedInspection extends LombokGetterOrSetterM
if (method.getBody() == null) {
return false;
}
final PsiStatement @NotNull [] methodStatements = Arrays.stream(method.getBody().getStatements()).filter(e -> !(e instanceof PsiEmptyStatement)).toArray(PsiStatement[]::new);
final PsiStatement @NotNull [] methodStatements =
Arrays.stream(method.getBody().getStatements()).filter(e -> !(e instanceof PsiEmptyStatement)).toArray(PsiStatement[]::new);
if (methodStatements.length != 1) {
return false;
}
@@ -112,7 +134,8 @@ public final class LombokSetterMayBeUsedInspection extends LombokGetterOrSetterM
if (assignment == null || assignment.getOperationTokenType() != JavaTokenType.EQ) {
return false;
}
final PsiReferenceExpression sourceRef = tryCast(PsiUtil.skipParenthesizedExprDown(assignment.getRExpression()), PsiReferenceExpression.class);
final PsiReferenceExpression sourceRef =
tryCast(PsiUtil.skipParenthesizedExprDown(assignment.getRExpression()), PsiReferenceExpression.class);
if (sourceRef == null || sourceRef.getQualifierExpression() != null) {
return false;
}
@@ -129,15 +152,12 @@ public final class LombokSetterMayBeUsedInspection extends LombokGetterOrSetterM
}
final @Nullable PsiExpression qualifier = targetRef.getQualifierExpression();
final @Nullable PsiThisExpression thisExpression = tryCast(qualifier, PsiThisExpression.class);
final PsiClass psiClass = PsiTreeUtil.getParentOfType(method, PsiClass.class);
if (psiClass == null) {
return false;
}
if (qualifier != null) {
if (thisExpression == null) {
return false;
} else if (thisExpression.getQualifier() != null) {
if (!thisExpression.getQualifier().isReferenceTo(psiClass)) {
}
else if (thisExpression.getQualifier() != null) {
if (!thisExpression.getQualifier().isReferenceTo(containingClass)) {
return false;
}
}
@@ -155,7 +175,7 @@ public final class LombokSetterMayBeUsedInspection extends LombokGetterOrSetterM
}
final boolean isMethodStatic = method.hasModifierProperty(PsiModifier.STATIC);
final PsiField field = psiClass.findFieldByName(fieldIdentifier, false);
final PsiField field = containingClass.findFieldByName(fieldIdentifier, false);
if (field == null
|| !field.isWritable()
|| isMethodStatic != field.hasModifierProperty(PsiModifier.STATIC)
@@ -164,7 +184,8 @@ public final class LombokSetterMayBeUsedInspection extends LombokGetterOrSetterM
}
if (isMethodStatic) {
staticCandidates.add(Pair.pair(field, method));
} else {
}
else {
instanceCandidates.add(Pair.pair(field, method));
}
return true;

View File

@@ -40,4 +40,12 @@ public class LombokSetterMayBeUsedInspectionTest extends LightDaemonAnalyzerTest
public void testInstanceAndStaticFields() {
doTest();
}
public void testSetterAlreadyUsed() {
doTest();
}
public void testSetterAlreadyUsedTolerate() {
doTest();
}
}

View File

@@ -0,0 +1,23 @@
import lombok.Setter;
@Setter
public class SetterAlreadyUsed {
private int number;
private String codeBlue;
//NO warning descr="Field 'codeBlue' may have Lombok @Setter" !
public void setCodeBlue(String codeBlue) {
this.codeBlue = codeBlue;
}
public void setCodeBlue(boolean codeBlue) {
this.codeBlue = Boolean.toString(codeBlue);
}
public static void main(String[] args) {
final SetterAlreadyUsed obj1 = new SetterAlreadyUsed();
obj1.setCodeBlue(true);
obj1.setCodeBlue("false");
System.out.println(obj1);
}
}

View File

@@ -0,0 +1,24 @@
import lombok.Setter;
import lombok.experimental.Tolerate;
@Setter
public class SetterAlreadyUsedTolerate {
private int number;
private String codeBlue;
<warning descr="Field 'codeBlue' may have Lombok @Setter">public void setCodeBlue(String codeBlue) {
this.codeBlue = codeBlue;
}</warning>
@Tolerate
public void setCodeBlue(boolean codeBlue) {
this.codeBlue = Boolean.toString(codeBlue);
}
public static void main(String[] args) {
final SetterAlreadyUsedTolerate obj1 = new SetterAlreadyUsedTolerate();
obj1.setCodeBlue(true);
obj1.setCodeBlue("false");
System.out.println(obj1);
}
}