mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-06 03:21:12 +07:00
fixed #761 Fix checks for methods that already exists in code, for equals/hashCode and toString
GitOrigin-RevId: 12cf760279af229cfd21fc81b9142d84f61bedc1
This commit is contained in:
committed by
intellij-monorepo-bot
parent
f73adab6db
commit
c412c6fddd
@@ -1,6 +1,7 @@
|
||||
<ul>
|
||||
<li>0.32
|
||||
<ol>
|
||||
<li>Fixed #761: EqualsAndHashCode: Wrong warning 'A method with one of those names already exists'</li>
|
||||
<li>Fixed #802: [Only for IntelliJ>=2020.2.2] val mis-infers an Optional(T) as Optional(Object) after map.</li>
|
||||
<li>Fixed #826: Error if using @FieldNameConstants in switch case</li>
|
||||
<li>Fixed #858: Delombok produces duplicate @NonNull annotations on setters/getters</li>
|
||||
|
||||
@@ -114,17 +114,16 @@ public class EqualsAndHashCodeProcessor extends AbstractClassProcessor {
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean validateExistingMethods(@NotNull PsiClass psiClass, @NotNull ProblemBuilder builder) {
|
||||
private void validateExistingMethods(@NotNull PsiClass psiClass, @NotNull ProblemBuilder builder) {
|
||||
if (hasOneOfMethodsDefined(psiClass)) {
|
||||
builder.addWarning("Not generating equals and hashCode: A method with one of those names already exists. (Either both or none of these methods will be generated).");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean hasOneOfMethodsDefined(@NotNull PsiClass psiClass) {
|
||||
final Collection<PsiMethod> classMethodsIntern = PsiClassUtil.collectClassMethodsIntern(psiClass);
|
||||
return PsiMethodUtil.hasMethodByName(classMethodsIntern, EQUALS_METHOD_NAME, HASH_CODE_METHOD_NAME);
|
||||
return PsiMethodUtil.hasMethodByName(classMethodsIntern, EQUALS_METHOD_NAME, 1) ||
|
||||
PsiMethodUtil.hasMethodByName(classMethodsIntern, HASH_CODE_METHOD_NAME, 0);
|
||||
}
|
||||
|
||||
protected void generatePsiElements(@NotNull PsiClass psiClass, @NotNull PsiAnnotation psiAnnotation, @NotNull List<? super PsiElement> target) {
|
||||
@@ -145,7 +144,7 @@ public class EqualsAndHashCodeProcessor extends AbstractClassProcessor {
|
||||
result.add(createEqualsMethod(psiClass, psiAnnotation, shouldGenerateCanEqual, memberInfos));
|
||||
|
||||
final Collection<PsiMethod> classMethods = PsiClassUtil.collectClassMethodsIntern(psiClass);
|
||||
if (shouldGenerateCanEqual && !PsiMethodUtil.hasMethodByName(classMethods, CAN_EQUAL_METHOD_NAME)) {
|
||||
if (shouldGenerateCanEqual && !PsiMethodUtil.hasMethodByName(classMethods, CAN_EQUAL_METHOD_NAME, 1)) {
|
||||
result.add(createCanEqualMethod(psiClass, psiAnnotation));
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import java.util.List;
|
||||
*/
|
||||
public class ToStringProcessor extends AbstractClassProcessor {
|
||||
|
||||
public static final String METHOD_NAME = "toString";
|
||||
public static final String TO_STRING_METHOD_NAME = "toString";
|
||||
|
||||
private static final String INCLUDE_ANNOTATION_METHOD = "name";
|
||||
private static final String INCLUDE_ANNOTATION_RANK = "rank";
|
||||
@@ -75,16 +75,15 @@ public class ToStringProcessor extends AbstractClassProcessor {
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean validateExistingMethods(@NotNull PsiClass psiClass, @NotNull ProblemBuilder builder) {
|
||||
boolean result = true;
|
||||
|
||||
final Collection<PsiMethod> classMethods = PsiClassUtil.collectClassMethodsIntern(psiClass);
|
||||
if (PsiMethodUtil.hasMethodByName(classMethods, METHOD_NAME)) {
|
||||
builder.addWarning("Not generated '%s'(): A method with same name already exists", METHOD_NAME);
|
||||
result = false;
|
||||
private void validateExistingMethods(@NotNull PsiClass psiClass, @NotNull ProblemBuilder builder) {
|
||||
if (hasToStringMethodDefined(psiClass)) {
|
||||
builder.addWarning("Not generated '%s'(): A method with same name already exists", TO_STRING_METHOD_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
private boolean hasToStringMethodDefined(@NotNull PsiClass psiClass) {
|
||||
final Collection<PsiMethod> classMethods = PsiClassUtil.collectClassMethodsIntern(psiClass);
|
||||
return PsiMethodUtil.hasMethodByName(classMethods, TO_STRING_METHOD_NAME, 0);
|
||||
}
|
||||
|
||||
protected void generatePsiElements(@NotNull PsiClass psiClass, @NotNull PsiAnnotation psiAnnotation, @NotNull List<? super PsiElement> target) {
|
||||
@@ -93,8 +92,7 @@ public class ToStringProcessor extends AbstractClassProcessor {
|
||||
|
||||
@NotNull
|
||||
Collection<PsiMethod> createToStringMethod(@NotNull PsiClass psiClass, @NotNull PsiAnnotation psiAnnotation) {
|
||||
final Collection<PsiMethod> classMethods = PsiClassUtil.collectClassMethodsIntern(psiClass);
|
||||
if (PsiMethodUtil.hasMethodByName(classMethods, METHOD_NAME)) {
|
||||
if (hasToStringMethodDefined(psiClass)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@@ -110,7 +108,7 @@ public class ToStringProcessor extends AbstractClassProcessor {
|
||||
final String paramString = createParamString(psiClass, memberInfos, psiAnnotation, forceCallSuper);
|
||||
final String blockText = String.format("return \"%s(%s)\";", getSimpleClassName(psiClass), paramString);
|
||||
|
||||
final LombokLightMethodBuilder methodBuilder = new LombokLightMethodBuilder(psiManager, METHOD_NAME)
|
||||
final LombokLightMethodBuilder methodBuilder = new LombokLightMethodBuilder(psiManager, TO_STRING_METHOD_NAME)
|
||||
.withMethodReturnType(PsiType.getJavaLangString(psiManager, GlobalSearchScope.allScope(psiClass.getProject())))
|
||||
.withContainingClass(psiClass)
|
||||
.withNavigationElement(psiAnnotation)
|
||||
|
||||
@@ -61,7 +61,7 @@ public class BuilderPreDefinedInnerClassMethodProcessor extends AbstractBuilderP
|
||||
}
|
||||
|
||||
// create 'toString' method
|
||||
if (!existedMethodNames.contains(ToStringProcessor.METHOD_NAME)) {
|
||||
if (!existedMethodNames.contains(ToStringProcessor.TO_STRING_METHOD_NAME)) {
|
||||
result.add(builderHandler.createToStringMethod(psiAnnotation, psiBuilderClass));
|
||||
}
|
||||
|
||||
|
||||
@@ -211,7 +211,7 @@ public class EqualsAndHashCodeToStringHandler {
|
||||
final PsiAnnotation getterLombokAnnotation = PsiAnnotationSearchUtil.findAnnotation(psiClass, Getter.class);
|
||||
hasGetter = null == getterLombokAnnotation || null != LombokProcessorUtil.getMethodModifier(getterLombokAnnotation);
|
||||
} else {
|
||||
hasGetter = PsiMethodUtil.hasMethodByName(PsiClassUtil.collectClassMethodsIntern(psiClass), getterName);
|
||||
hasGetter = PsiMethodUtil.hasMethodByName(PsiClassUtil.collectClassMethodsIntern(psiClass), getterName, 0);
|
||||
}
|
||||
|
||||
return hasGetter ? getterName + "()" : fieldName;
|
||||
|
||||
@@ -343,7 +343,7 @@ public class SuperBuilderHandler extends BuilderHandler {
|
||||
result.add(buildMethod);
|
||||
}
|
||||
|
||||
if (!existedMethodNames.contains(ToStringProcessor.METHOD_NAME)) {
|
||||
if (!existedMethodNames.contains(ToStringProcessor.TO_STRING_METHOD_NAME)) {
|
||||
// create 'toString' method
|
||||
result.add(createToStringMethod(psiAnnotation, baseClassBuilder, forceCallSuper));
|
||||
}
|
||||
|
||||
@@ -3,9 +3,7 @@ package de.plushnikov.intellij.plugin.util;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Plushnikov Michail
|
||||
@@ -17,35 +15,25 @@ public class PsiMethodUtil {
|
||||
return elementFactory.createCodeBlockFromText("{" + blockText + "}", psiElement);
|
||||
}
|
||||
|
||||
public static boolean hasMethodByName(@NotNull Collection<PsiMethod> classMethods, @NotNull String methodName) {
|
||||
return classMethods.stream().map(PsiMethod::getName).anyMatch(methodName::equals);
|
||||
public static boolean hasMethodByName(@NotNull Collection<PsiMethod> classMethods, @NotNull String methodName, int paramCount) {
|
||||
return classMethods.stream()
|
||||
.filter(m -> methodName.equals(m.getName()))
|
||||
.anyMatch(m -> acceptedParameterCount(m, paramCount));
|
||||
}
|
||||
|
||||
public static boolean hasMethodByName(@NotNull Collection<PsiMethod> classMethods, String... methodNames) {
|
||||
final List<String> searchedMethodNames = Arrays.asList(methodNames);
|
||||
return classMethods.stream().map(PsiMethod::getName).anyMatch(searchedMethodNames::contains);
|
||||
public static boolean hasSimilarMethod(@NotNull Collection<PsiMethod> classMethods, @NotNull String methodName, int paramCount) {
|
||||
return classMethods.stream()
|
||||
.filter(m -> methodName.equalsIgnoreCase(m.getName()))
|
||||
.anyMatch(m -> acceptedParameterCount(m, paramCount));
|
||||
}
|
||||
|
||||
public static boolean hasSimilarMethod(@NotNull Collection<PsiMethod> classMethods, @NotNull String methodName, int methodArgCount) {
|
||||
for (PsiMethod classMethod : classMethods) {
|
||||
if (isSimilarMethod(classMethod, methodName, methodArgCount)) {
|
||||
return true;
|
||||
}
|
||||
private static boolean acceptedParameterCount(@NotNull PsiMethod classMethod, int methodArgCount) {
|
||||
int minArgs = classMethod.getParameterList().getParametersCount();
|
||||
int maxArgs = minArgs;
|
||||
if (classMethod.isVarArgs()) {
|
||||
minArgs--;
|
||||
maxArgs = Integer.MAX_VALUE;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isSimilarMethod(@NotNull PsiMethod classMethod, @NotNull String methodName, int methodArgCount) {
|
||||
boolean equalNames = methodName.equalsIgnoreCase(classMethod.getName());
|
||||
if (equalNames) {
|
||||
int minArgs = classMethod.getParameterList().getParametersCount();
|
||||
int maxArgs = minArgs;
|
||||
if (classMethod.isVarArgs()) {
|
||||
minArgs--;
|
||||
maxArgs = Integer.MAX_VALUE;
|
||||
}
|
||||
return !(methodArgCount < minArgs || methodArgCount > maxArgs);
|
||||
}
|
||||
return false;
|
||||
return !(methodArgCount < minArgs || methodArgCount > maxArgs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ daemon.donate.title=Lombok support plugin updated to v{0}
|
||||
daemon.donate.content=<br/>\
|
||||
Helpful? <b><a href="https://www.paypal.me/mplushnikov">Donate with PayPal</a></b><br/><br/>\
|
||||
Fixes:<br/>\
|
||||
- Fixed (<a href="https://github.com/mplushnikov/lombok-intellij-plugin/issues/761">#761</a>): EqualsAndHashCode: Wrong warning 'A method with one of those names already exists'<br/>\
|
||||
- Fixed (<a href="https://github.com/mplushnikov/lombok-intellij-plugin/issues/802">#802</a>): val mis-infers an Optional(T) as Optional(Object) after map. Only for IntelliJ>=2020.2.2<br/>\
|
||||
- Fixed (<a href="https://github.com/mplushnikov/lombok-intellij-plugin/issues/826">#826</a>): Error if using @FieldNameConstants in switch case<br/>\
|
||||
- Fixed (<a href="https://github.com/mplushnikov/lombok-intellij-plugin/issues/858">#858</a>): Delombok produces duplicate @NonNull annotations on setters/getters<br/>\
|
||||
|
||||
@@ -59,4 +59,7 @@ public class EqualsAndHashCodeTest extends AbstractLombokParsingTestCase {
|
||||
doTest(true);
|
||||
}
|
||||
|
||||
public void testEqualsandhashcode$EqualsAndHashCodeWithNamedExistingMethods() {
|
||||
doTest(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,4 +38,8 @@ public class ToStringTest extends AbstractLombokParsingTestCase {
|
||||
public void testTostring$ToStringSimpleClassName() {
|
||||
doTest(true);
|
||||
}
|
||||
|
||||
public void testTostring$ToStringWithNamedExistingMethods() {
|
||||
doTest(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import java.util.Objects;
|
||||
|
||||
public class EqualsAndHashCodeWithNamedExistingMethods {
|
||||
private int someInt;
|
||||
private Integer someInteger;
|
||||
|
||||
public boolean equals(Object o, Object o2) {
|
||||
return o.equals(o2);
|
||||
}
|
||||
|
||||
public int hashCode(Float someFloat) {
|
||||
return Objects.hash(someFloat);
|
||||
}
|
||||
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) return true;
|
||||
if (!(o instanceof EqualsAndHashCodeWithNamedExistingMethods)) return false;
|
||||
final EqualsAndHashCodeWithNamedExistingMethods other = (EqualsAndHashCodeWithNamedExistingMethods) o;
|
||||
if (!other.canEqual((Object) this)) return false;
|
||||
if (this.someInt != other.someInt) return false;
|
||||
final Object this$someInteger = this.someInteger;
|
||||
final Object other$someInteger = other.someInteger;
|
||||
if (this$someInteger == null ? other$someInteger != null : !this$someInteger.equals(other$someInteger))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean canEqual(final Object other) {
|
||||
return other instanceof EqualsAndHashCodeWithNamedExistingMethods;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
final int PRIME = 59;
|
||||
int result = 1;
|
||||
result = result * PRIME + this.someInt;
|
||||
final Object $someInteger = this.someInteger;
|
||||
result = result * PRIME + ($someInteger == null ? 43 : $someInteger.hashCode());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
public class ToStringWithNamedExistingMethods {
|
||||
private int someInt;
|
||||
|
||||
public String toString(String string) {
|
||||
return string;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "ToStringWithNamedExistingMethods(someInt=" + this.someInt + ")";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@EqualsAndHashCode
|
||||
public class EqualsAndHashCodeWithNamedExistingMethods {
|
||||
<caret>
|
||||
private int someInt;
|
||||
private Integer someInteger;
|
||||
|
||||
public boolean equals(Object o, Object o2) {
|
||||
return o.equals(o2);
|
||||
}
|
||||
|
||||
public int hashCode(Float someFloat) {
|
||||
return Objects.hash(someFloat);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import lombok.ToString;
|
||||
|
||||
@ToString
|
||||
public class ToStringWithNamedExistingMethods {
|
||||
<caret>
|
||||
private int someInt;
|
||||
|
||||
public String toString(String string) {
|
||||
return string;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user