Generate equals/hashCode Action: Use Arrays.equals/Arrays.hashCode for properties of array types

#KT-10514 Fixed
This commit is contained in:
Alexey Sedunov
2016-01-11 15:09:58 +03:00
parent 7b67eed3dd
commit 5a108c5cde
6 changed files with 101 additions and 5 deletions
@@ -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<Kot
variablesForEquals.forEach {
val propName = it.name.asString()
append("if ($propName != $paramName.$propName) return false\n")
val notEquals = when {
KotlinBuiltIns.isArray(it.type) || KotlinBuiltIns.isPrimitiveArray(it.type) ->
"!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<Kot
val builtIns = builtIns
var text = when (type.constructor.declarationDescriptor) {
builtIns.byte, builtIns.short, builtIns.int -> 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"
@@ -0,0 +1,7 @@
class A(val n: IntArray, val s: Array<String>) {<caret>
val f: Float = 1.0f
fun foo() {
}
}
@@ -0,0 +1,29 @@
import java.util.Arrays
class A(val n: IntArray, val s: Array<String>) {
val f: Float = 1.0f
fun foo() {
}
<caret>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
}
}
@@ -0,0 +1,7 @@
class A(val n: IntArray?, val s: Array<String>?) {<caret>
val f: Float = 1.0f
fun foo() {
}
}
@@ -0,0 +1,29 @@
import java.util.Arrays
class A(val n: IntArray?, val s: Array<String>?) {
val f: Float = 1.0f
fun foo() {
}
<caret>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
}
}
@@ -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");