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.project.Project
|
||||||
import com.intellij.openapi.ui.Messages
|
import com.intellij.openapi.ui.Messages
|
||||||
import com.intellij.util.IncorrectOperationException
|
import com.intellij.util.IncorrectOperationException
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully
|
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
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.KotlinNameSuggester
|
||||||
import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMemberChooserObject
|
import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMemberChooserObject
|
||||||
import org.jetbrains.kotlin.idea.core.overrideImplement.generateMember
|
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.quickfix.insertMembersAfter
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.quoteIfNeeded
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
@@ -209,7 +210,13 @@ class KotlinGenerateEqualsAndHashcodeAction : KotlinGenerateMemberActionBase<Kot
|
|||||||
|
|
||||||
variablesForEquals.forEach {
|
variablesForEquals.forEach {
|
||||||
val propName = it.name.asString()
|
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')
|
append('\n')
|
||||||
@@ -230,9 +237,14 @@ class KotlinGenerateEqualsAndHashcodeAction : KotlinGenerateMemberActionBase<Kot
|
|||||||
|
|
||||||
val builtIns = builtIns
|
val builtIns = builtIns
|
||||||
|
|
||||||
var text = when (type.constructor.declarationDescriptor) {
|
val typeClass = type.constructor.declarationDescriptor
|
||||||
builtIns.byte, builtIns.short, builtIns.int -> ref
|
var text = when {
|
||||||
else -> if (isNullable) "$ref?.hashCode()" else "$ref.hashCode()"
|
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) {
|
if (isNullable) {
|
||||||
text += " ?: 0"
|
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);
|
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")
|
@TestMetadata("dataClass.kt")
|
||||||
public void testDataClass() throws Exception {
|
public void testDataClass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/generate/equalsWithHashCode/dataClass.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/generate/equalsWithHashCode/dataClass.kt");
|
||||||
@@ -113,6 +119,12 @@ public class GenerateHashCodeAndEqualsActionTestGenerated extends AbstractGenera
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("object.kt")
|
||||||
public void testObject() throws Exception {
|
public void testObject() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/generate/equalsWithHashCode/object.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/generate/equalsWithHashCode/object.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user