aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaksha Vasisht2011-10-10 11:40:28 (EDT)
committerRaksha Vasisht2011-10-11 05:00:22 (EDT)
commit8bddf00407bfda5dcb448394c7dfd59664ed5281 (patch)
tree944045b38329f2dfa32b166396aa7e4268bcee4a
parent784a8ef626fc1a34a10d69659b8efda2d2ae211b (diff)
downloadeclipse.jdt.ui-8bddf00407bfda5dcb448394c7dfd59664ed5281.zip
eclipse.jdt.ui-8bddf00407bfda5dcb448394c7dfd59664ed5281.tar.gz
eclipse.jdt.ui-8bddf00407bfda5dcb448394c7dfd59664ed5281.tar.bz2
Fixed bug 304176:[hashcode/equals] Generated equals() should use
Arrays.deepEquals() instead of Arrays.equals()
-rw-r--r--org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/source/GenerateHashCodeEqualsTest.java73
-rw-r--r--org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/GenerateHashCodeEqualsOperation.java40
2 files changed, 106 insertions, 7 deletions
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/source/GenerateHashCodeEqualsTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/source/GenerateHashCodeEqualsTest.java
index 6bc07bd..c5af64a 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/source/GenerateHashCodeEqualsTest.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/source/GenerateHashCodeEqualsTest.java
@@ -1421,5 +1421,76 @@ public class GenerateHashCodeEqualsTest extends SourceTestCase {
compareSource(expected, a.getSource());
}
+
+ /**
+ * Test that generated equals() should use Arrays.deepEquals() instead of Arrays.equals() for projects with compliance >= 1.5
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=304176
+ *
+ * @throws Exception rarely
+ */
+ public void testArraysDeepEqualsIn15() throws Exception {
+ IJavaProject javaProject= fPackageP.getJavaProject();
+ Map oldOptions= javaProject.getOptions(false);
+ Map newOptions= new HashMap(oldOptions);
+ JavaModelUtil.setComplianceOptions(newOptions, JavaCore.VERSION_1_5);
+ javaProject.setOptions(newOptions);
+ try {
+ ICompilationUnit a= fPackageP.createCompilationUnit("A.java", "package p;\r\n" +
+ "\r\n" +
+ "public class A {\r\n" +
+ "\r\n" +
+ " int[][][] a = new int[][][] {{null}};\r\n" +
+ " int[][][] b = new int[][][] {{null}};\r\n" +
+ "\r\n" +
+ "}\r\n" +
+ "", true, null);
-}
+ IField[] fields= getFields(a.getType("A"), new String[] {"a", "b"});
+ runOperation(a.getType("A"), fields, false, false);
+
+ String expected= "package p;\r\n" +
+ "\r\n" +
+ "import java.util.Arrays;\r\n" +
+ "\r\n" +
+ "public class A {\r\n" +
+ "\r\n" +
+ " int[][][] a = new int[][][] {{null}};\r\n" +
+ " int[][][] b = new int[][][] {{null}};\r\n" +
+ " /* (non-Javadoc)\r\n" +
+ " * @see java.lang.Object#hashCode()\r\n" +
+ " */\r\n" +
+ " @Override\r\n" +
+ " public int hashCode() {\r\n" +
+ " final int prime = 31;\r\n" +
+ " int result = 1;\r\n" +
+ " result = prime * result + Arrays.hashCode(a);\r\n" +
+ " result = prime * result + Arrays.hashCode(b);\r\n" +
+ " return result;\r\n" +
+ " }\r\n" +
+ " /* (non-Javadoc)\r\n" +
+ " * @see java.lang.Object#equals(java.lang.Object)\r\n" +
+ " */\r\n" +
+ " @Override\r\n" +
+ " public boolean equals(Object obj) {\r\n" +
+ " if (this == obj)\r\n" +
+ " return true;\r\n" +
+ " if (obj == null)\r\n" +
+ " return false;\r\n" +
+ " if (getClass() != obj.getClass())\r\n" +
+ " return false;\r\n" +
+ " A other = (A) obj;\r\n" +
+ " if (!Arrays.deepEquals(a, other.a))\r\n" +
+ " return false;\r\n" +
+ " if (!Arrays.deepEquals(b, other.b))\r\n" +
+ " return false;\r\n" +
+ " return true;\r\n" +
+ " }\r\n" +
+ "\r\n" +
+ "}" +
+ "";
+ compareSource(expected, a.getSource());
+ } finally {
+ javaProject.setOptions(oldOptions);
+ }
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/GenerateHashCodeEqualsOperation.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/GenerateHashCodeEqualsOperation.java
index 8416c46..bc7f17e 100644
--- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/GenerateHashCodeEqualsOperation.java
+++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/GenerateHashCodeEqualsOperation.java
@@ -138,6 +138,8 @@ public final class GenerateHashCodeEqualsOperation implements IWorkspaceRunnable
private static final String METHODNAME_GETCLASS= "getClass"; //$NON-NLS-1$
private static final String METHODNAME_EQUALS= "equals"; //$NON-NLS-1$
+
+ private static final String METHODNAME_DEEP_EQUALS= "deepEquals"; //$NON-NLS-1$
private static final String METHODNAME_HASH_CODE= "hashCode"; //$NON-NLS-1$
@@ -853,12 +855,20 @@ public final class GenerateHashCodeEqualsOperation implements IWorkspaceRunnable
}
for (int i= 0; i < fFields.length; i++) {
- if (fFields[i].getType().isPrimitive() || fFields[i].getType().isEnum())
- body.statements().add(createSimpleComparison(fFields[i]));
- else if (fFields[i].getType().isArray())
- body.statements().add(createArrayComparison(fFields[i].getName()));
- else
- body.statements().add(createQualifiedComparison(fFields[i].getName()));
+ IVariableBinding field= fFields[i];
+ ITypeBinding type= field.getType();
+ if (type.isPrimitive() || type.isEnum())
+ body.statements().add(createSimpleComparison(field));
+ else if (type.isArray()) {
+ IJavaProject project= fUnit.getJavaElement().getJavaProject();
+ if (type.getDimensions() > 1 && JavaModelUtil.is50OrHigher(project)) {
+ body.statements().add(createMultiArrayComparison(field.getName()));
+ } else {
+ body.statements().add(createArrayComparison(field.getName()));
+ }
+ } else
+ body.statements().add(createQualifiedComparison(field.getName()));
+
}
// the last return true:
@@ -934,6 +944,24 @@ public final class GenerateHashCodeEqualsOperation implements IWorkspaceRunnable
return ifSt;
}
+
+ private Statement createMultiArrayComparison(String name) {
+ MethodInvocation invoc= fAst.newMethodInvocation();
+ invoc.setName(fAst.newSimpleName(METHODNAME_DEEP_EQUALS));
+ invoc.setExpression(getQualifiedName(JAVA_UTIL_ARRAYS));
+ invoc.arguments().add(getThisAccessForEquals(name));
+ invoc.arguments().add(getOtherAccess(name));
+
+ PrefixExpression pe= fAst.newPrefixExpression();
+ pe.setOperator(PrefixExpression.Operator.NOT);
+ pe.setOperand(invoc);
+
+ IfStatement ifSt= fAst.newIfStatement();
+ ifSt.setExpression(pe);
+ ifSt.setThenStatement(getThenStatement(getReturnFalse()));
+
+ return ifSt;
+ }
/**
* Creates a comparison of reference types.