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

org.jetbrains.kotlin.ir.overrides.CopyIrTreeWithSymbolsForFakeOverrides.kt Maven / Gradle / Ivy

There is a newer version: 2.1.0-RC
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.overrides

import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrOverridableMember
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.linkage.partial.IrUnimplementedOverridesStrategy
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.utils.memoryOptimizedMap

// This is basically modelled after the inliner copier.
class CopyIrTreeWithSymbolsForFakeOverrides(
    private val overridableMember: IrOverridableMember,
    typeArguments: Map,
    private val parent: IrClass,
    unimplementedOverridesStrategy: IrUnimplementedOverridesStrategy
) {
    fun copy(): IrOverridableMember {
        // Create new symbols.
        overridableMember.acceptVoid(symbolRemapper)

        // Make symbol remapper aware of the callsite's type arguments.
        // Copy IR.
        val result = overridableMember.transform(
            if (parent.isEffectivelyExternal()) copierMakingExternal else copier,
            data = null
        ) as IrOverridableMember

        result.patchDeclarationParents(parent)

        return result
    }

    private inner class FakeOverrideTypeRemapper(
        val symbolRemapper: SymbolRemapper,
        val typeArguments: Map
    ) : TypeRemapper {

        override fun enterScope(irTypeParametersContainer: IrTypeParametersContainer) {}

        override fun leaveScope() {}

        private fun remapTypeArguments(arguments: List) =
            arguments.memoryOptimizedMap { argument ->
                (argument as? IrTypeProjection)?.let { makeTypeProjection(remapType(it.type), it.variance) }
                    ?: argument
            }

        override fun remapType(type: IrType): IrType {
            if (type !is IrSimpleType) return type

            return when (val substitutedType = typeArguments[type.classifier]) {
                is IrDynamicType -> substitutedType
                is IrSimpleType -> substitutedType.mergeNullability(type)
                else -> type.buildSimpleType {
                    kotlinType = null
                    classifier = symbolRemapper.getReferencedClassifier(type.classifier)
                    arguments = remapTypeArguments(type.arguments)
                    annotations = type.annotations.memoryOptimizedMap { it.transform(copier, null) as IrConstructorCall }
                }
            }
        }
    }

    private class FakeOverrideSymbolRemapperImpl(
        private val typeArguments: Map,
        descriptorsRemapper: DescriptorsRemapper
    ) :
        DeepCopySymbolRemapper(descriptorsRemapper) {

        override fun getReferencedClassifier(symbol: IrClassifierSymbol): IrClassifierSymbol {
            val result = super.getReferencedClassifier(symbol)
            if (result !is IrTypeParameterSymbol)
                return result
            return typeArguments[result]?.classifierOrNull ?: result
        }
    }

    private val symbolRemapper =
        FakeOverrideSymbolRemapperImpl(
            typeArguments,
            NullDescriptorsRemapper
        )

    private val copier = FakeOverrideCopier(
        symbolRemapper,
        FakeOverrideTypeRemapper(symbolRemapper, typeArguments),
        SymbolRenamer.DEFAULT,
        makeExternal = false,
        parent,
        unimplementedOverridesStrategy
    )

    private val copierMakingExternal = FakeOverrideCopier(
        symbolRemapper,
        FakeOverrideTypeRemapper(symbolRemapper, typeArguments),
        SymbolRenamer.DEFAULT,
        makeExternal = true,
        parent,
        unimplementedOverridesStrategy
    )
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy