Generate equals/hashCode Action: Use Arrays.equals/Arrays.hashCode for properties of array types
#KT-10514 Fixed
This commit is contained in:
+17
-5
@@ -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() {
|
||||
|
||||
}
|
||||
}
|
||||
+29
@@ -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
|
||||
}
|
||||
}
|
||||
+12
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user