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

org.jetbrains.kotlin.ir.interpreter.state.reflection.ReflectionState.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.reflection

import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.interpreter.stack.Fields
import org.jetbrains.kotlin.ir.interpreter.state.State
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.parentClassOrNull
import org.jetbrains.kotlin.ir.util.render
import kotlin.math.min

internal abstract class ReflectionState : State {
    override val fields: Fields = mutableMapOf()

    override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? = null

    private fun renderReceivers(dispatchReceiver: IrType?, extensionReceiver: IrType?): String {
        return buildString {
            if (dispatchReceiver != null) {
                append(dispatchReceiver.renderType()).append(".")
            }

            if (extensionReceiver != null) {
                val addParentheses = dispatchReceiver != null
                if (addParentheses) append("(")
                append(extensionReceiver.renderType()).append(".")
                if (addParentheses) append(")")
            }
        }
    }

    protected fun renderLambda(irFunction: IrFunction): String {
        val receiver = (irFunction.dispatchReceiverParameter?.type ?: irFunction.extensionReceiverParameter?.type)?.renderType()
        val arguments = irFunction.valueParameters.joinToString(prefix = "(", postfix = ")") { it.type.renderType() }
        val returnType = irFunction.returnType.renderType()
        return ("$arguments -> $returnType").let { if (receiver != null) "$receiver.$it" else it }
    }

    protected fun renderFunction(irFunction: IrFunction): String {
        val dispatchReceiver = irFunction.parentClassOrNull?.defaultType // = instanceReceiverParameter
        val extensionReceiver = irFunction.extensionReceiverParameter?.type
        val receivers = if (irFunction is IrConstructor) "" else renderReceivers(dispatchReceiver, extensionReceiver)
        val arguments = irFunction.valueParameters.joinToString(prefix = "(", postfix = ")") { it.type.renderType() }
        val returnType = irFunction.returnType.renderType()
        return "fun $receivers${irFunction.name}$arguments: $returnType"
    }

    protected fun renderProperty(property: IrProperty): String {
        val prefix = if (property.isVar) "var" else "val"
        val receivers = renderReceivers(property.getter?.dispatchReceiverParameter?.type, property.getter?.extensionReceiverParameter?.type)
        val returnType = property.getter!!.returnType.renderType()
        return "$prefix $receivers${property.name}: $returnType"
    }

    protected fun IrType.renderType(): String {
        var renderedType = this.render().replace(".", "")
        if (renderedType.contains("', startIndex) + 1
            renderedType = renderedType.replaceRange(startIndex, lastTriangle, "get")
        }
        do {
            val index = renderedType.indexOf(" of ")
            if (index == -1) break
            val replaceUntilComma = renderedType.indexOf(',', index)
            val replaceUntilTriangle = renderedType.indexOf('>', index)
            val replaceUntil = when {
                replaceUntilComma == -1 && replaceUntilTriangle == -1 -> renderedType.length
                replaceUntilComma == -1 -> replaceUntilTriangle
                replaceUntilTriangle == -1 -> replaceUntilComma
                else -> min(replaceUntilComma, replaceUntilTriangle)
            }
            renderedType = renderedType.replaceRange(index, replaceUntil, "")
        } while (true)
        return renderedType
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy