diff --git a/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateEqualsAndHashcodeAction.kt b/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateEqualsAndHashcodeAction.kt index ef8ef1e2560..084f9ea61b2 100644 --- a/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateEqualsAndHashcodeAction.kt +++ b/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateEqualsAndHashcodeAction.kt @@ -24,6 +24,7 @@ import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project import com.intellij.openapi.ui.Messages import com.intellij.util.IncorrectOperationException +import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor @@ -31,8 +32,8 @@ import org.jetbrains.kotlin.idea.core.CollectingNameValidator import org.jetbrains.kotlin.idea.core.KotlinNameSuggester import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMemberChooserObject import org.jetbrains.kotlin.idea.core.overrideImplement.generateMember -import org.jetbrains.kotlin.idea.refactoring.quoteIfNeeded import org.jetbrains.kotlin.idea.quickfix.insertMembersAfter +import org.jetbrains.kotlin.idea.refactoring.quoteIfNeeded import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.incremental.components.NoLookupLocation @@ -209,7 +210,13 @@ class KotlinGenerateEqualsAndHashcodeAction : KotlinGenerateMemberActionBase + "!java.util.Arrays.equals($propName, $paramName.$propName)" + else -> + "$propName != $paramName.$propName" + } + append("if ($notEquals) return false\n") } append('\n') @@ -230,9 +237,14 @@ class KotlinGenerateEqualsAndHashcodeAction : KotlinGenerateMemberActionBase ref - else -> if (isNullable) "$ref?.hashCode()" else "$ref.hashCode()" + val typeClass = type.constructor.declarationDescriptor + var text = when { + typeClass == builtIns.byte || typeClass == builtIns.short || typeClass == builtIns.int -> + ref + KotlinBuiltIns.isArray(type) || KotlinBuiltIns.isPrimitiveArray(type) -> + if (isNullable) "$ref?.let { java.util.Arrays.hashCode(it) }" else "java.util.Arrays.hashCode($ref)" + else -> + if (isNullable) "$ref?.hashCode()" else "$ref.hashCode()" } if (isNullable) { text += " ?: 0" diff --git a/idea/testData/codeInsight/generate/equalsWithHashCode/arrays.kt b/idea/testData/codeInsight/generate/equalsWithHashCode/arrays.kt new file mode 100644 index 00000000000..6ba5ec87223 --- /dev/null +++ b/idea/testData/codeInsight/generate/equalsWithHashCode/arrays.kt @@ -0,0 +1,7 @@ +class A(val n: IntArray, val s: Array) { + val f: Float = 1.0f + + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/generate/equalsWithHashCode/arrays.kt.after b/idea/testData/codeInsight/generate/equalsWithHashCode/arrays.kt.after new file mode 100644 index 00000000000..cc128145e6d --- /dev/null +++ b/idea/testData/codeInsight/generate/equalsWithHashCode/arrays.kt.after @@ -0,0 +1,29 @@ +import java.util.Arrays + +class A(val n: IntArray, val s: Array) { + val f: Float = 1.0f + + fun foo() { + + } + + override fun equals(other: Any?): Boolean{ + if (this === other) return true + if (other?.javaClass != javaClass) return false + + other as A + + if (!Arrays.equals(n, other.n)) return false + if (!Arrays.equals(s, other.s)) return false + if (f != other.f) return false + + return true + } + + override fun hashCode(): Int{ + var result = Arrays.hashCode(n) + result += 31 * result + Arrays.hashCode(s) + result += 31 * result + f.hashCode() + return result + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/generate/equalsWithHashCode/nullableArrays.kt b/idea/testData/codeInsight/generate/equalsWithHashCode/nullableArrays.kt new file mode 100644 index 00000000000..f986afbc953 --- /dev/null +++ b/idea/testData/codeInsight/generate/equalsWithHashCode/nullableArrays.kt @@ -0,0 +1,7 @@ +class A(val n: IntArray?, val s: Array?) { + val f: Float = 1.0f + + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/generate/equalsWithHashCode/nullableArrays.kt.after b/idea/testData/codeInsight/generate/equalsWithHashCode/nullableArrays.kt.after new file mode 100644 index 00000000000..69c4aa14f20 --- /dev/null +++ b/idea/testData/codeInsight/generate/equalsWithHashCode/nullableArrays.kt.after @@ -0,0 +1,29 @@ +import java.util.Arrays + +class A(val n: IntArray?, val s: Array?) { + val f: Float = 1.0f + + fun foo() { + + } + + override fun equals(other: Any?): Boolean{ + if (this === other) return true + if (other?.javaClass != javaClass) return false + + other as A + + if (!Arrays.equals(n, other.n)) return false + if (!Arrays.equals(s, other.s)) return false + if (f != other.f) return false + + return true + } + + override fun hashCode(): Int{ + var result = n?.let { Arrays.hashCode(it) } ?: 0 + result += 31 * result + (s?.let { Arrays.hashCode(it) } ?: 0) + result += 31 * result + f.hashCode() + return result + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/generate/GenerateHashCodeAndEqualsActionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/generate/GenerateHashCodeAndEqualsActionTestGenerated.java index d703a7a0c04..7bdab1bdd07 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/generate/GenerateHashCodeAndEqualsActionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/generate/GenerateHashCodeAndEqualsActionTestGenerated.java @@ -41,6 +41,12 @@ public class GenerateHashCodeAndEqualsActionTestGenerated extends AbstractGenera doTest(fileName); } + @TestMetadata("arrays.kt") + public void testArrays() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/generate/equalsWithHashCode/arrays.kt"); + doTest(fileName); + } + @TestMetadata("dataClass.kt") public void testDataClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/generate/equalsWithHashCode/dataClass.kt"); @@ -113,6 +119,12 @@ public class GenerateHashCodeAndEqualsActionTestGenerated extends AbstractGenera doTest(fileName); } + @TestMetadata("nullableArrays.kt") + public void testNullableArrays() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/generate/equalsWithHashCode/nullableArrays.kt"); + doTest(fileName); + } + @TestMetadata("object.kt") public void testObject() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/generate/equalsWithHashCode/object.kt");