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

org.jetbrains.kotlin.fir.scopes.impl.AbstractFirOverrideScope.kt Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/*
 * Copyright 2010-2019 JetBrains s.r.o. 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.fir.scopes.impl

import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.FirPropertyBuilder
import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder
import org.jetbrains.kotlin.fir.declarations.builder.FirValueParameterBuilder
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol

abstract class AbstractFirOverrideScope(
    val session: FirSession,
    protected val overrideChecker: FirOverrideChecker
) : FirTypeScope() {
    //base symbol as key, overridden as value
    val overrideByBase = mutableMapOf, FirCallableSymbol<*>?>()

    private fun isOverriddenFunction(overrideCandidate: FirSimpleFunction, baseDeclaration: FirSimpleFunction): Boolean {
        return overrideChecker.isOverriddenFunction(overrideCandidate, baseDeclaration)
    }

    private fun isOverriddenProperty(overrideCandidate: FirCallableMemberDeclaration<*>, baseDeclaration: FirProperty): Boolean {
        return overrideChecker.isOverriddenProperty(overrideCandidate, baseDeclaration)
    }

    protected fun similarFunctionsOrBothProperties(
        overrideCandidate: FirCallableMemberDeclaration<*>,
        baseDeclaration: FirCallableMemberDeclaration<*>
    ): Boolean {
        return when (overrideCandidate) {
            is FirSimpleFunction -> when (baseDeclaration) {
                is FirSimpleFunction -> isOverriddenFunction(overrideCandidate, baseDeclaration)
                is FirProperty -> isOverriddenProperty(overrideCandidate, baseDeclaration)
                else -> false
            }
            is FirConstructor -> false
            is FirProperty -> baseDeclaration is FirProperty && isOverriddenProperty(overrideCandidate, baseDeclaration)
            is FirField -> baseDeclaration is FirField
            else -> error("Unknown fir callable type: $overrideCandidate, $baseDeclaration")
        }
    }

    // Receiver is super-type function here
    protected open fun FirCallableSymbol<*>.getOverridden(overrideCandidates: Set>): FirCallableSymbol<*>? {
        if (overrideByBase.containsKey(this)) return overrideByBase[this]

        val baseDeclaration = (this as AbstractFirBasedSymbol<*>).fir as FirCallableMemberDeclaration<*>
        val override = overrideCandidates.firstOrNull {
            val overrideCandidate = (it as AbstractFirBasedSymbol<*>).fir as FirCallableMemberDeclaration<*>
            baseDeclaration.modality != Modality.FINAL && similarFunctionsOrBothProperties(overrideCandidate, baseDeclaration)
        } // TODO: two or more overrides for one fun?
        overrideByBase[this] = override
        return override
    }

    protected open fun createFunctionCopy(
        firSimpleFunction: FirSimpleFunction,
        newSymbol: FirNamedFunctionSymbol
    ): FirSimpleFunctionBuilder =
        FirSimpleFunctionBuilder().apply {
            source = firSimpleFunction.source
            session = firSimpleFunction.session
            resolvePhase = firSimpleFunction.resolvePhase
            origin = FirDeclarationOrigin.FakeOverride
            returnTypeRef = firSimpleFunction.returnTypeRef
            receiverTypeRef = firSimpleFunction.receiverTypeRef
            name = firSimpleFunction.name
            status = firSimpleFunction.status
            symbol = newSymbol
        }

    protected open fun createValueParameterCopy(parameter: FirValueParameter, newDefaultValue: FirExpression?): FirValueParameterBuilder =
        FirValueParameterBuilder().apply {
            source = parameter.source
            session = parameter.session
            resolvePhase = parameter.resolvePhase
            origin = FirDeclarationOrigin.FakeOverride
            returnTypeRef = parameter.returnTypeRef
            name = parameter.name
            symbol = FirVariableSymbol(parameter.symbol.callableId)
            defaultValue = newDefaultValue
            isCrossinline = parameter.isCrossinline
            isNoinline = parameter.isNoinline
            isVararg = parameter.isVararg
        }

    protected open fun createPropertyCopy(
        firProperty: FirProperty,
        newSymbol: FirPropertySymbol
    ): FirPropertyBuilder =
        FirPropertyBuilder().apply {
            source = firProperty.source
            session = firProperty.session
            resolvePhase = firProperty.resolvePhase
            origin = FirDeclarationOrigin.FakeOverride
            returnTypeRef = firProperty.returnTypeRef
            receiverTypeRef = firProperty.receiverTypeRef
            isVar = firProperty.isVar
            isLocal = firProperty.isLocal
            getter = firProperty.getter
            setter = firProperty.setter
            name = firProperty.name
            status = firProperty.status
            symbol = newSymbol
        }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy