Refactoring: extract generator for functions from Any
This commit is contained in:
+6
-50
@@ -33,32 +33,22 @@ import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||
* TODO: data class with zero components gets no toString/equals/hashCode methods. This is inconsistent and should be
|
||||
* changed here with the platform backends adopted.
|
||||
*/
|
||||
abstract class DataClassMethodGenerator(protected val declaration: KtClassOrObject, private val bindingContext: BindingContext) {
|
||||
protected val classDescriptor: ClassDescriptor = BindingContextUtils.getNotNull(bindingContext, BindingContext.CLASS, declaration)
|
||||
abstract class DataClassMethodGenerator(
|
||||
declaration: KtClassOrObject,
|
||||
bindingContext: BindingContext
|
||||
) : FunctionsFromAnyGenerator(declaration, bindingContext) {
|
||||
|
||||
fun generate() {
|
||||
override fun generate() {
|
||||
generateComponentFunctionsForDataClasses()
|
||||
|
||||
generateCopyFunctionForDataClasses(primaryConstructorParameters)
|
||||
|
||||
val properties = dataProperties
|
||||
if (properties.isNotEmpty()) {
|
||||
generateDataClassToStringIfNeeded(properties)
|
||||
generateDataClassHashCodeIfNeeded(properties)
|
||||
generateDataClassEqualsIfNeeded(properties)
|
||||
}
|
||||
super.generate()
|
||||
}
|
||||
|
||||
protected abstract fun generateComponentFunction(function: FunctionDescriptor, parameter: ValueParameterDescriptor)
|
||||
|
||||
protected abstract fun generateCopyFunction(function: FunctionDescriptor, constructorParameters: List<KtParameter>)
|
||||
|
||||
protected abstract fun generateToStringMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>)
|
||||
|
||||
protected abstract fun generateHashCodeMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>)
|
||||
|
||||
protected abstract fun generateEqualsMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>)
|
||||
|
||||
private fun generateComponentFunctionsForDataClasses() {
|
||||
// primary constructor should exist for data classes
|
||||
// but when generating light-classes still need to check we have one
|
||||
@@ -76,38 +66,4 @@ abstract class DataClassMethodGenerator(protected val declaration: KtClassOrObje
|
||||
val copyFunction = bindingContext.get(BindingContext.DATA_CLASS_COPY_FUNCTION, classDescriptor) ?: return
|
||||
generateCopyFunction(copyFunction, constructorParameters)
|
||||
}
|
||||
|
||||
private fun generateDataClassToStringIfNeeded(properties: List<PropertyDescriptor>) {
|
||||
val function = getMemberToGenerate(
|
||||
classDescriptor, "toString",
|
||||
KotlinBuiltIns::isString, List<ValueParameterDescriptor>::isEmpty
|
||||
) ?: return
|
||||
generateToStringMethod(function, properties)
|
||||
}
|
||||
|
||||
private fun generateDataClassHashCodeIfNeeded(properties: List<PropertyDescriptor>) {
|
||||
val function = getMemberToGenerate(
|
||||
classDescriptor, "hashCode",
|
||||
KotlinBuiltIns::isInt, List<ValueParameterDescriptor>::isEmpty
|
||||
) ?: return
|
||||
generateHashCodeMethod(function, properties)
|
||||
}
|
||||
|
||||
private fun generateDataClassEqualsIfNeeded(properties: List<PropertyDescriptor>) {
|
||||
val function = getMemberToGenerate(
|
||||
classDescriptor, "equals",
|
||||
KotlinBuiltIns::isBoolean
|
||||
) { parameters ->
|
||||
parameters.size == 1 && KotlinBuiltIns.isNullableAny(parameters.first().type)
|
||||
} ?: return
|
||||
generateEqualsMethod(function, properties)
|
||||
}
|
||||
|
||||
private val dataProperties: List<PropertyDescriptor>
|
||||
get() = primaryConstructorParameters
|
||||
.filter { it.hasValOrVar() }
|
||||
.map { bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, it)!! }
|
||||
|
||||
private val primaryConstructorParameters: List<KtParameter>
|
||||
get() = (declaration as? KtClass)?.primaryConstructorParameters.orEmpty()
|
||||
}
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.common
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||
|
||||
abstract class FunctionsFromAnyGenerator(protected val declaration: KtClassOrObject, protected val bindingContext: BindingContext) {
|
||||
protected val classDescriptor: ClassDescriptor = BindingContextUtils.getNotNull(bindingContext, BindingContext.CLASS, declaration)
|
||||
|
||||
open fun generate() {
|
||||
val properties = primaryConstructorProperties
|
||||
if (properties.isNotEmpty()) {
|
||||
generateToStringIfNeeded(properties)
|
||||
generateHashCodeIfNeeded(properties)
|
||||
generateEqualsIfNeeded(properties)
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun generateToStringMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>)
|
||||
|
||||
protected abstract fun generateHashCodeMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>)
|
||||
|
||||
protected abstract fun generateEqualsMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>)
|
||||
|
||||
private fun generateToStringIfNeeded(properties: List<PropertyDescriptor>) {
|
||||
val function = CodegenUtil.getMemberToGenerate(
|
||||
classDescriptor, "toString",
|
||||
KotlinBuiltIns::isString, List<ValueParameterDescriptor>::isEmpty
|
||||
) ?: return
|
||||
generateToStringMethod(function, properties)
|
||||
}
|
||||
|
||||
private fun generateHashCodeIfNeeded(properties: List<PropertyDescriptor>) {
|
||||
val function = CodegenUtil.getMemberToGenerate(
|
||||
classDescriptor, "hashCode",
|
||||
KotlinBuiltIns::isInt, List<ValueParameterDescriptor>::isEmpty
|
||||
) ?: return
|
||||
generateHashCodeMethod(function, properties)
|
||||
}
|
||||
|
||||
private fun generateEqualsIfNeeded(properties: List<PropertyDescriptor>) {
|
||||
val function = CodegenUtil.getMemberToGenerate(
|
||||
classDescriptor, "equals",
|
||||
KotlinBuiltIns::isBoolean
|
||||
) { parameters ->
|
||||
parameters.size == 1 && KotlinBuiltIns.isNullableAny(parameters.first().type)
|
||||
} ?: return
|
||||
generateEqualsMethod(function, properties)
|
||||
}
|
||||
|
||||
private val primaryConstructorProperties: List<PropertyDescriptor>
|
||||
get() = primaryConstructorParameters
|
||||
.filter { it.hasValOrVar() }
|
||||
.map { bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, it)!! }
|
||||
|
||||
protected val primaryConstructorParameters: List<KtParameter>
|
||||
get() = (declaration as? KtClass)?.primaryConstructorParameters.orEmpty()
|
||||
}
|
||||
Reference in New Issue
Block a user