Implement proper contract for generated java.lang.Annotation.hashCode()
#KT-48606 Fixed
This commit is contained in:
@@ -139,6 +139,7 @@ abstract class IrBuiltIns {
|
||||
|
||||
abstract val intPlusSymbol: IrSimpleFunctionSymbol
|
||||
abstract val intTimesSymbol: IrSimpleFunctionSymbol
|
||||
abstract val intXorSymbol: IrSimpleFunctionSymbol
|
||||
|
||||
abstract val extensionToString: IrSimpleFunctionSymbol
|
||||
abstract val stringPlus: IrSimpleFunctionSymbol
|
||||
|
||||
+6
-4
@@ -32,10 +32,7 @@ import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeBuilder
|
||||
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
import org.jetbrains.kotlin.ir.util.functions
|
||||
import org.jetbrains.kotlin.ir.util.referenceClassifier
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
@@ -387,6 +384,11 @@ class IrBuiltInsOverDescriptors(
|
||||
KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, int)
|
||||
}.let { symbolTable.referenceSimpleFunction(it) }
|
||||
|
||||
override val intXorSymbol: IrSimpleFunctionSymbol =
|
||||
builtIns.int.unsubstitutedMemberScope.findFirstFunction("xor") {
|
||||
KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, int)
|
||||
}.let { symbolTable.referenceSimpleFunction(it) }
|
||||
|
||||
override val intPlusSymbol: IrSimpleFunctionSymbol =
|
||||
builtIns.int.unsubstitutedMemberScope.findFirstFunction("plus") {
|
||||
KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, int)
|
||||
|
||||
@@ -16,7 +16,9 @@ import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.mapTypeParameters
|
||||
import org.jetbrains.kotlin.ir.expressions.mapValueParameters
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
@@ -160,7 +162,7 @@ abstract class DataClassMembersGenerator(
|
||||
+irResultVar
|
||||
|
||||
for (property in properties.drop(1)) {
|
||||
val shiftedResult = irCallOp(context.irBuiltIns.intTimesSymbol, irIntType, irGet(irResultVar), irInt(31))
|
||||
val shiftedResult = shiftResultOfHashCode(irResultVar)
|
||||
val irRhs = irCallOp(context.irBuiltIns.intPlusSymbol, irIntType, shiftedResult, getHashCodeOfProperty(property))
|
||||
+irSet(irResultVar.symbol, irRhs)
|
||||
}
|
||||
@@ -175,30 +177,10 @@ abstract class DataClassMembersGenerator(
|
||||
context.irBuiltIns.intType,
|
||||
irGetProperty(irThis(), property),
|
||||
irInt(0),
|
||||
getHashCodeOf(property, irGetProperty(irThis(), property))
|
||||
getHashCodeOf(this, property, irGetProperty(irThis(), property))
|
||||
)
|
||||
else ->
|
||||
getHashCodeOf(property, irGetProperty(irThis(), property))
|
||||
}
|
||||
}
|
||||
|
||||
private fun getHashCodeOf(property: IrProperty, irValue: IrExpression): IrExpression {
|
||||
val hashCodeFunctionInfo = getHashCodeFunctionInfo(property.backingField!!.type)
|
||||
val hashCodeFunctionSymbol = hashCodeFunctionInfo.symbol
|
||||
|
||||
val hasDispatchReceiver = hashCodeFunctionSymbol.descriptor.dispatchReceiverParameter != null
|
||||
return irCall(
|
||||
hashCodeFunctionSymbol,
|
||||
context.irBuiltIns.intType,
|
||||
valueArgumentsCount = if (hasDispatchReceiver) 0 else 1,
|
||||
typeArgumentsCount = 0
|
||||
).apply {
|
||||
if (hasDispatchReceiver) {
|
||||
dispatchReceiver = irValue
|
||||
} else {
|
||||
putValueArgument(0, irValue)
|
||||
}
|
||||
hashCodeFunctionInfo.commitSubstituted(this)
|
||||
getHashCodeOf(this, property, irGetProperty(irThis(), property))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,6 +212,32 @@ abstract class DataClassMembersGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun IrBuilderWithScope.shiftResultOfHashCode(irResultVar: IrVariable): IrExpression =
|
||||
irCallOp(context.irBuiltIns.intTimesSymbol, context.irBuiltIns.intType, irGet(irResultVar), irInt(31))
|
||||
|
||||
protected open fun getHashCodeOf(builder: IrBuilderWithScope, property: IrProperty, irValue: IrExpression) =
|
||||
builder.getHashCodeOf(property.backingField!!.type, irValue)
|
||||
|
||||
protected fun IrBuilderWithScope.getHashCodeOf(type: IrType, irValue: IrExpression): IrExpression {
|
||||
val hashCodeFunctionInfo = getHashCodeFunctionInfo(type)
|
||||
val hashCodeFunctionSymbol = hashCodeFunctionInfo.symbol
|
||||
val hasDispatchReceiver = hashCodeFunctionSymbol.descriptor.dispatchReceiverParameter != null
|
||||
return irCall(
|
||||
hashCodeFunctionSymbol,
|
||||
context.irBuiltIns.intType,
|
||||
valueArgumentsCount = if (hasDispatchReceiver) 0 else 1,
|
||||
typeArgumentsCount = 0
|
||||
).apply {
|
||||
if (hasDispatchReceiver) {
|
||||
dispatchReceiver = irValue
|
||||
} else {
|
||||
putValueArgument(0, irValue)
|
||||
}
|
||||
hashCodeFunctionInfo.commitSubstituted(this)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun getIrProperty(property: PropertyDescriptor): IrProperty =
|
||||
irPropertiesByDescriptor[property]
|
||||
?: throw AssertionError("Class: ${irClass.descriptor}: unexpected property descriptor: $property")
|
||||
|
||||
Reference in New Issue
Block a user