Rethink main goal of stack frame
This commit is contained in:
+54
-67
@@ -9,9 +9,10 @@ import org.jetbrains.kotlin.backend.common.interpreter.builtins.CompileTimeFunct
|
|||||||
import org.jetbrains.kotlin.backend.common.interpreter.builtins.binaryFunctions
|
import org.jetbrains.kotlin.backend.common.interpreter.builtins.binaryFunctions
|
||||||
import org.jetbrains.kotlin.backend.common.interpreter.builtins.unaryFunctions
|
import org.jetbrains.kotlin.backend.common.interpreter.builtins.unaryFunctions
|
||||||
import org.jetbrains.kotlin.backend.common.interpreter.stack.*
|
import org.jetbrains.kotlin.backend.common.interpreter.stack.*
|
||||||
|
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||||
@@ -19,7 +20,6 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
|||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.util.isFakeOverride
|
import org.jetbrains.kotlin.ir.util.isFakeOverride
|
||||||
import org.jetbrains.kotlin.ir.util.statements
|
import org.jetbrains.kotlin.ir.util.statements
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
@@ -27,7 +27,9 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
|||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
|
|
||||||
class IrInterpreter : IrElementVisitor<State, Frame> {
|
class IrInterpreter : IrElementVisitor<State, Frame> {
|
||||||
private val unit = Complex(null, emptyList())
|
private val builtIns = DefaultBuiltIns.Instance
|
||||||
|
private val unit = Complex(builtIns.unit, mutableListOf())
|
||||||
|
private val any = Complex(builtIns.any, mutableListOf())
|
||||||
|
|
||||||
fun interpret(expression: IrExpression): IrExpression {
|
fun interpret(expression: IrExpression): IrExpression {
|
||||||
return visitExpression(expression, InterpreterFrame()).toIrExpression()
|
return visitExpression(expression, InterpreterFrame()).toIrExpression()
|
||||||
@@ -39,7 +41,7 @@ class IrInterpreter : IrElementVisitor<State, Frame> {
|
|||||||
else -> TODO("not supported")
|
else -> TODO("not supported")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//todo move out util methods
|
||||||
private fun IrElement?.getState(descriptor: DeclarationDescriptor, data: Frame): State? {
|
private fun IrElement?.getState(descriptor: DeclarationDescriptor, data: Frame): State? {
|
||||||
val arg = this?.accept(this@IrInterpreter, data) ?: return null
|
val arg = this?.accept(this@IrInterpreter, data) ?: return null
|
||||||
return arg.setDescriptor(descriptor)
|
return arg.setDescriptor(descriptor)
|
||||||
@@ -48,28 +50,26 @@ class IrInterpreter : IrElementVisitor<State, Frame> {
|
|||||||
private fun IrMemberAccessExpression.convertValueParameters(data: Frame): MutableList<State> {
|
private fun IrMemberAccessExpression.convertValueParameters(data: Frame): MutableList<State> {
|
||||||
val state = mutableListOf<State>()
|
val state = mutableListOf<State>()
|
||||||
for (i in 0 until this.valueArgumentsCount) {
|
for (i in 0 until this.valueArgumentsCount) {
|
||||||
this.getValueArgument(i).getState(this.symbol.descriptor.valueParameters[i], data)?.let { state += it }
|
this.getValueArgument(i).getState((this.symbol.descriptor as FunctionDescriptor).valueParameters[i], data)?.let { state += it }
|
||||||
}
|
}
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrFunctionSymbol.caclOverridden(states: List<State>): State {
|
private fun calculateOverridden(symbol: IrFunctionSymbol, data: Frame): State {
|
||||||
val owner = this.owner as IrFunctionImpl
|
val owner = symbol.owner as IrFunctionImpl
|
||||||
val overridden = owner.overriddenSymbols.first()
|
val overridden = owner.overriddenSymbols.first()
|
||||||
val newStates = states.first { it.getDescriptor() == this.descriptor.containingDeclaration }.getState().toMutableList()
|
val overriddenReceiver = data.getVar(symbol.getThisAsReceiver()).getState(overridden.getThisAsReceiver())
|
||||||
|
val valueParameters = symbol.owner.valueParameters.zip(overridden.owner.valueParameters)
|
||||||
|
.map { data.getVar(it.first.descriptor).setDescriptor(it.second.descriptor) }
|
||||||
|
val newStates = InterpreterFrame((valueParameters + overriddenReceiver).toMutableList())
|
||||||
|
|
||||||
return if (overridden.owner.body != null) {
|
return if (overridden.owner.body != null) {
|
||||||
val temp = newStates.first { it.getDescriptor() == overridden.descriptor.containingDeclaration }
|
overridden.owner.body!!.accept(this@IrInterpreter, newStates)
|
||||||
overridden.owner.body!!.accept(this@IrInterpreter, InterpreterFrame(mutableListOf(temp)))
|
|
||||||
} else {
|
} else {
|
||||||
overridden.caclOverridden(newStates)
|
calculateOverridden(overridden.owner.symbol, newStates)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrFunctionAccessExpression.getBody(): IrBody? {
|
|
||||||
return this.symbol.owner.body
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun calculateBuiltIns(descriptor: FunctionDescriptor, frame: Frame): Any {
|
private fun calculateBuiltIns(descriptor: FunctionDescriptor, frame: Frame): Any {
|
||||||
val methodName = descriptor.name.asString()
|
val methodName = descriptor.name.asString()
|
||||||
val receiverType = descriptor.dispatchReceiverParameter?.type ?: descriptor.extensionReceiverParameter?.type
|
val receiverType = descriptor.dispatchReceiverParameter?.type ?: descriptor.extensionReceiverParameter?.type
|
||||||
@@ -87,31 +87,12 @@ class IrInterpreter : IrElementVisitor<State, Frame> {
|
|||||||
2 -> {
|
2 -> {
|
||||||
val function = binaryFunctions[signature]
|
val function = binaryFunctions[signature]
|
||||||
?: throw NoSuchMethodException("For given function $signature there is no entry in binary map")
|
?: throw NoSuchMethodException("For given function $signature there is no entry in binary map")
|
||||||
function.invoke(argsValues[0], argsValues[1])
|
function.invoke(argsValues[1], argsValues[0])
|
||||||
}
|
}
|
||||||
else -> throw UnsupportedOperationException("Unsupported number of arguments")
|
else -> throw UnsupportedOperationException("Unsupported number of arguments")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Any.toIrConst(expression: IrExpression): IrConst<*> {
|
|
||||||
return when (this) {
|
|
||||||
is Boolean -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Boolean, this)
|
|
||||||
is Char -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Char, this)
|
|
||||||
is Byte -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Byte, this)
|
|
||||||
is Short -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Short, this)
|
|
||||||
is Int -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Int, this)
|
|
||||||
is Long -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Long, this)
|
|
||||||
is String -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.String, this)
|
|
||||||
is Float -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Float, this)
|
|
||||||
is Double -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Double, this)
|
|
||||||
else -> throw UnsupportedOperationException("Unsupported const element type $this")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun <T> IrConst<T>.toPrimitive(): Primitive<T> {
|
|
||||||
return Primitive(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitElement(element: IrElement, data: Frame): State {
|
override fun visitElement(element: IrElement, data: Frame): State {
|
||||||
return when (element) {
|
return when (element) {
|
||||||
is IrCall -> visitCall(element, data)
|
is IrCall -> visitCall(element, data)
|
||||||
@@ -127,15 +108,19 @@ class IrInterpreter : IrElementVisitor<State, Frame> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall, data: Frame): State {
|
override fun visitCall(expression: IrCall, data: Frame): State {
|
||||||
val dispatchReceiver = expression.dispatchReceiver?.accept(this, data)
|
|
||||||
val extensionReceiver = expression.extensionReceiver?.accept(this, data)
|
|
||||||
val newFrame = InterpreterFrame(expression.convertValueParameters(data))
|
val newFrame = InterpreterFrame(expression.convertValueParameters(data))
|
||||||
|
if (expression.symbol.owner.isFakeOverride) {
|
||||||
|
expression.dispatchReceiver?.accept(this, data)?.let { newFrame.addVar(it) }
|
||||||
|
return calculateOverridden(expression.symbol, newFrame)
|
||||||
|
}
|
||||||
|
|
||||||
|
val dispatchReceiver = expression.dispatchReceiver?.accept(this, data)
|
||||||
|
?.setDescriptor(expression.symbol.descriptor.dispatchReceiverParameter!!)
|
||||||
|
val extensionReceiver = expression.extensionReceiver?.accept(this, data)
|
||||||
|
?.setDescriptor(expression.symbol.descriptor.extensionReceiverParameter?.containingDeclaration!!)
|
||||||
(dispatchReceiver ?: extensionReceiver)?.also { newFrame.addVar(it) }
|
(dispatchReceiver ?: extensionReceiver)?.also { newFrame.addVar(it) }
|
||||||
|
|
||||||
return if (expression.getBody() == null) {
|
return if (expression.getBody() == null) {
|
||||||
if (expression.symbol.owner.isFakeOverride) {
|
|
||||||
return expression.symbol.caclOverridden(newFrame.getAll())
|
|
||||||
}
|
|
||||||
calculateBuiltIns(expression.symbol.descriptor, newFrame).toIrConst(expression).toPrimitive()
|
calculateBuiltIns(expression.symbol.descriptor, newFrame).toIrConst(expression).toPrimitive()
|
||||||
} else {
|
} else {
|
||||||
expression.getBody()!!.accept(this, newFrame)
|
expression.getBody()!!.accept(this, newFrame)
|
||||||
@@ -143,40 +128,45 @@ class IrInterpreter : IrElementVisitor<State, Frame> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun <T> visitConst(expression: IrConst<T>, data: Frame): State {
|
override fun <T> visitConst(expression: IrConst<T>, data: Frame): State {
|
||||||
return Primitive(expression)
|
return expression.toPrimitive()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun visitConstructor(constructor: IrFunctionAccessExpression, data: Frame): State {
|
||||||
|
val newFrame = InterpreterFrame(constructor.convertValueParameters(data))
|
||||||
|
val obj = Complex((constructor.symbol.descriptor.containingDeclaration as ClassDescriptor).thisAsReceiverParameter, mutableListOf())
|
||||||
|
constructor.getBody()?.statements?.forEach {
|
||||||
|
when (it) {
|
||||||
|
is IrDelegatingConstructorCall -> {
|
||||||
|
obj.addSuperQualifier(visitDelegatingConstructorCall(it, newFrame) as Complex)
|
||||||
|
newFrame.addVar(obj)
|
||||||
|
}
|
||||||
|
else -> it.accept(this, newFrame)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitConstructorCall(expression: IrConstructorCall, data: Frame): State {
|
override fun visitConstructorCall(expression: IrConstructorCall, data: Frame): State {
|
||||||
val newFrame = InterpreterFrame(expression.convertValueParameters(data))
|
return visitConstructor(expression, data)
|
||||||
val state = expression.getBody()?.accept(this, newFrame) ?: unit
|
|
||||||
return Complex(expression.symbol.descriptor.containingDeclaration, state.getState())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: Frame): State {
|
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: Frame): State {
|
||||||
if (expression.symbol.descriptor.containingDeclaration.classId?.asString() == "kotlin/Any") {
|
if (expression.symbol.descriptor.containingDeclaration.defaultType == builtIns.anyType) {
|
||||||
return unit
|
return any
|
||||||
}
|
}
|
||||||
|
|
||||||
val newFrame = InterpreterFrame(expression.convertValueParameters(data))
|
return visitConstructor(expression, data)
|
||||||
val state = expression.getBody()?.accept(this, newFrame) ?: unit
|
|
||||||
return Complex(expression.symbol.descriptor.containingDeclaration, state.getState())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun visitStatements(statements: List<IrStatement>, data: Frame): State {
|
private fun visitStatements(statements: List<IrStatement>, data: Frame): State {
|
||||||
val state = mutableListOf<State>()
|
|
||||||
statements.forEach {
|
statements.forEach {
|
||||||
when (it) {
|
when (it) {
|
||||||
is IrReturn -> return visitReturn(it, data)
|
is IrReturn -> return it.accept(this, data)
|
||||||
else -> state += it.accept(this, data)
|
else -> it.accept(this, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state.removeIf { it == unit }
|
return unit
|
||||||
return when (state.size) {
|
|
||||||
0 -> unit
|
|
||||||
1 -> state.first()
|
|
||||||
else -> Complex(null, state)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitReturn(expression: IrReturn, data: Frame): State {
|
override fun visitReturn(expression: IrReturn, data: Frame): State {
|
||||||
@@ -184,21 +174,18 @@ class IrInterpreter : IrElementVisitor<State, Frame> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitSetField(expression: IrSetField, data: Frame): State {
|
override fun visitSetField(expression: IrSetField, data: Frame): State {
|
||||||
val value = expression.value.accept(this, data)
|
val value = expression.value.accept(this, data).setDescriptor(expression.symbol.owner.descriptor)
|
||||||
return value.setDescriptor(expression.symbol.owner.descriptor)
|
val receiver = (expression.receiver as IrDeclarationReference).symbol.descriptor
|
||||||
|
data.getVar(receiver).setState(value)
|
||||||
|
return unit
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitGetField(expression: IrGetField, data: Frame): State {
|
override fun visitGetField(expression: IrGetField, data: Frame): State {
|
||||||
return data.getVar(expression.symbol.descriptor.containingDeclaration)
|
val receiver = (expression.receiver as IrDeclarationReference).symbol.descriptor
|
||||||
.getState()
|
return data.getVar(receiver).getState(expression.symbol.descriptor).copy()
|
||||||
.first { it.getDescriptor() == expression.descriptor }
|
|
||||||
.copy()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitGetValue(expression: IrGetValue, data: Frame): State {
|
override fun visitGetValue(expression: IrGetValue, data: Frame): State {
|
||||||
if (expression.symbol.descriptor is ReceiverParameterDescriptor) {
|
|
||||||
return data.getVar(expression.symbol.descriptor.containingDeclaration).copy()
|
|
||||||
}
|
|
||||||
return data.getVar(expression.symbol.descriptor).copy()
|
return data.getVar(expression.symbol.descriptor).copy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.common.interpreter
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.interpreter.stack.Primitive
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
|
|
||||||
|
fun IrFunctionSymbol.getThisAsReceiver(): ReceiverParameterDescriptor {
|
||||||
|
return (this.descriptor.containingDeclaration as ClassDescriptor).thisAsReceiverParameter
|
||||||
|
}
|
||||||
|
|
||||||
|
fun IrFunctionAccessExpression.getBody(): IrBody? {
|
||||||
|
return this.symbol.owner.body
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Any.toIrConst(expression: IrExpression): IrConst<*> {
|
||||||
|
return when (this) {
|
||||||
|
is Boolean -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Boolean, this)
|
||||||
|
is Char -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Char, this)
|
||||||
|
is Byte -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Byte, this)
|
||||||
|
is Short -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Short, this)
|
||||||
|
is Int -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Int, this)
|
||||||
|
is Long -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Long, this)
|
||||||
|
is String -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.String, this)
|
||||||
|
is Float -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Float, this)
|
||||||
|
is Double -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Double, this)
|
||||||
|
else -> throw UnsupportedOperationException("Unsupported const element type $this")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> IrConst<T>.toPrimitive(): Primitive<T> {
|
||||||
|
return Primitive(this)
|
||||||
|
}
|
||||||
+1
-1
@@ -20,7 +20,7 @@ class InterpreterFrame(val pool: MutableList<State> = mutableListOf()) : Frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getVar(descriptor: DeclarationDescriptor): State {
|
override fun getVar(descriptor: DeclarationDescriptor): State {
|
||||||
return pool.firstOrNull { it.getDescriptor() == descriptor }
|
return pool.firstOrNull { it.isTypeOf(descriptor) }
|
||||||
?: throw NoSuchElementException("Frame pool doesn't contains variable with descriptor $descriptor")
|
?: throw NoSuchElementException("Frame pool doesn't contains variable with descriptor $descriptor")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+51
-17
@@ -9,24 +9,38 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrConst
|
import org.jetbrains.kotlin.ir.expressions.IrConst
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
fun getState(): List<State>
|
fun getState(descriptor: DeclarationDescriptor): State
|
||||||
fun getDescriptor(): DeclarationDescriptor?
|
fun setState(newState: State)
|
||||||
|
fun getDescriptor(): DeclarationDescriptor
|
||||||
fun setDescriptor(descriptor: DeclarationDescriptor): State
|
fun setDescriptor(descriptor: DeclarationDescriptor): State
|
||||||
|
fun isTypeOf(descriptor: DeclarationDescriptor): Boolean
|
||||||
fun copy(): State
|
fun copy(): State
|
||||||
}
|
}
|
||||||
|
|
||||||
class Primitive<T>(private val value: IrConst<T>) : State {
|
class Primitive<T>(private var value: IrConst<T>) : State {
|
||||||
private lateinit var declarationDescriptor: DeclarationDescriptor
|
private lateinit var declarationDescriptor: DeclarationDescriptor
|
||||||
|
|
||||||
private constructor(descriptor: DeclarationDescriptor, value: IrConst<T>) : this(value) {
|
constructor(descriptor: DeclarationDescriptor, value: IrConst<T>) : this(value) {
|
||||||
declarationDescriptor = descriptor
|
declarationDescriptor = descriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getState(): List<State> {
|
fun getIrConst(): IrConst<T> {
|
||||||
return listOf(this)
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDescriptor(): DeclarationDescriptor? {
|
override fun getState(descriptor: DeclarationDescriptor): State {
|
||||||
|
return when (descriptor) {
|
||||||
|
this.declarationDescriptor -> this
|
||||||
|
else -> throw IllegalAccessException("Can't get descriptor $descriptor from $this")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setState(newState: State) {
|
||||||
|
newState as? Primitive<T> ?: throw IllegalArgumentException("Cannot set $newState in current $this")
|
||||||
|
value = newState.value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDescriptor(): DeclarationDescriptor {
|
||||||
return declarationDescriptor
|
return declarationDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,24 +49,40 @@ class Primitive<T>(private val value: IrConst<T>) : State {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isTypeOf(descriptor: DeclarationDescriptor): Boolean {
|
||||||
|
return declarationDescriptor == descriptor
|
||||||
|
}
|
||||||
|
|
||||||
override fun copy(): State {
|
override fun copy(): State {
|
||||||
return Primitive(declarationDescriptor, value)
|
return Primitive(declarationDescriptor, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun getIrConst(): IrConst<T> {
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "Primitive(varName='${declarationDescriptor.name}', value=${value.value})"
|
return "Primitive(varName='${declarationDescriptor.name}', value=${value.value})"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Complex(private var declarationDescriptor: DeclarationDescriptor?, private val values: List<State>) : State {
|
class Complex(private var declarationDescriptor: DeclarationDescriptor, private val values: MutableList<State>) : State {
|
||||||
override fun getState(): List<State> {
|
private val superQualifiers = mutableListOf<Complex>()
|
||||||
return values
|
|
||||||
|
public fun addSuperQualifier(superObj: Complex) {
|
||||||
|
superQualifiers += superObj.superQualifiers
|
||||||
|
superQualifiers += superObj
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDescriptor(): DeclarationDescriptor? {
|
override fun getState(descriptor: DeclarationDescriptor): State {
|
||||||
|
return (values + superQualifiers).first { it.getDescriptor() == descriptor }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setState(newState: State) {
|
||||||
|
val oldState = values.firstOrNull { it.getDescriptor() == newState.getDescriptor() }
|
||||||
|
if (oldState == null) {
|
||||||
|
values.add(newState)
|
||||||
|
} else {
|
||||||
|
values[values.indexOf(oldState)] = newState
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDescriptor(): DeclarationDescriptor {
|
||||||
return declarationDescriptor
|
return declarationDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,11 +91,15 @@ class Complex(private var declarationDescriptor: DeclarationDescriptor?, private
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isTypeOf(descriptor: DeclarationDescriptor): Boolean {
|
||||||
|
return (superQualifiers + this).any { it.declarationDescriptor == descriptor }
|
||||||
|
}
|
||||||
|
|
||||||
override fun copy(): State {
|
override fun copy(): State {
|
||||||
return Complex(declarationDescriptor, values)
|
return Complex(declarationDescriptor, values).apply { this.superQualifiers += this@Complex.superQualifiers }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "Complex(objName='${declarationDescriptor?.name}', values=$values)"
|
return "Complex(obj='$declarationDescriptor', super=$superQualifiers, values=$values)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user