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 27cd16d239e..ef8cc18a57a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateEqualsAndHashcodeAction.kt +++ b/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateEqualsAndHashcodeAction.kt @@ -29,7 +29,6 @@ import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.VariableDescriptor -import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde import org.jetbrains.kotlin.idea.core.CollectingNameValidator @@ -47,7 +46,6 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.TargetPlatform import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny -import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.utils.addIfNotNull @@ -70,30 +68,19 @@ class KotlinGenerateEqualsAndHashcodeAction : KotlinGenerateMemberActionBase, - val variablesForHashCode: List + val needEquals: Boolean, + val needHashCode: Boolean, + val classDescriptor: ClassDescriptor, + val variablesForEquals: List, + val variablesForHashCode: List ) override fun isValidForClass(targetClass: KtClassOrObject): Boolean { return targetClass is KtClass - && targetClass !is KtEnumEntry - && !targetClass.isEnum() - && !targetClass.isAnnotation() - && !targetClass.isInterface() - && (!targetClass.isData() || isValidForDataClass(targetClass)) - } - - private fun isValidForDataClass(targetClass: KtClass): Boolean { - val constructor = targetClass.primaryConstructor ?: return false - val context = constructor.analyze(BodyResolveMode.PARTIAL) - return constructor.valueParameters.any { parameter -> - parameter.hasValOrVar() && context.get(BindingContext.TYPE, parameter.typeReference)?.let { type -> - KotlinBuiltIns.isArray(type) || KotlinBuiltIns.isPrimitiveArray(type) - } ?: false - } + && targetClass !is KtEnumEntry + && !targetClass.isEnum() + && !targetClass.isAnnotation() + && !targetClass.isInterface() } override fun prepareMembersInfo(klass: KtClassOrObject, project: Project, editor: Editor?): Info? { @@ -116,7 +103,7 @@ class KotlinGenerateEqualsAndHashcodeAction : KotlinGenerateMemberActionBase { "!${generateArraysEqualsCall(it, canUseArrayContentFunctions, propName, "$paramName.$propName")}" - } else -> { + } + else -> { "$propName != $paramName.$propName" } } @@ -332,10 +320,10 @@ class KotlinGenerateEqualsAndHashcodeAction : KotlinGenerateMemberActionBase { val targetClass = info.classDescriptor.source.getPsi() as KtClass val prototypes = ArrayList(2) - .apply { - addIfNotNull(generateEquals(project, info, targetClass)) - addIfNotNull(generateHashCode(project, info, targetClass)) - } + .apply { + addIfNotNull(generateEquals(project, info, targetClass)) + addIfNotNull(generateHashCode(project, info, targetClass)) + } val anchor = with(targetClass.declarations) { lastIsInstanceOrNull() ?: lastOrNull() } return insertMembersAfter(editor, targetClass, prototypes, anchor) } diff --git a/idea/testData/codeInsight/generate/equalsWithHashCode/dataClass.kt b/idea/testData/codeInsight/generate/equalsWithHashCode/dataClass.kt index 9cc91f7fdc9..87a9b7ade2e 100644 --- a/idea/testData/codeInsight/generate/equalsWithHashCode/dataClass.kt +++ b/idea/testData/codeInsight/generate/equalsWithHashCode/dataClass.kt @@ -1,2 +1 @@ -// NOT_APPLICABLE data class A(val n: Int) \ No newline at end of file diff --git a/idea/testData/codeInsight/generate/equalsWithHashCode/dataClass.kt.after b/idea/testData/codeInsight/generate/equalsWithHashCode/dataClass.kt.after new file mode 100644 index 00000000000..3bc38d4a6b0 --- /dev/null +++ b/idea/testData/codeInsight/generate/equalsWithHashCode/dataClass.kt.after @@ -0,0 +1,16 @@ +data class A(val n: Int) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as A + + if (n != other.n) return false + + return true + } + + override fun hashCode(): Int { + return n + } +} \ No newline at end of file