Refactor DataClassMembersGenerator.kt for better work with LazyIr
^KT-49428
This commit is contained in:
+5
-3
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
|||||||
import org.jetbrains.kotlin.backend.common.ir.addFakeOverrides
|
import org.jetbrains.kotlin.backend.common.ir.addFakeOverrides
|
||||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||||
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.addConstructor
|
import org.jetbrains.kotlin.ir.builders.declarations.addConstructor
|
||||||
@@ -221,16 +222,17 @@ class AnnotationImplementationMemberGenerator(
|
|||||||
override fun IrBuilderWithScope.shiftResultOfHashCode(irResultVar: IrVariable): IrExpression = irGet(irResultVar) // no default (* 31)
|
override fun IrBuilderWithScope.shiftResultOfHashCode(irResultVar: IrVariable): IrExpression = irGet(irResultVar) // no default (* 31)
|
||||||
|
|
||||||
override fun getHashCodeOf(builder: IrBuilderWithScope, property: IrProperty, irValue: IrExpression): IrExpression = with(builder) {
|
override fun getHashCodeOf(builder: IrBuilderWithScope, property: IrProperty, irValue: IrExpression): IrExpression = with(builder) {
|
||||||
val propertyValueHashCode = getHashCodeOf(property.backingField!!.type, irValue)
|
val propertyValueHashCode = getHashCodeOf(property.type, irValue)
|
||||||
val propertyNameHashCode = getHashCodeOf(backendContext.irBuiltIns.stringType, irString(property.name.toString()))
|
val propertyNameHashCode = getHashCodeOf(backendContext.irBuiltIns.stringType, irString(property.name.toString()))
|
||||||
val multiplied = irCallOp(context.irBuiltIns.intTimesSymbol, context.irBuiltIns.intType, propertyNameHashCode, irInt(127))
|
val multiplied = irCallOp(context.irBuiltIns.intTimesSymbol, context.irBuiltIns.intType, propertyNameHashCode, irInt(127))
|
||||||
return irCallOp(context.irBuiltIns.intXorSymbol, context.irBuiltIns.intType, multiplied, propertyValueHashCode)
|
return irCallOp(context.irBuiltIns.intXorSymbol, context.irBuiltIns.intType, multiplied, propertyValueHashCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manual implementation of equals is required for two reasons:
|
// Manual implementation of equals is required for following reasons:
|
||||||
// 1. `other` should be casted to interface instead of implementation
|
// 1. `other` should be casted to interface instead of implementation
|
||||||
// 2. Properties should be retrieved using getters without accessing backing fields
|
// 2. Properties should be retrieved using getters without accessing backing fields
|
||||||
// (DataClassMembersGenerator typically tries to access fields)
|
// (DataClassMembersGenerator typically tries to access fields)
|
||||||
|
// 3. Custom equals function should be used on properties
|
||||||
fun generateEqualsUsingGetters(equalsFun: IrSimpleFunction, typeForEquals: IrType, properties: List<IrProperty>) = equalsFun.apply {
|
fun generateEqualsUsingGetters(equalsFun: IrSimpleFunction, typeForEquals: IrType, properties: List<IrProperty>) = equalsFun.apply {
|
||||||
body = backendContext.createIrBuilder(symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody {
|
body = backendContext.createIrBuilder(symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody {
|
||||||
val irType = typeForEquals
|
val irType = typeForEquals
|
||||||
@@ -245,7 +247,7 @@ class AnnotationImplementationMemberGenerator(
|
|||||||
for (property in properties) {
|
for (property in properties) {
|
||||||
val arg1 = property.get(irThis())
|
val arg1 = property.get(irThis())
|
||||||
val arg2 = property.get(irGet(irType, otherWithCast.symbol))
|
val arg2 = property.get(irGet(irType, otherWithCast.symbol))
|
||||||
+irIfThenReturnFalse(irNot(selectEquals(property.getter?.returnType ?: property.backingField!!.type, arg1, arg2)))
|
+irIfThenReturnFalse(irNot(selectEquals(property.type, arg1, arg2)))
|
||||||
}
|
}
|
||||||
+irReturnTrue()
|
+irReturnTrue()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ abstract class DataClassMembersGenerator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected val IrProperty.type
|
||||||
|
get() = this.backingField?.type ?: this.getter?.returnType ?: error("Can't find type of ${this.render()}")
|
||||||
|
|
||||||
private inner class MemberFunctionBuilder(
|
private inner class MemberFunctionBuilder(
|
||||||
startOffset: Int = SYNTHETIC_OFFSET,
|
startOffset: Int = SYNTHETIC_OFFSET,
|
||||||
endOffset: Int = SYNTHETIC_OFFSET,
|
endOffset: Int = SYNTHETIC_OFFSET,
|
||||||
@@ -172,7 +175,7 @@ abstract class DataClassMembersGenerator(
|
|||||||
|
|
||||||
private fun getHashCodeOfProperty(property: IrProperty): IrExpression {
|
private fun getHashCodeOfProperty(property: IrProperty): IrExpression {
|
||||||
return when {
|
return when {
|
||||||
property.backingField!!.type.isNullable() ->
|
property.type.isNullable() ->
|
||||||
irIfNull(
|
irIfNull(
|
||||||
context.irBuiltIns.intType,
|
context.irBuiltIns.intType,
|
||||||
irGetProperty(irThis(), property),
|
irGetProperty(irThis(), property),
|
||||||
@@ -195,7 +198,7 @@ abstract class DataClassMembersGenerator(
|
|||||||
|
|
||||||
val irPropertyValue = irGetProperty(irThis(), property)
|
val irPropertyValue = irGetProperty(irThis(), property)
|
||||||
|
|
||||||
val classifier = property.backingField!!.type.classifierOrNull
|
val classifier = property.type.classifierOrNull
|
||||||
val irPropertyStringValue =
|
val irPropertyStringValue =
|
||||||
if (classifier.isArrayOrPrimitiveArray)
|
if (classifier.isArrayOrPrimitiveArray)
|
||||||
irCall(context.irBuiltIns.dataClassArrayMemberToStringSymbol, context.irBuiltIns.stringType).apply {
|
irCall(context.irBuiltIns.dataClassArrayMemberToStringSymbol, context.irBuiltIns.stringType).apply {
|
||||||
@@ -216,7 +219,7 @@ abstract class DataClassMembersGenerator(
|
|||||||
irCallOp(context.irBuiltIns.intTimesSymbol, context.irBuiltIns.intType, irGet(irResultVar), irInt(31))
|
irCallOp(context.irBuiltIns.intTimesSymbol, context.irBuiltIns.intType, irGet(irResultVar), irInt(31))
|
||||||
|
|
||||||
protected open fun getHashCodeOf(builder: IrBuilderWithScope, property: IrProperty, irValue: IrExpression) =
|
protected open fun getHashCodeOf(builder: IrBuilderWithScope, property: IrProperty, irValue: IrExpression) =
|
||||||
builder.getHashCodeOf(property.backingField!!.type, irValue)
|
builder.getHashCodeOf(property.type, irValue)
|
||||||
|
|
||||||
protected fun IrBuilderWithScope.getHashCodeOf(type: IrType, irValue: IrExpression): IrExpression {
|
protected fun IrBuilderWithScope.getHashCodeOf(type: IrType, irValue: IrExpression): IrExpression {
|
||||||
val hashCodeFunctionInfo = getHashCodeFunctionInfo(type)
|
val hashCodeFunctionInfo = getHashCodeFunctionInfo(type)
|
||||||
@@ -242,9 +245,6 @@ abstract class DataClassMembersGenerator(
|
|||||||
irPropertiesByDescriptor[property]
|
irPropertiesByDescriptor[property]
|
||||||
?: throw AssertionError("Class: ${irClass.descriptor}: unexpected property descriptor: $property")
|
?: throw AssertionError("Class: ${irClass.descriptor}: unexpected property descriptor: $property")
|
||||||
|
|
||||||
fun getBackingField(property: PropertyDescriptor): IrField =
|
|
||||||
getIrProperty(property).backingField!!
|
|
||||||
|
|
||||||
val IrClassifierSymbol?.isArrayOrPrimitiveArray: Boolean
|
val IrClassifierSymbol?.isArrayOrPrimitiveArray: Boolean
|
||||||
get() = this == context.irBuiltIns.arrayClass || this in context.irBuiltIns.primitiveArraysToPrimitiveTypes
|
get() = this == context.irBuiltIns.arrayClass || this in context.irBuiltIns.primitiveArraysToPrimitiveTypes
|
||||||
|
|
||||||
|
|||||||
+2
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.konan.lower
|
|||||||
import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
|
import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
|
||||||
import org.jetbrains.kotlin.backend.common.lower.AnnotationImplementationTransformer
|
import org.jetbrains.kotlin.backend.common.lower.AnnotationImplementationTransformer
|
||||||
import org.jetbrains.kotlin.backend.konan.*
|
import org.jetbrains.kotlin.backend.konan.*
|
||||||
|
import org.jetbrains.kotlin.backend.konan.ir.isFinalClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
@@ -35,6 +36,7 @@ internal class NativeAnnotationImplementationTransformer(context: Context, irFil
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun implementAnnotationPropertiesAndConstructor(implClass: IrClass, annotationClass: IrClass, generatedConstructor: IrConstructor) {
|
override fun implementAnnotationPropertiesAndConstructor(implClass: IrClass, annotationClass: IrClass, generatedConstructor: IrConstructor) {
|
||||||
|
require(!annotationClass.isFinalClass) { "Annotation class ${annotationClass.kotlinFqName} shouldn't be final" }
|
||||||
val properties = annotationClass.getAnnotationProperties()
|
val properties = annotationClass.getAnnotationProperties()
|
||||||
properties.forEach { property ->
|
properties.forEach { property ->
|
||||||
val propType = property.getter!!.returnType
|
val propType = property.getter!!.returnType
|
||||||
|
|||||||
Reference in New Issue
Block a user