Simplify constructor interpretation
Unified case with secondary and primary constructors
This commit is contained in:
+6
-13
@@ -427,7 +427,6 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
|
|
||||||
private suspend fun interpretConstructor(constructorCall: IrFunctionAccessExpression): ExecutionResult {
|
private suspend fun interpretConstructor(constructorCall: IrFunctionAccessExpression): ExecutionResult {
|
||||||
val owner = constructorCall.symbol.owner
|
val owner = constructorCall.symbol.owner
|
||||||
val isPrimary = (owner as IrConstructor).isPrimary
|
|
||||||
val valueArguments = mutableListOf<Variable>()
|
val valueArguments = mutableListOf<Variable>()
|
||||||
|
|
||||||
interpretValueParameters(constructorCall, owner, valueArguments).check { return it }
|
interpretValueParameters(constructorCall, owner, valueArguments).check { return it }
|
||||||
@@ -472,23 +471,17 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
return Next
|
return Next
|
||||||
}
|
}
|
||||||
|
|
||||||
val receiverState = Common(parent)
|
val state = Common(parent)
|
||||||
valueArguments.add(Variable(constructorCall.getThisAsReceiver(), receiverState)) //used to set up fields in body
|
valueArguments.add(Variable(constructorCall.getThisAsReceiver(), state)) //used to set up fields in body
|
||||||
return stack.newFrame(initPool = valueArguments) {
|
return stack.newFrame(initPool = valueArguments) {
|
||||||
val statements = constructorCall.getBody()!!.statements
|
val statements = constructorCall.getBody()!!.statements
|
||||||
when (val first = statements[0]) {
|
// enum entry use IrTypeOperatorCall with IMPLICIT_COERCION_TO_UNIT as delegation call, but we need the value
|
||||||
// enum entry use IrTypeOperatorCall with IMPLICIT_COERCION_TO_UNIT as delegation call, but we need the value
|
((statements[0] as? IrTypeOperatorCall)?.argument ?: statements[0]).interpret().check { return@newFrame it }
|
||||||
is IrTypeOperatorCall -> first.argument.interpret().check { return@newFrame it }
|
|
||||||
else -> first.interpret().check { return@newFrame it }
|
|
||||||
}
|
|
||||||
val returnedState = stack.popReturnValue() as Complex
|
val returnedState = stack.popReturnValue() as Complex
|
||||||
|
|
||||||
for (i in 1 until statements.size) statements[i].interpret().check { return@newFrame it }
|
for (i in 1 until statements.size) statements[i].interpret().check { return@newFrame it }
|
||||||
|
|
||||||
val state =
|
stack.pushReturnValue(state.apply { this.setSuperClassInstance(returnedState) })
|
||||||
if (isPrimary) receiverState.apply { this.setSuperClassInstance(returnedState) }
|
|
||||||
else returnedState.apply { setStatesFrom(receiverState) } // if is secondary then only copy all properties from receiver
|
|
||||||
|
|
||||||
stack.pushReturnValue(state)
|
|
||||||
Next
|
Next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-4
@@ -17,8 +17,15 @@ abstract class Complex(
|
|||||||
override val irClass: IrClass, override val fields: MutableList<Variable>, var superClass: Complex?, var subClass: Complex?
|
override val irClass: IrClass, override val fields: MutableList<Variable>, var superClass: Complex?, var subClass: Complex?
|
||||||
) : State {
|
) : State {
|
||||||
fun setSuperClassInstance(superClass: Complex) {
|
fun setSuperClassInstance(superClass: Complex) {
|
||||||
this.superClass = superClass
|
if (this.irClass == superClass.irClass) {
|
||||||
superClass.subClass = this
|
// if superClass is just secondary constructor instance, then copy properties that isn't already present in instance
|
||||||
|
superClass.fields.forEach { if (!this.contains(it)) fields.add(it) }
|
||||||
|
this.superClass = superClass.superClass
|
||||||
|
superClass.superClass?.subClass = this
|
||||||
|
} else {
|
||||||
|
this.superClass = superClass
|
||||||
|
superClass.subClass = this
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getOriginal(): Complex {
|
fun getOriginal(): Complex {
|
||||||
@@ -29,6 +36,8 @@ abstract class Complex(
|
|||||||
return irClass.fqNameForIrSerialization.toString()
|
return irClass.fqNameForIrSerialization.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun contains(variable: Variable) = fields.any { it.descriptor == variable.descriptor }
|
||||||
|
|
||||||
override fun setState(newVar: Variable) {
|
override fun setState(newVar: Variable) {
|
||||||
when (val oldState = fields.firstOrNull { it.descriptor == newVar.descriptor }) {
|
when (val oldState = fields.firstOrNull { it.descriptor == newVar.descriptor }) {
|
||||||
null -> fields.add(newVar) // newVar isn't present in value list
|
null -> fields.add(newVar) // newVar isn't present in value list
|
||||||
@@ -36,8 +45,6 @@ abstract class Complex(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setStatesFrom(state: Complex) = state.fields.forEach { setState(it) }
|
|
||||||
|
|
||||||
override fun getIrFunction(descriptor: FunctionDescriptor): IrFunction? {
|
override fun getIrFunction(descriptor: FunctionDescriptor): IrFunction? {
|
||||||
val propertyGetters = irClass.declarations.filterIsInstance<IrProperty>().mapNotNull { it.getter }
|
val propertyGetters = irClass.declarations.filterIsInstance<IrProperty>().mapNotNull { it.getter }
|
||||||
val functions = irClass.declarations.filterIsInstance<IrFunction>()
|
val functions = irClass.declarations.filterIsInstance<IrFunction>()
|
||||||
|
|||||||
Reference in New Issue
Block a user