Java: use Java 8 primitive wrapper static hashCode() methods when generating hashCode() (IDEA-152920)

GitOrigin-RevId: eeebfeed7f8fb7d69322d407345298995635d6aa
This commit is contained in:
Bas Leijdekkers
2023-11-15 22:58:11 +00:00
committed by intellij-monorepo-bot
parent d3e6301c6a
commit fdcadc203c
6 changed files with 114 additions and 18 deletions
@@ -2,7 +2,7 @@ public int hashCode() {
#if (!$superHasHashCode && $fields.size() == 1)
#set($field = $fields.get(0))
#if ($field.primitive)
#addTempForOneField($field)
#addTempForOneField($field)
return #addPrimitiveFieldHashCode($field);
#else
return #addFieldHashCode($field, false);
@@ -48,14 +48,30 @@ public int hashCode() {
#if ($field.byte || $field.short || $field.char)
(int) $fName##
#elseif ($field.long)
(int)($fName ^ ($fName >>> 32))##
#if ($java_version < 8)
(int)($fName ^ ($fName >>> 32))##
#else
java.lang.Long.hashCode($fName)##
#end
#elseif ($field.boolean)
($fName ? 1 : 0)##
#if ($java_version < 8)
($fName ? 1 : 0)##
#else
java.lang.Boolean.hashCode($fName)##
#end
#elseif ($field.float)
java.lang.Float.floatToIntBits($fName)##
#if ($java_version < 8)
java.lang.Float.floatToIntBits($fName)##
#else
java.lang.Float.hashCode($fName)##
#end
#elseif ($field.double)
#set($tempName = "#getTempVarName()")
(int) ($tempName ^ ($tempName >>> 32))##
#if ($java_version < 8)
#set($tempName = "#getTempVarName()")
(int) ($tempName ^ ($tempName >>> 32))##
#else
java.lang.Double.hashCode($fName)##
#end
#elseif ($field.void)
0##
#else
@@ -68,17 +84,17 @@ public int hashCode() {
#end
##
#macro(addTempForOneField $field)
#if ($field.double)
#if ($field.double && $java_version < 8)
#if ($settings.generateFinalLocals)
final ##
final ##
#end
#set($tempName = "#getTempVarName()")
long $tempName = java.lang.Double.doubleToLongBits($field.accessor);
#set($tempName = "#getTempVarName()")
long $tempName = java.lang.Double.doubleToLongBits($field.accessor);
#end
#end
##
#macro(adjustHashCodeToArrays $field)
#if ($field.array && $java_version > 4)
#if ($field.array && $java_version > 4)
#if ($field.nestedArray)
java.util.Arrays.deepHashCode($field.accessor)##
#else
@@ -99,7 +115,7 @@ public int hashCode() {
##
#macro(addTempDeclaration $resultDeclarationCompleted)
#foreach($field in $fields)
#if ($field.double)
#if ($field.double && $java_version < 8)
#if (!$resultDeclarationCompleted)
;
#end
@@ -112,16 +128,16 @@ public int hashCode() {
#end
##
#macro(addTempAssignment $field)
#if ($field.double)
#if ($field.double && $java_version < 8)
#set($tempName = "#getTempVarName()")
$tempName = java.lang.Double.doubleToLongBits($field.accessor);
#end
#end
##
#macro(addFieldHashCode $field $brace)
#set($name = $field.accessor)
#if ($field.notNull)#adjustHashCodeToArrays($field)
#elseif ($field.array && $java_version > 4)#adjustHashCodeToArrays($field)
#set($name = $field.accessor)
#if ($field.notNull)#adjustHashCodeToArrays($field)
#elseif ($field.array && $java_version > 4)#adjustHashCodeToArrays($field)
#else
#if ($brace)(##
#end
@@ -0,0 +1,18 @@
class Test {
double d;
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final Test test = (Test) o;
if (Double.compare(d, test.d) != 0) return false;
return true;
}
public int hashCode() {
return Double.hashCode(d);
}
}
@@ -0,0 +1,37 @@
public class X {
private long l = 1l;
private boolean b = true;
private byte v = 1;
private short s = 1;
private int i = 1;
private float f = 1.0f;
private double d = 1.0;
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final X x = (X) o;
if (l != x.l) return false;
if (b != x.b) return false;
if (v != x.v) return false;
if (s != x.s) return false;
if (i != x.i) return false;
if (Float.compare(f, x.f) != 0) return false;
if (Double.compare(d, x.d) != 0) return false;
return true;
}
public int hashCode() {
int result = Long.hashCode(l);
result = 31 * result + Boolean.hashCode(b);
result = 31 * result + (int) v;
result = 31 * result + (int) s;
result = 31 * result + i;
result = 31 * result + Float.hashCode(f);
result = 31 * result + Double.hashCode(d);
return result;
}
}
@@ -0,0 +1,3 @@
class Test {
double d;
}
@@ -0,0 +1,9 @@
public class X {
private long l = 1l;
private boolean b = true;
private byte v = 1;
private short s = 1;
private int i = 1;
private float f = 1.0f;
private double d = 1.0;
}
@@ -29,6 +29,11 @@ public class GenerateEqualsTest extends LightJavaCodeInsightTestCase {
doTest(new int[]{0, 1, 2}, new int[0], new int[0], false);
}
public void testPrimitiveFieldsJava8() {
int[] indices = {0, 1, 2, 3, 4, 5, 6};
doTest(indices, indices, new int[0], false);
}
public void testFields() {
doTest(new int[]{0, 1, 2}, new int[0], new int[]{1}, false);
}
@@ -53,6 +58,10 @@ public class GenerateEqualsTest extends LightJavaCodeInsightTestCase {
doTest(new int[]{0}, new int[]{0}, new int[0], false);
}
public void testOneDoubleFieldJava8() {
doTest(new int[]{0}, new int[]{0}, new int[0], false);
}
public void testOneFloatField() {
doTest(new int[]{0}, new int[]{0}, new int[0], false);
}
@@ -86,8 +95,7 @@ public class GenerateEqualsTest extends LightJavaCodeInsightTestCase {
}
public void testDifferentTypes() {
doTest(Functions.id(), Functions.id(), fields -> PsiField.EMPTY_ARRAY, true
);
doTest(Functions.id(), Functions.id(), fields -> PsiField.EMPTY_ARRAY, true);
}
public void testDifferentTypesGetters() {
@@ -205,4 +213,9 @@ public class GenerateEqualsTest extends LightJavaCodeInsightTestCase {
}
return result.toArray(PsiField.EMPTY_ARRAY);
}
@Override
protected LanguageLevel getDefaultLanguageLevel() {
return LanguageLevel.JDK_1_7;
}
}