Interpret properties and init blocks in order of appearance

This commit is contained in:
Ivan Kylchik
2021-06-10 22:53:16 +03:00
committed by TeamCityServer
parent 78475a5d9c
commit 8972fc5158
2 changed files with 12 additions and 10 deletions
@@ -194,15 +194,14 @@ private fun unfoldValueParameters(expression: IrFunctionAccessExpression, callSt
private fun unfoldInstanceInitializerCall(instanceInitializerCall: IrInstanceInitializerCall, callStack: CallStack) { private fun unfoldInstanceInitializerCall(instanceInitializerCall: IrInstanceInitializerCall, callStack: CallStack) {
val irClass = instanceInitializerCall.classSymbol.owner val irClass = instanceInitializerCall.classSymbol.owner
val toInitialize = irClass.declarations.filter { it is IrProperty || (it is IrAnonymousInitializer && !it.isStatic) }
// init blocks processing toInitialize.reversed().forEach {
val anonymousInitializer = irClass.declarations.filterIsInstance<IrAnonymousInitializer>().filter { !it.isStatic } when {
anonymousInitializer.reversed().forEach { callStack.addInstruction(CompoundInstruction(it.body)) } it is IrAnonymousInitializer -> callStack.addInstruction(CompoundInstruction(it.body))
it is IrProperty && it.backingField?.initializer?.expression != null -> callStack.addInstruction(CompoundInstruction(it.backingField))
// properties processing }
val classProperties = irClass.declarations.filterIsInstance<IrProperty>() }
classProperties.filter { it.backingField?.initializer?.expression != null }.reversed()
.forEach { callStack.addInstruction(CompoundInstruction(it.backingField)) }
} }
private fun unfoldField(field: IrField, callStack: CallStack) { private fun unfoldField(field: IrField, callStack: CallStack) {
@@ -424,14 +424,17 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
valueArguments.forEachIndexed { index, irConst -> enumSuperCall.putValueArgument(index, irConst) } valueArguments.forEachIndexed { index, irConst -> enumSuperCall.putValueArgument(index, irConst) }
} }
val enumConstructorCall = enumEntry.initializerExpression?.expression as? IrEnumConstructorCall val enumInitializer = enumEntry.initializerExpression?.expression
?: throw InterpreterError("Initializer at enum entry ${enumEntry.fqNameWhenAvailable} is null") ?: throw InterpreterError("Initializer at enum entry ${enumEntry.fqNameWhenAvailable} is null")
val enumConstructorCall = enumInitializer as? IrEnumConstructorCall
?: (enumInitializer as IrBlock).statements.filterIsInstance<IrEnumConstructorCall>().single()
val enumClassObject = Variable(enumConstructorCall.getThisReceiver(), Common(enumEntry.correspondingClass ?: enumClass)) val enumClassObject = Variable(enumConstructorCall.getThisReceiver(), Common(enumEntry.correspondingClass ?: enumClass))
environment.mapOfEnums[enumEntry.symbol] = enumClassObject.state as Complex environment.mapOfEnums[enumEntry.symbol] = enumClassObject.state as Complex
callStack.newSubFrame(enumEntry) callStack.newSubFrame(enumEntry)
callStack.addInstruction(CustomInstruction(cleanEnumSuperCall)) callStack.addInstruction(CustomInstruction(cleanEnumSuperCall))
callStack.addInstruction(CompoundInstruction(enumConstructorCall)) callStack.addInstruction(CompoundInstruction(enumInitializer))
callStack.addVariable(enumClassObject) callStack.addVariable(enumClassObject)
} }
} }