All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlin.ir.interpreter.state.Complex.kt Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/*
 * Copyright 2010-2020 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.ir.interpreter.state

import org.jetbrains.kotlin.ir.interpreter.getCorrectReceiverByFunction
import org.jetbrains.kotlin.ir.interpreter.getLastOverridden
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
import org.jetbrains.kotlin.ir.util.isInterface
import org.jetbrains.kotlin.ir.util.overrides

internal abstract class Complex(override val irClass: IrClass, override val fields: MutableList) : State {
    var superClass: Complex? = null
    var subClass: Complex? = null
    val interfaces: MutableList = mutableListOf() // filled lazily, as needed
    override val typeArguments: MutableList = mutableListOf()
    var outerClass: Variable? = null

    fun setSuperClassInstance(superClass: Complex) {
        if (this.irClass == superClass.irClass) {
            // 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 {
        return subClass?.getOriginal() ?: this
    }

    fun irClassFqName(): String {
        return irClass.fqNameForIrSerialization.toString()
    }

    private fun contains(variable: Variable) = fields.any { it.symbol == variable.symbol }

    private fun getIrFunction(symbol: IrFunctionSymbol): IrFunction? {
        val propertyGetters = irClass.declarations.filterIsInstance().mapNotNull { it.getter }
        val functions = irClass.declarations.filterIsInstance()
        return (propertyGetters + functions).firstOrNull {
            if (it is IrSimpleFunction) it.overrides(symbol.owner as IrSimpleFunction) else it == symbol.owner
        }
    }

    private fun getThisOrSuperReceiver(superIrClass: IrClass?): Complex? {
        return when {
            superIrClass == null -> this.getOriginal()
            superIrClass.isInterface -> Common(superIrClass).apply {
                interfaces.add(this)
                this.subClass = this@Complex
            }
            else -> this.superClass
        }
    }

    protected fun getOverridden(owner: IrSimpleFunction, qualifier: State?): IrSimpleFunction {
        if (!owner.isFakeOverride) return owner
        if (qualifier == null || qualifier is ExceptionState || (qualifier as? Complex)?.superClass == null) {
            return owner.getLastOverridden() as IrSimpleFunction
        }

        val overriddenOwner = owner.overriddenSymbols.single().owner
        return when {
            overriddenOwner.body != null -> overriddenOwner
            else -> getOverridden(overriddenOwner, qualifier.superClass!!)
        }
    }

    override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? {
        val receiver = getThisOrSuperReceiver(expression.superQualifierSymbol?.owner) ?: return null

        val irFunction = receiver.getIrFunction(expression.symbol) ?: return null

        return when (irFunction.body) {
            null -> getOverridden(irFunction as IrSimpleFunction, this.getCorrectReceiverByFunction(irFunction))
            else -> irFunction
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy