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
|
* 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.
|
* changed here with the platform backends adopted.
|
||||||
*/
|
*/
|
||||||
abstract class DataClassMethodGenerator(protected val declaration: KtClassOrObject, private val bindingContext: BindingContext) {
|
abstract class DataClassMethodGenerator(
|
||||||
protected val classDescriptor: ClassDescriptor = BindingContextUtils.getNotNull(bindingContext, BindingContext.CLASS, declaration)
|
declaration: KtClassOrObject,
|
||||||
|
bindingContext: BindingContext
|
||||||
|
) : FunctionsFromAnyGenerator(declaration, bindingContext) {
|
||||||
|
|
||||||
fun generate() {
|
override fun generate() {
|
||||||
generateComponentFunctionsForDataClasses()
|
generateComponentFunctionsForDataClasses()
|
||||||
|
|
||||||
generateCopyFunctionForDataClasses(primaryConstructorParameters)
|
generateCopyFunctionForDataClasses(primaryConstructorParameters)
|
||||||
|
|
||||||
val properties = dataProperties
|
super.generate()
|
||||||
if (properties.isNotEmpty()) {
|
|
||||||
generateDataClassToStringIfNeeded(properties)
|
|
||||||
generateDataClassHashCodeIfNeeded(properties)
|
|
||||||
generateDataClassEqualsIfNeeded(properties)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun generateComponentFunction(function: FunctionDescriptor, parameter: ValueParameterDescriptor)
|
protected abstract fun generateComponentFunction(function: FunctionDescriptor, parameter: ValueParameterDescriptor)
|
||||||
|
|
||||||
protected abstract fun generateCopyFunction(function: FunctionDescriptor, constructorParameters: List<KtParameter>)
|
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() {
|
private fun generateComponentFunctionsForDataClasses() {
|
||||||
// primary constructor should exist for data classes
|
// primary constructor should exist for data classes
|
||||||
// but when generating light-classes still need to check we have one
|
// 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
|
val copyFunction = bindingContext.get(BindingContext.DATA_CLASS_COPY_FUNCTION, classDescriptor) ?: return
|
||||||
generateCopyFunction(copyFunction, constructorParameters)
|
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