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

org.jetbrains.kotlin.ir.types.irTypes.kt Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/*
 * 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.ir.types

import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.impl.*
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
import org.jetbrains.kotlin.types.typeUtil.makeNullable
import org.jetbrains.kotlin.utils.addToStdlib.cast
import org.jetbrains.kotlin.utils.addToStdlib.safeAs

fun IrType.withHasQuestionMark(newHasQuestionMark: Boolean): IrType =
    when (this) {
        is IrSimpleType ->
            if (this.hasQuestionMark == newHasQuestionMark)
                this
            else
                buildSimpleType {
                    hasQuestionMark = newHasQuestionMark
                    kotlinType = originalKotlinType?.run {
                        if (newHasQuestionMark) makeNullable() else makeNotNullable()
                    }
                }
        else -> this
    }

val IrType.classifierOrFail: IrClassifierSymbol
    get() = cast().classifier

val IrType.classifierOrNull: IrClassifierSymbol?
    get() = safeAs()?.classifier

val IrType.classOrNull: IrClassSymbol?
    get() = classifierOrNull as? IrClassSymbol

val IrTypeArgument.typeOrNull: IrType? get() = (this as? IrTypeProjection)?.type

fun IrType.makeNotNull() =
    if (this is IrSimpleType && this.hasQuestionMark) {
        buildSimpleType {
            kotlinType = originalKotlinType?.makeNotNullable()
            hasQuestionMark = false
        }
    } else
        this

fun IrType.makeNullable() =
    if (this is IrSimpleType && !this.hasQuestionMark)
        buildSimpleType {
            kotlinType = originalKotlinType?.makeNullable()
            hasQuestionMark = true
        }
    else
        this

@ObsoleteDescriptorBasedAPI
fun IrType.toKotlinType(): KotlinType {
    originalKotlinType?.let {
        return it
    }

    return when (this) {
        is IrSimpleType -> makeKotlinType(classifier, arguments, hasQuestionMark)
        else -> TODO(toString())
    }
}

fun IrType.getClass(): IrClass? =
    classOrNull?.owner

fun IrClassSymbol.createType(hasQuestionMark: Boolean, arguments: List): IrSimpleType =
    IrSimpleTypeImpl(
        this,
        hasQuestionMark,
        arguments,
        emptyList()
    )

@ObsoleteDescriptorBasedAPI
private fun makeKotlinType(
    classifier: IrClassifierSymbol,
    arguments: List,
    hasQuestionMark: Boolean
): SimpleType {
    val kotlinTypeArguments = arguments.mapIndexed { index, it ->
        when (it) {
            is IrTypeProjection -> TypeProjectionImpl(it.variance, it.type.toKotlinType())
            is IrStarProjection -> StarProjectionImpl((classifier.descriptor as ClassDescriptor).typeConstructor.parameters[index])
            else -> error(it)
        }
    }
    return classifier.descriptor.defaultType.replace(newArguments = kotlinTypeArguments).makeNullableAsSpecified(hasQuestionMark)
}

val IrClassifierSymbol.defaultType: IrType
    get() = when (this) {
        is IrClassSymbol -> owner.defaultType
        is IrTypeParameterSymbol -> owner.defaultType
        else -> error("Unexpected classifier symbol type $this")
    }

val IrTypeParameter.defaultType: IrType
    get() = IrSimpleTypeImpl(
        symbol,
        hasQuestionMark = false,
        arguments = emptyList(),
        annotations = emptyList()
    )

val IrClassSymbol.starProjectedType: IrSimpleType
    get() = IrSimpleTypeImpl(
        this,
        hasQuestionMark = false,
        arguments = owner.typeParameters.map { IrStarProjectionImpl },
        annotations = emptyList()
    )

fun IrClassifierSymbol.typeWithParameters(parameters: List): IrSimpleType =
    typeWith(parameters.map { it.defaultType })

fun IrClassifierSymbol.typeWith(vararg arguments: IrType): IrSimpleType = typeWith(arguments.toList())

fun IrClassifierSymbol.typeWith(arguments: List): IrSimpleType =
    IrSimpleTypeImpl(
        this,
        false,
        arguments.map { makeTypeProjection(it, Variance.INVARIANT) },
        emptyList()
    )

fun IrClass.typeWith(arguments: List) = this.symbol.typeWith(arguments)

fun IrClass.typeWith(vararg arguments: IrType) = this.symbol.typeWith(arguments.toList())




© 2015 - 2024 Weber Informatics LLC | Privacy Policy