Fix IR generation: temporary variable in 'hashCode()' for data class should be 'var'
This commit is contained in:
@@ -48,6 +48,12 @@ fun <T : IrElement> IrStatementsBuilder<T>.defineTemporary(value: IrExpression,
|
|||||||
return temporary.descriptor
|
return temporary.descriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T : IrElement> IrStatementsBuilder<T>.defineTemporaryVar(value: IrExpression, nameHint: String? = null): VariableDescriptor {
|
||||||
|
val temporary = scope.createTemporaryVariable(value, nameHint, isMutable = true)
|
||||||
|
+temporary
|
||||||
|
return temporary.descriptor
|
||||||
|
}
|
||||||
|
|
||||||
fun IrBuilderWithScope.irReturn(value: IrExpression) =
|
fun IrBuilderWithScope.irReturn(value: IrExpression) =
|
||||||
IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, scope.assertCastOwner(), value)
|
IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, scope.assertCastOwner(), value)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -103,7 +103,7 @@ class DataClassMembersGenerator(
|
|||||||
|
|
||||||
override fun generateHashCodeMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
override fun generateHashCodeMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
||||||
buildMember(function) {
|
buildMember(function) {
|
||||||
val result = defineTemporary(irInt(0), "result")
|
val result = defineTemporaryVar(irInt(0), "result")
|
||||||
var first = true
|
var first = true
|
||||||
for (property in properties) {
|
for (property in properties) {
|
||||||
val hashCodeOfProperty = getHashCodeOfProperty(irThis(), property)
|
val hashCodeOfProperty = getHashCodeOfProperty(irThis(), property)
|
||||||
|
|||||||
@@ -30,18 +30,18 @@ class Scope(val scopeOwner: DeclarationDescriptor) {
|
|||||||
private var lastTemporaryIndex: Int = 0
|
private var lastTemporaryIndex: Int = 0
|
||||||
private fun nextTemporaryIndex(): Int = lastTemporaryIndex++
|
private fun nextTemporaryIndex(): Int = lastTemporaryIndex++
|
||||||
|
|
||||||
private fun createDescriptorForTemporaryVariable(type: KotlinType, nameHint: String? = null): IrTemporaryVariableDescriptor =
|
private fun createDescriptorForTemporaryVariable(type: KotlinType, nameHint: String? = null, isMutable: Boolean = false): IrTemporaryVariableDescriptor =
|
||||||
IrTemporaryVariableDescriptorImpl(scopeOwner, Name.identifier(getNameForTemporary(nameHint)), type)
|
IrTemporaryVariableDescriptorImpl(scopeOwner, Name.identifier(getNameForTemporary(nameHint)), type, isMutable)
|
||||||
|
|
||||||
private fun getNameForTemporary(nameHint: String?): String {
|
private fun getNameForTemporary(nameHint: String?): String {
|
||||||
val index = nextTemporaryIndex()
|
val index = nextTemporaryIndex()
|
||||||
return if (nameHint != null) "tmp${index}_$nameHint" else "tmp$index"
|
return if (nameHint != null) "tmp${index}_$nameHint" else "tmp$index"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createTemporaryVariable(irExpression: IrExpression, nameHint: String? = null): IrVariable =
|
fun createTemporaryVariable(irExpression: IrExpression, nameHint: String? = null, isMutable: Boolean = false): IrVariable =
|
||||||
IrVariableImpl(
|
IrVariableImpl(
|
||||||
irExpression.startOffset, irExpression.endOffset, IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
|
irExpression.startOffset, irExpression.endOffset, IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
|
||||||
createDescriptorForTemporaryVariable(irExpression.type, nameHint),
|
createDescriptorForTemporaryVariable(irExpression.type, nameHint, isMutable),
|
||||||
irExpression
|
irExpression
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -29,7 +29,8 @@ interface IrTemporaryVariableDescriptor : VariableDescriptor
|
|||||||
class IrTemporaryVariableDescriptorImpl(
|
class IrTemporaryVariableDescriptorImpl(
|
||||||
containingDeclaration: DeclarationDescriptor,
|
containingDeclaration: DeclarationDescriptor,
|
||||||
name: Name,
|
name: Name,
|
||||||
outType: KotlinType
|
outType: KotlinType,
|
||||||
|
private val isMutable: Boolean = false
|
||||||
): VariableDescriptorImpl(containingDeclaration, Annotations.EMPTY, name, outType, SourceElement.NO_SOURCE),
|
): VariableDescriptorImpl(containingDeclaration, Annotations.EMPTY, name, outType, SourceElement.NO_SOURCE),
|
||||||
IrTemporaryVariableDescriptor
|
IrTemporaryVariableDescriptor
|
||||||
{
|
{
|
||||||
@@ -41,7 +42,7 @@ class IrTemporaryVariableDescriptorImpl(
|
|||||||
throw UnsupportedOperationException("Temporary variable descriptor shouldn't be substituted (so far): $this")
|
throw UnsupportedOperationException("Temporary variable descriptor shouldn't be substituted (so far): $this")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isVar(): Boolean = false
|
override fun isVar(): Boolean = isMutable
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R =
|
override fun <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R =
|
||||||
visitor.visitVariableDescriptor(this, data)
|
visitor.visitVariableDescriptor(this, data)
|
||||||
|
|||||||
+1
-1
@@ -72,7 +72,7 @@ FILE /dataClasses.kt
|
|||||||
CONST String type=kotlin.String value=')'
|
CONST String type=kotlin.String value=')'
|
||||||
FUN GENERATED_DATA_CLASS_MEMBER public open override fun hashCode(): kotlin.Int
|
FUN GENERATED_DATA_CLASS_MEMBER public open override fun hashCode(): kotlin.Int
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
VAR IR_TEMPORARY_VARIABLE val tmp0_result: kotlin.Int
|
VAR IR_TEMPORARY_VARIABLE var tmp0_result: kotlin.Int
|
||||||
CONST Int type=kotlin.Int value='0'
|
CONST Int type=kotlin.Int value='0'
|
||||||
SET_VAR 'tmp0_result: Int' type=kotlin.Unit origin=EQ
|
SET_VAR 'tmp0_result: Int' type=kotlin.Unit origin=EQ
|
||||||
CALL 'hashCode(): Int' type=kotlin.Int origin=null
|
CALL 'hashCode(): Int' type=kotlin.Int origin=null
|
||||||
|
|||||||
Reference in New Issue
Block a user