[FIR] Introduce & use FirDelegatedMemberScope
This commit is contained in:
+1
-1
@@ -7,6 +7,6 @@ open class B(private val a: A) : A by a
|
||||
class C(a: A) : B(a) {
|
||||
override fun foo() {
|
||||
// Should be resolved to delegated B.foo (no error)
|
||||
super.<!ABSTRACT_SUPER_CALL!>foo<!>()
|
||||
super.foo()
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -164,7 +164,7 @@ private fun processConstructors(
|
||||
}
|
||||
is FirClassSymbol ->
|
||||
(matchedSymbol.fir as FirClass<*>).scope(
|
||||
substitutor, session, scopeSession, false,
|
||||
substitutor, session, scopeSession, skipPrivateMembers = false,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,18 +7,17 @@ package org.jetbrains.kotlin.fir.scopes
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.classId
|
||||
import org.jetbrains.kotlin.fir.declarations.isExpect
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
|
||||
class KotlinScopeProvider(
|
||||
@@ -39,14 +38,16 @@ class KotlinScopeProvider(
|
||||
val decoratedDeclaredMemberScope =
|
||||
declaredMemberScopeDecorator(klass, declaredScope, useSiteSession, scopeSession)
|
||||
|
||||
val delegateFields = klass.declarations.filterIsInstance<FirField>().filter { it.isSynthetic }
|
||||
val scopes = lookupSuperTypes(klass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession)
|
||||
.mapNotNull { useSiteSuperType ->
|
||||
if (useSiteSuperType is ConeClassErrorType) return@mapNotNull null
|
||||
val symbol = useSiteSuperType.lookupTag.toSymbol(useSiteSession)
|
||||
if (symbol is FirRegularClassSymbol) {
|
||||
val delegateField = delegateFields.find { it.returnTypeRef.coneType == useSiteSuperType }
|
||||
symbol.fir.scope(
|
||||
substitutor(symbol, useSiteSuperType, useSiteSession),
|
||||
useSiteSession, scopeSession,
|
||||
useSiteSession, scopeSession, delegateField,
|
||||
skipPrivateMembers = true,
|
||||
classId = klass.classId,
|
||||
isFromExpectClass = (klass as? FirRegularClass)?.isExpect == true
|
||||
@@ -94,6 +95,8 @@ data class ConeSubstitutionScopeKey(
|
||||
val classId: ClassId?, val isFromExpectClass: Boolean, val substitutor: ConeSubstitutor
|
||||
) : ScopeSessionKey<FirClass<*>, FirClassSubstitutionScope>()
|
||||
|
||||
data class DelegatedMemberScopeKey(val callableId: CallableId) : ScopeSessionKey<FirField, FirDelegatedMemberScope>()
|
||||
|
||||
fun FirClass<*>.unsubstitutedScope(useSiteSession: FirSession, scopeSession: ScopeSession): FirTypeScope {
|
||||
return scopeProvider.getUseSiteMemberScope(this, useSiteSession, scopeSession)
|
||||
}
|
||||
@@ -102,13 +105,20 @@ internal fun FirClass<*>.scope(
|
||||
substitutor: ConeSubstitutor,
|
||||
useSiteSession: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
delegateField: FirField? = null,
|
||||
skipPrivateMembers: Boolean,
|
||||
classId: ClassId? = this.classId,
|
||||
isFromExpectClass: Boolean = false
|
||||
): FirTypeScope {
|
||||
val basicScope = scopeProvider.getUseSiteMemberScope(
|
||||
this, useSiteSession, scopeSession
|
||||
)
|
||||
val basicScope = unsubstitutedScope(useSiteSession, scopeSession).let {
|
||||
if (delegateField != null) {
|
||||
scopeSession.getOrBuild(delegateField, DelegatedMemberScopeKey(delegateField.symbol.callableId)) {
|
||||
FirDelegatedMemberScope(it, useSiteSession)
|
||||
}
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
if (substitutor == ConeSubstitutor.Empty) return basicScope
|
||||
|
||||
return scopeSession.getOrBuild(
|
||||
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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.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.buildProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class FirDelegatedMemberScope(
|
||||
private val useSiteScope: FirTypeScope,
|
||||
private val session: FirSession
|
||||
) : FirTypeScope() {
|
||||
private val delegatedFunctionCache = mutableMapOf<FirNamedFunctionSymbol, FirNamedFunctionSymbol>()
|
||||
private val delegatedPropertyCache = mutableMapOf<FirPropertySymbol, FirPropertySymbol>()
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) {
|
||||
useSiteScope.processFunctionsByName(name) processor@{ functionSymbol ->
|
||||
if (functionSymbol !is FirNamedFunctionSymbol) {
|
||||
processor(functionSymbol)
|
||||
return@processor
|
||||
}
|
||||
val original = functionSymbol.fir
|
||||
if (original.modality == Modality.FINAL) {
|
||||
processor(functionSymbol)
|
||||
return@processor
|
||||
}
|
||||
val delegatedSymbol = delegatedFunctionCache.getOrPut(functionSymbol) {
|
||||
val delegatedFunction = buildSimpleFunction {
|
||||
origin = FirDeclarationOrigin.Delegated
|
||||
session = this@FirDelegatedMemberScope.session
|
||||
this.name = name
|
||||
symbol = FirNamedFunctionSymbol(
|
||||
functionSymbol.callableId,
|
||||
overriddenSymbol = functionSymbol
|
||||
)
|
||||
status = FirDeclarationStatusImpl(original.visibility, Modality.OPEN).apply {
|
||||
isOperator = original.isOperator
|
||||
}
|
||||
resolvePhase = FirResolvePhase.BODY_RESOLVE
|
||||
returnTypeRef = original.returnTypeRef
|
||||
receiverTypeRef = original.receiverTypeRef
|
||||
valueParameters.addAll(original.valueParameters)
|
||||
typeParameters.addAll(original.typeParameters)
|
||||
annotations.addAll(original.annotations)
|
||||
}
|
||||
delegatedFunction.symbol as FirNamedFunctionSymbol
|
||||
}
|
||||
processor(delegatedSymbol)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
useSiteScope.processPropertiesByName(name) processor@{ propertySymbol ->
|
||||
if (propertySymbol !is FirPropertySymbol) {
|
||||
processor(propertySymbol)
|
||||
return@processor
|
||||
}
|
||||
val original = propertySymbol.fir
|
||||
if (original.modality == Modality.FINAL) {
|
||||
processor(propertySymbol)
|
||||
return@processor
|
||||
}
|
||||
val delegatedSymbol = delegatedPropertyCache.getOrPut(propertySymbol) {
|
||||
val delegatedProperty = buildProperty {
|
||||
origin = FirDeclarationOrigin.Delegated
|
||||
session = this@FirDelegatedMemberScope.session
|
||||
this.name = name
|
||||
symbol = FirPropertySymbol(
|
||||
propertySymbol.callableId,
|
||||
overriddenSymbol = propertySymbol
|
||||
)
|
||||
isVar = original.isVar
|
||||
isLocal = false
|
||||
status = FirDeclarationStatusImpl(original.visibility, Modality.OPEN)
|
||||
resolvePhase = FirResolvePhase.BODY_RESOLVE
|
||||
returnTypeRef = original.returnTypeRef
|
||||
receiverTypeRef = original.receiverTypeRef
|
||||
typeParameters.addAll(original.typeParameters)
|
||||
annotations.addAll(original.annotations)
|
||||
}
|
||||
delegatedProperty.symbol
|
||||
}
|
||||
processor(delegatedSymbol)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processDirectOverriddenFunctionsWithBaseScope(
|
||||
functionSymbol: FirFunctionSymbol<*>,
|
||||
processor: (FirFunctionSymbol<*>, FirTypeScope) -> ProcessorAction
|
||||
): ProcessorAction {
|
||||
return useSiteScope.processDirectOverriddenFunctionsWithBaseScope(functionSymbol, processor)
|
||||
}
|
||||
|
||||
override fun processDirectOverriddenPropertiesWithBaseScope(
|
||||
propertySymbol: FirPropertySymbol,
|
||||
processor: (FirPropertySymbol, FirTypeScope) -> ProcessorAction
|
||||
): ProcessorAction {
|
||||
return useSiteScope.processDirectOverriddenPropertiesWithBaseScope(propertySymbol, processor)
|
||||
}
|
||||
|
||||
override fun getCallableNames(): Set<Name> {
|
||||
return useSiteScope.getCallableNames()
|
||||
}
|
||||
|
||||
override fun getClassifierNames(): Set<Name> {
|
||||
return useSiteScope.getClassifierNames()
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ sealed class FirDeclarationOrigin {
|
||||
object Enhancement : FirDeclarationOrigin()
|
||||
object ImportedFromObject : FirDeclarationOrigin()
|
||||
object IntersectionOverride : FirDeclarationOrigin()
|
||||
object Delegated : FirDeclarationOrigin()
|
||||
|
||||
class Plugin(val key: FirPluginKey) : FirDeclarationOrigin()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user