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

kotlin.reflect.jvm.internal.ReflectionObjectRenderer.kt Maven / Gradle / Ivy

There is a newer version: 2.1.0-Beta1
Show newest version
/*
 * Copyright 2010-2015 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package kotlin.reflect.jvm.internal

import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.types.KotlinType
import kotlin.reflect.KParameter

internal object ReflectionObjectRenderer {
    private val renderer = DescriptorRenderer.FQ_NAMES_IN_TYPES

    private fun StringBuilder.appendReceiverType(receiver: ReceiverParameterDescriptor?) {
        if (receiver != null) {
            append(renderType(receiver.type))
            append(".")
        }
    }

    private fun StringBuilder.appendReceivers(callable: CallableDescriptor) {
        val dispatchReceiver = callable.instanceReceiverParameter
        val extensionReceiver = callable.extensionReceiverParameter

        appendReceiverType(dispatchReceiver)

        val addParentheses = dispatchReceiver != null && extensionReceiver != null
        if (addParentheses) append("(")
        appendReceiverType(extensionReceiver)
        if (addParentheses) append(")")
    }

    private fun renderCallable(descriptor: CallableDescriptor): String {
        return when (descriptor) {
            is PropertyDescriptor -> renderProperty(descriptor)
            is FunctionDescriptor -> renderFunction(descriptor)
            else -> error("Illegal callable: $descriptor")
        }
    }

    // TODO: include visibility
    fun renderProperty(descriptor: PropertyDescriptor): String {
        return buildString {
            append(if (descriptor.isVar) "var " else "val ")
            appendReceivers(descriptor)
            append(renderer.renderName(descriptor.name, true))

            append(": ")
            append(renderType(descriptor.type))
        }
    }

    fun renderFunction(descriptor: FunctionDescriptor): String {
        return buildString {
            append("fun ")
            appendReceivers(descriptor)
            append(renderer.renderName(descriptor.name, true))

            descriptor.valueParameters.joinTo(this, separator = ", ", prefix = "(", postfix = ")") {
                renderType(it.type) // TODO: vararg
            }

            append(": ")
            append(renderType(descriptor.returnType!!))
        }
    }

    fun renderLambda(invoke: FunctionDescriptor): String {
        return buildString {
            appendReceivers(invoke)

            invoke.valueParameters.joinTo(this, separator = ", ", prefix = "(", postfix = ")") {
                renderType(it.type)
            }

            append(" -> ")
            append(renderType(invoke.returnType!!))
        }
    }

    fun renderParameter(parameter: KParameterImpl): String {
        return buildString {
            when (parameter.kind) {
                KParameter.Kind.EXTENSION_RECEIVER -> append("extension receiver parameter")
                KParameter.Kind.INSTANCE -> append("instance parameter")
                KParameter.Kind.VALUE -> append("parameter #${parameter.index} ${parameter.name}")
            }

            append(" of ")
            append(renderCallable(parameter.callable.descriptor))
        }
    }

    fun renderType(type: KotlinType): String {
        return renderer.renderType(type)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy