mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
generate equals/hashCode: support deep arrays equals for java > 1.5 (IDEA-131533)
This commit is contained in:
@@ -18,9 +18,9 @@ package com.intellij.codeInsight.generation;
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
@@ -234,6 +234,9 @@ public class GenerateEqualsHelper implements Runnable {
|
||||
|
||||
@NonNls private static final MessageFormat ARRAY_COMPARER_MF =
|
||||
new MessageFormat("if(!java.util.Arrays.equals({1}, {0}.{1})) return false;\n");
|
||||
|
||||
@NonNls private static final MessageFormat ARRAY_DEEP_COMPARER_MF =
|
||||
new MessageFormat("if(!java.util.Arrays.deepEquals({1}, {0}.{1})) return false;\n");
|
||||
@NonNls private static final MessageFormat FIELD_COMPARER_MF =
|
||||
new MessageFormat("if({1}!=null ? !{1}.equals({0}.{1}) : {0}.{1}!= null)return false;\n");
|
||||
@NonNls private static final MessageFormat NON_NULL_FIELD_COMPARER_MF = new MessageFormat("if(!{1}.equals({0}.{1}))return false;\n");
|
||||
@@ -244,9 +247,14 @@ public class GenerateEqualsHelper implements Runnable {
|
||||
private void addArrayEquals(StringBuffer buffer, PsiField field) {
|
||||
final PsiType fieldType = field.getType();
|
||||
if (isNestedArray(fieldType)) {
|
||||
buffer.append(" ");
|
||||
buffer.append(CodeInsightBundle.message("generate.equals.compare.nested.arrays.comment", field.getName()));
|
||||
buffer.append("\n");
|
||||
if (JavaVersionService.getInstance().isAtLeast(field, JavaSdkVersion.JDK_1_5)) {
|
||||
ARRAY_DEEP_COMPARER_MF.format(getComparerFormatParameters(field), buffer, null);
|
||||
}
|
||||
else {
|
||||
buffer.append(" ");
|
||||
buffer.append(CodeInsightBundle.message("generate.equals.compare.nested.arrays.comment", field.getName()));
|
||||
buffer.append("\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (isArrayOfObjects(fieldType)) {
|
||||
@@ -474,7 +482,14 @@ public class GenerateEqualsHelper implements Runnable {
|
||||
}
|
||||
|
||||
private static void adjustHashCodeToArrays(@NonNls StringBuilder buffer, final PsiField field, final String name) {
|
||||
if (field.getType() instanceof PsiArrayType && hasArraysHashCode(field)) {
|
||||
final PsiType fieldType = field.getType();
|
||||
if (fieldType instanceof PsiArrayType &&
|
||||
JavaVersionService.getInstance().isAtLeast(field, JavaSdkVersion.JDK_1_5)) {
|
||||
if (isNestedArray(fieldType)) {
|
||||
buffer.append(" ");
|
||||
buffer.append("// Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode");
|
||||
buffer.append("\n");
|
||||
}
|
||||
buffer.append("java.util.Arrays.hashCode(");
|
||||
buffer.append(name);
|
||||
buffer.append(")");
|
||||
@@ -485,16 +500,6 @@ public class GenerateEqualsHelper implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasArraysHashCode(final PsiField field) {
|
||||
// the method was added in JDK 1.5 - check for actual method presence rather than language level
|
||||
Module module = ModuleUtilCore.findModuleForPsiElement(field);
|
||||
if (module == null) return false;
|
||||
PsiClass arraysClass = JavaPsiFacade.getInstance(field.getProject()).findClass("java.util.Arrays", module.getModuleWithLibrariesScope());
|
||||
if (arraysClass == null) return false;
|
||||
final PsiMethod[] methods = arraysClass.findMethodsByName("hashCode", false);
|
||||
return methods.length > 0;
|
||||
}
|
||||
|
||||
@SuppressWarnings("HardCodedStringLiteral")
|
||||
private void addSuperHashCode(StringBuilder buffer) {
|
||||
if (mySuperHasHashCode) {
|
||||
|
||||
+24
-13
@@ -22,8 +22,11 @@ import com.intellij.codeInsight.generation.GenerateEqualsHelper;
|
||||
import com.intellij.ide.wizard.StepAdapter;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.ui.VerticalFlowLayout;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.classMembers.AbstractMemberInfoModel;
|
||||
import com.intellij.refactoring.classMembers.MemberInfoBase;
|
||||
import com.intellij.refactoring.classMembers.MemberInfoTooltipManager;
|
||||
@@ -263,12 +266,15 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass,
|
||||
public String getTooltip(MemberInfo memberInfo) {
|
||||
if (checkForProblems(memberInfo) == OK) return null;
|
||||
if (!(memberInfo.getMember() instanceof PsiField)) return CodeInsightBundle.message("generate.equals.hashcode.internal.error");
|
||||
final PsiType type = ((PsiField)memberInfo.getMember()).getType();
|
||||
if (GenerateEqualsHelper.isNestedArray(type)) {
|
||||
return CodeInsightBundle .message("generate.equals.warning.equals.for.nested.arrays.not.supported");
|
||||
}
|
||||
if (GenerateEqualsHelper.isArrayOfObjects(type)) {
|
||||
return CodeInsightBundle.message("generate.equals.warning.generated.equals.could.be.incorrect");
|
||||
final PsiField field = (PsiField)memberInfo.getMember();
|
||||
if (!JavaVersionService.getInstance().isAtLeast(field, JavaSdkVersion.JDK_1_5)) {
|
||||
final PsiType type = field.getType();
|
||||
if (GenerateEqualsHelper.isNestedArray(type)) {
|
||||
return CodeInsightBundle .message("generate.equals.warning.equals.for.nested.arrays.not.supported");
|
||||
}
|
||||
if (GenerateEqualsHelper.isArrayOfObjects(type)) {
|
||||
return CodeInsightBundle.message("generate.equals.warning.generated.equals.could.be.incorrect");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -277,16 +283,20 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass,
|
||||
@Override
|
||||
public boolean isMemberEnabled(MemberInfo member) {
|
||||
if (!(member.getMember() instanceof PsiField)) return false;
|
||||
final PsiType type = ((PsiField)member.getMember()).getType();
|
||||
return !GenerateEqualsHelper.isNestedArray(type);
|
||||
final PsiField field = (PsiField)member.getMember();
|
||||
final PsiType type = field.getType();
|
||||
return JavaVersionService.getInstance().isAtLeast(field, JavaSdkVersion.JDK_1_5) || !GenerateEqualsHelper.isNestedArray(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int checkForProblems(@NotNull MemberInfo member) {
|
||||
if (!(member.getMember() instanceof PsiField)) return ERROR;
|
||||
final PsiType type = ((PsiField)member.getMember()).getType();
|
||||
if (GenerateEqualsHelper.isNestedArray(type)) return ERROR;
|
||||
if (GenerateEqualsHelper.isArrayOfObjects(type)) return WARNING;
|
||||
final PsiField field = (PsiField)member.getMember();
|
||||
final PsiType type = field.getType();
|
||||
if (!JavaVersionService.getInstance().isAtLeast(field, JavaSdkVersion.JDK_1_5)) {
|
||||
if (GenerateEqualsHelper.isNestedArray(type)) return ERROR;
|
||||
if (GenerateEqualsHelper.isArrayOfObjects(type)) return WARNING;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -302,8 +312,9 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass,
|
||||
public String getTooltip(MemberInfo memberInfo) {
|
||||
if (isMemberEnabled(memberInfo)) return null;
|
||||
if (!(memberInfo.getMember() instanceof PsiField)) return CodeInsightBundle.message("generate.equals.hashcode.internal.error");
|
||||
final PsiType type = ((PsiField)memberInfo.getMember()).getType();
|
||||
if (!(type instanceof PsiArrayType)) return null;
|
||||
final PsiField field = (PsiField)memberInfo.getMember();
|
||||
final PsiType type = field.getType();
|
||||
if (!(type instanceof PsiArrayType) || JavaVersionService.getInstance().isAtLeast(field, JavaSdkVersion.JDK_1_5)) return null;
|
||||
return CodeInsightBundle.message("generate.equals.hashcode.warning.hashcode.for.arrays.is.not.supported");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@ class Test {
|
||||
|
||||
final Test test = (Test) o;
|
||||
|
||||
// Compare nested arrays - values of myIIs here
|
||||
if (!Arrays.deepEquals(myIIs, test.myIIs)) return false;
|
||||
if (!Arrays.equals(myIs, test.myIs)) return false;
|
||||
// Probably incorrect - comparing Object[] arrays with Arrays.equals
|
||||
if (!Arrays.equals(myOs, test.myOs)) return false;
|
||||
@@ -21,7 +21,8 @@ class Test {
|
||||
|
||||
public int hashCode() {
|
||||
int result = myOs != null ? Arrays.hashCode(myOs) : 0;
|
||||
result = 31 * result + (myIIs != null ? Arrays.hashCode(myIIs) : 0);
|
||||
result = 31 * result + (myIIs != null ? // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
|
||||
Arrays.hashCode(myIIs) : 0);
|
||||
result = 31 * result + (myIs != null ? Arrays.hashCode(myIs) : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user