[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) {
|
class C(a: A) : B(a) {
|
||||||
override fun foo() {
|
override fun foo() {
|
||||||
// Should be resolved to delegated B.foo (no error)
|
// 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 ->
|
is FirClassSymbol ->
|
||||||
(matchedSymbol.fir as FirClass<*>).scope(
|
(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.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
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.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.*
|
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.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
|
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
|
||||||
class KotlinScopeProvider(
|
class KotlinScopeProvider(
|
||||||
@@ -39,14 +38,16 @@ class KotlinScopeProvider(
|
|||||||
val decoratedDeclaredMemberScope =
|
val decoratedDeclaredMemberScope =
|
||||||
declaredMemberScopeDecorator(klass, declaredScope, useSiteSession, scopeSession)
|
declaredMemberScopeDecorator(klass, declaredScope, useSiteSession, scopeSession)
|
||||||
|
|
||||||
|
val delegateFields = klass.declarations.filterIsInstance<FirField>().filter { it.isSynthetic }
|
||||||
val scopes = lookupSuperTypes(klass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession)
|
val scopes = lookupSuperTypes(klass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession)
|
||||||
.mapNotNull { useSiteSuperType ->
|
.mapNotNull { useSiteSuperType ->
|
||||||
if (useSiteSuperType is ConeClassErrorType) return@mapNotNull null
|
if (useSiteSuperType is ConeClassErrorType) return@mapNotNull null
|
||||||
val symbol = useSiteSuperType.lookupTag.toSymbol(useSiteSession)
|
val symbol = useSiteSuperType.lookupTag.toSymbol(useSiteSession)
|
||||||
if (symbol is FirRegularClassSymbol) {
|
if (symbol is FirRegularClassSymbol) {
|
||||||
|
val delegateField = delegateFields.find { it.returnTypeRef.coneType == useSiteSuperType }
|
||||||
symbol.fir.scope(
|
symbol.fir.scope(
|
||||||
substitutor(symbol, useSiteSuperType, useSiteSession),
|
substitutor(symbol, useSiteSuperType, useSiteSession),
|
||||||
useSiteSession, scopeSession,
|
useSiteSession, scopeSession, delegateField,
|
||||||
skipPrivateMembers = true,
|
skipPrivateMembers = true,
|
||||||
classId = klass.classId,
|
classId = klass.classId,
|
||||||
isFromExpectClass = (klass as? FirRegularClass)?.isExpect == true
|
isFromExpectClass = (klass as? FirRegularClass)?.isExpect == true
|
||||||
@@ -94,6 +95,8 @@ data class ConeSubstitutionScopeKey(
|
|||||||
val classId: ClassId?, val isFromExpectClass: Boolean, val substitutor: ConeSubstitutor
|
val classId: ClassId?, val isFromExpectClass: Boolean, val substitutor: ConeSubstitutor
|
||||||
) : ScopeSessionKey<FirClass<*>, FirClassSubstitutionScope>()
|
) : ScopeSessionKey<FirClass<*>, FirClassSubstitutionScope>()
|
||||||
|
|
||||||
|
data class DelegatedMemberScopeKey(val callableId: CallableId) : ScopeSessionKey<FirField, FirDelegatedMemberScope>()
|
||||||
|
|
||||||
fun FirClass<*>.unsubstitutedScope(useSiteSession: FirSession, scopeSession: ScopeSession): FirTypeScope {
|
fun FirClass<*>.unsubstitutedScope(useSiteSession: FirSession, scopeSession: ScopeSession): FirTypeScope {
|
||||||
return scopeProvider.getUseSiteMemberScope(this, useSiteSession, scopeSession)
|
return scopeProvider.getUseSiteMemberScope(this, useSiteSession, scopeSession)
|
||||||
}
|
}
|
||||||
@@ -102,13 +105,20 @@ internal fun FirClass<*>.scope(
|
|||||||
substitutor: ConeSubstitutor,
|
substitutor: ConeSubstitutor,
|
||||||
useSiteSession: FirSession,
|
useSiteSession: FirSession,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
|
delegateField: FirField? = null,
|
||||||
skipPrivateMembers: Boolean,
|
skipPrivateMembers: Boolean,
|
||||||
classId: ClassId? = this.classId,
|
classId: ClassId? = this.classId,
|
||||||
isFromExpectClass: Boolean = false
|
isFromExpectClass: Boolean = false
|
||||||
): FirTypeScope {
|
): FirTypeScope {
|
||||||
val basicScope = scopeProvider.getUseSiteMemberScope(
|
val basicScope = unsubstitutedScope(useSiteSession, scopeSession).let {
|
||||||
this, useSiteSession, scopeSession
|
if (delegateField != null) {
|
||||||
)
|
scopeSession.getOrBuild(delegateField, DelegatedMemberScopeKey(delegateField.symbol.callableId)) {
|
||||||
|
FirDelegatedMemberScope(it, useSiteSession)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
it
|
||||||
|
}
|
||||||
|
}
|
||||||
if (substitutor == ConeSubstitutor.Empty) return basicScope
|
if (substitutor == ConeSubstitutor.Empty) return basicScope
|
||||||
|
|
||||||
return scopeSession.getOrBuild(
|
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 Enhancement : FirDeclarationOrigin()
|
||||||
object ImportedFromObject : FirDeclarationOrigin()
|
object ImportedFromObject : FirDeclarationOrigin()
|
||||||
object IntersectionOverride : FirDeclarationOrigin()
|
object IntersectionOverride : FirDeclarationOrigin()
|
||||||
|
object Delegated : FirDeclarationOrigin()
|
||||||
|
|
||||||
class Plugin(val key: FirPluginKey) : FirDeclarationOrigin()
|
class Plugin(val key: FirPluginKey) : FirDeclarationOrigin()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user