[FE] Fix 'containingClassForStaticMemberAttr' for fake overrides (KTIJ-22808)
This commit is contained in:
+19
-5
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.*
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirSafe
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolver.AllCandidatesResolver
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry
|
||||
@@ -73,6 +74,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.shouldIjPlatformExceptionBeRethrown
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.withPsiEntry
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
|
||||
|
||||
internal class KtFirCallResolver(
|
||||
@@ -966,11 +968,23 @@ internal class KtFirCallResolver(
|
||||
psi: KtElement,
|
||||
resolveFragmentOfCall: Boolean
|
||||
): List<KtCallCandidateInfo> {
|
||||
val candidates = AllCandidatesResolver(analysisSession.useSiteSession).getAllCandidatesForDelegatedConstructor(
|
||||
analysisSession.firResolveSession,
|
||||
this,
|
||||
psi
|
||||
)
|
||||
fun findDerivedClass(psi: KtElement): KtClassOrObject? {
|
||||
val parent = psi.parent
|
||||
return when (psi) {
|
||||
is KtConstructorDelegationCall -> ((parent as? KtSecondaryConstructor)?.parent as? KtClassBody)?.parent as? KtClassOrObject
|
||||
is KtSuperTypeCallEntry -> (parent as? KtSuperTypeList)?.parent as? KtClassOrObject
|
||||
is KtConstructorCalleeExpression -> (parent as? KtElement)?.let(::findDerivedClass)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
val derivedClass = findDerivedClass(psi)
|
||||
?.getOrBuildFirSafe<FirClass>(firResolveSession)
|
||||
?: return emptyList()
|
||||
|
||||
val candidates = AllCandidatesResolver(analysisSession.useSiteSession)
|
||||
.getAllCandidatesForDelegatedConstructor(analysisSession.firResolveSession, this, derivedClass.symbol.toLookupTag(), psi)
|
||||
|
||||
return candidates.mapNotNull {
|
||||
convertToKtCallCandidateInfo(
|
||||
this,
|
||||
|
||||
+6
-4
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.tower.FirTowerResolver
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
@@ -71,6 +72,7 @@ class AllCandidatesResolver(private val firSession: FirSession) {
|
||||
fun getAllCandidatesForDelegatedConstructor(
|
||||
firResolveSession: LLFirResolveSession,
|
||||
delegatedConstructorCall: FirDelegatedConstructorCall,
|
||||
derivedClassLookupTag: ConeClassLikeLookupTag,
|
||||
element: KtElement
|
||||
): List<OverloadCandidate> {
|
||||
initializeBodyResolveContext(firResolveSession, element)
|
||||
@@ -78,10 +80,10 @@ class AllCandidatesResolver(private val firSession: FirSession) {
|
||||
val firFile = element.containingKtFile.getOrBuildFirFile(firResolveSession)
|
||||
val constructedType = delegatedConstructorCall.constructedTypeRef.coneType as ConeClassLikeType
|
||||
return bodyResolveComponents.context.withFile(firFile, bodyResolveComponents) {
|
||||
bodyResolveComponents.callResolver.resolveDelegatingConstructorCall(delegatedConstructorCall, constructedType)
|
||||
bodyResolveComponents.collector.allCandidates.map {
|
||||
OverloadCandidate(it, isInBestCandidates = it in bodyResolveComponents.collector.bestCandidates())
|
||||
}
|
||||
bodyResolveComponents.callResolver
|
||||
.resolveDelegatingConstructorCall(delegatedConstructorCall, constructedType, derivedClassLookupTag)
|
||||
bodyResolveComponents.collector.allCandidates
|
||||
.map { OverloadCandidate(it, isInBestCandidates = it in bodyResolveComponents.collector.bestCandidates()) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -356,11 +356,16 @@ internal tailrec fun FirCallableSymbol<*>.unwrapSubstitutionAndIntersectionOverr
|
||||
}
|
||||
|
||||
context(Fir2IrComponents)
|
||||
internal tailrec fun FirCallableSymbol<*>.unwrapCallRepresentative(root: FirCallableSymbol<*> = this): FirCallableSymbol<*> {
|
||||
internal tailrec fun FirCallableSymbol<*>.unwrapCallRepresentative(
|
||||
owner: ConeClassLikeLookupTag? = containingClassLookupTag()
|
||||
): FirCallableSymbol<*> {
|
||||
val fir = fir
|
||||
|
||||
if (fir is FirConstructor) {
|
||||
val originalForTypeAlias = fir.originalConstructorIfTypeAlias
|
||||
if (originalForTypeAlias != null) return originalForTypeAlias.symbol.unwrapCallRepresentative(this)
|
||||
if (originalForTypeAlias != null) {
|
||||
return originalForTypeAlias.symbol.unwrapCallRepresentative(owner)
|
||||
}
|
||||
}
|
||||
|
||||
if (fir.isIntersectionOverride) {
|
||||
@@ -370,17 +375,18 @@ internal tailrec fun FirCallableSymbol<*>.unwrapCallRepresentative(root: FirCall
|
||||
// interface C : A, B // for C.foo we've got an IR fake override
|
||||
// for {A & B} we don't have such an IR declaration, so we're unwrapping it
|
||||
if (fir.dispatchReceiverType is ConeIntersectionType) {
|
||||
return fir.baseForIntersectionOverride!!.symbol.unwrapCallRepresentative(this)
|
||||
return fir.baseForIntersectionOverride!!.symbol.unwrapCallRepresentative(owner)
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
val overriddenSymbol = fir.originalForSubstitutionOverride?.takeIf {
|
||||
it.containingClassLookupTag() == root.containingClassLookupTag()
|
||||
}?.symbol ?: return this
|
||||
val originalForOverride = fir.originalForSubstitutionOverride
|
||||
if (originalForOverride != null && originalForOverride.containingClassLookupTag() == owner) {
|
||||
return originalForOverride.symbol.unwrapCallRepresentative(owner)
|
||||
}
|
||||
|
||||
return overriddenSymbol.unwrapCallRepresentative(this)
|
||||
return this
|
||||
}
|
||||
|
||||
context(Fir2IrComponents)
|
||||
|
||||
+10
-1
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.backend.generators
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.fir.backend.*
|
||||
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
|
||||
@@ -22,6 +23,7 @@ import org.jetbrains.kotlin.fir.extensions.declarationGenerators
|
||||
import org.jetbrains.kotlin.fir.extensions.extensionService
|
||||
import org.jetbrains.kotlin.fir.extensions.generatedMembers
|
||||
import org.jetbrains.kotlin.fir.extensions.generatedNestedClassifiers
|
||||
import org.jetbrains.kotlin.fir.getOwnerLookupTag
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolvedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||
@@ -339,7 +341,14 @@ internal class ClassMemberGenerator(
|
||||
startOffset, endOffset, constructedIrType, "Cannot find delegated constructor call"
|
||||
)
|
||||
}
|
||||
val constructorSymbol = referencedSymbol.unwrapCallRepresentative() as FirConstructorSymbol
|
||||
|
||||
// Unwrap substitution overrides from both derived class and a super class
|
||||
val constructorSymbol = referencedSymbol
|
||||
.unwrapCallRepresentative(referencedSymbol.containingClassLookupTag())
|
||||
.unwrapCallRepresentative((referencedSymbol.resolvedReturnType as? ConeClassLikeType)?.lookupTag)
|
||||
|
||||
check(constructorSymbol is FirConstructorSymbol)
|
||||
|
||||
val firDispatchReceiver = dispatchReceiver
|
||||
return convertWithOffsets { startOffset, endOffset ->
|
||||
val irConstructorSymbol = declarationStorage.getIrFunctionSymbol(constructorSymbol) as IrConstructorSymbol
|
||||
|
||||
+7
-3
@@ -118,6 +118,7 @@ class FakeOverrideGenerator(
|
||||
val symbol = FirFakeOverrideGenerator.createSymbolForSubstitutionOverride(callableSymbol, firClass.symbol.classId)
|
||||
FirFakeOverrideGenerator.createSubstitutionOverrideFunction(
|
||||
session, symbol, firFunction,
|
||||
derivedClassLookupTag = firClass.symbol.toLookupTag(),
|
||||
newDispatchReceiverType = firClass.defaultType(),
|
||||
isExpect = (firClass as? FirRegularClass)?.isExpect == true
|
||||
)
|
||||
@@ -145,6 +146,7 @@ class FakeOverrideGenerator(
|
||||
FirFakeOverrideGenerator.createSymbolForSubstitutionOverride(callableSymbol, firClass.symbol.classId)
|
||||
FirFakeOverrideGenerator.createSubstitutionOverrideProperty(
|
||||
session, symbolForOverride, firProperty,
|
||||
derivedClassLookupTag = firClass.symbol.toLookupTag(),
|
||||
newDispatchReceiverType = firClass.defaultType(),
|
||||
isExpect = (firClass as? FirRegularClass)?.isExpect == true
|
||||
)
|
||||
@@ -169,11 +171,11 @@ class FakeOverrideGenerator(
|
||||
{ field, irParent, _, _, _ ->
|
||||
declarationStorage.createIrField(field, irParent)
|
||||
},
|
||||
createFakeOverrideSymbol = { firField, callableSymbol ->
|
||||
createFakeOverrideSymbol = { firField, _ ->
|
||||
FirFakeOverrideGenerator.createSubstitutionOverrideField(
|
||||
session, firField, callableSymbol,
|
||||
session, firField,
|
||||
derivedClassLookupTag = firClass.symbol.toLookupTag(),
|
||||
newReturnType = firField.returnTypeRef.coneType,
|
||||
derivedClassId = firClass.symbol.classId
|
||||
)
|
||||
},
|
||||
baseStaticFieldSymbols,
|
||||
@@ -324,6 +326,7 @@ class FakeOverrideGenerator(
|
||||
createFakeOverrideSymbol = { firFunction, callableSymbol ->
|
||||
FirFakeOverrideGenerator.createSubstitutionOverrideFunction(
|
||||
session, callableSymbol, firFunction,
|
||||
derivedClassLookupTag = klass.symbol.toLookupTag(),
|
||||
newDispatchReceiverType = klass.defaultType(),
|
||||
isExpect = (klass as? FirRegularClass)?.isExpect == true
|
||||
)
|
||||
@@ -342,6 +345,7 @@ class FakeOverrideGenerator(
|
||||
createFakeOverrideSymbol = { firProperty, callableSymbol ->
|
||||
FirFakeOverrideGenerator.createSubstitutionOverrideProperty(
|
||||
session, callableSymbol, firProperty,
|
||||
derivedClassLookupTag = klass.symbol.toLookupTag(),
|
||||
newDispatchReceiverType = klass.defaultType(),
|
||||
isExpect = (klass as? FirRegularClass)?.isExpect == true
|
||||
)
|
||||
|
||||
@@ -93,7 +93,7 @@ object JavaScopeProvider : FirScopeProvider() {
|
||||
)
|
||||
|
||||
val superTypeScopes = superTypes.mapNotNull {
|
||||
it.scopeForSupertype(useSiteSession, scopeSession, subClass = regularClass)
|
||||
it.scopeForSupertype(useSiteSession, scopeSession, regularClass)
|
||||
}
|
||||
|
||||
JavaClassUseSiteMemberScope(
|
||||
|
||||
@@ -81,6 +81,7 @@ private fun wrapSubstitutionScopeIfNeed(
|
||||
session, useSiteMemberScope, PLATFORM_TYPE_PARAMETERS_SUBSTITUTION_SCOPE_KEY, substitutor,
|
||||
dispatchReceiverTypeForSubstitutedMembers = derivedClass.defaultType(),
|
||||
skipPrivateMembers = true,
|
||||
derivedClassLookupTag = derivedClass.symbol.toLookupTag()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.scopes.jvm
|
||||
|
||||
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltInsSignatures
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.containingClassForStaticMemberAttr
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
||||
@@ -81,6 +80,7 @@ class JvmMappedScope(
|
||||
FirFakeOverrideGenerator.createCopyForFirFunction(
|
||||
newSymbol,
|
||||
baseFunction = symbol.fir,
|
||||
derivedClassLookupTag = firKotlinClass.symbol.toLookupTag(),
|
||||
session,
|
||||
symbol.fir.origin,
|
||||
newDispatchReceiverType = kotlinDispatchReceiverType,
|
||||
@@ -125,6 +125,7 @@ class JvmMappedScope(
|
||||
newSymbol,
|
||||
session,
|
||||
oldConstructor,
|
||||
derivedClassLookupTag = firKotlinClass.symbol.toLookupTag(),
|
||||
symbol.fir.origin,
|
||||
newDispatchReceiverType = null,
|
||||
newReturnType = substitutor.substituteOrSelf(oldConstructor.returnTypeRef.coneType),
|
||||
@@ -133,9 +134,7 @@ class JvmMappedScope(
|
||||
newContextReceiverTypes = emptyList(),
|
||||
isExpect = false,
|
||||
fakeOverrideSubstitution = null
|
||||
).apply {
|
||||
containingClassForStaticMemberAttr = firKotlinClass.symbol.toLookupTag()
|
||||
}
|
||||
)
|
||||
newSymbol
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirScopeWithFakeOverrideTypeCalculat
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.dynamicMembersStorage
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.getOrBuildScopeForIntegerConstantOperatorType
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
@@ -43,6 +44,14 @@ fun FirSmartCastExpression.smartcastScope(
|
||||
return FirUnstableSmartcastTypeScope(smartcastScope, originalScope)
|
||||
}
|
||||
|
||||
fun ConeClassLikeType.delegatingConstructorScope(
|
||||
useSiteSession: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
derivedClassLookupTag: ConeClassLikeLookupTag?
|
||||
): FirTypeScope? {
|
||||
return classScope(useSiteSession, scopeSession, FirResolvePhase.DECLARATIONS, derivedClassLookupTag)
|
||||
}
|
||||
|
||||
fun ConeKotlinType.scope(
|
||||
useSiteSession: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
@@ -56,23 +65,7 @@ fun ConeKotlinType.scope(
|
||||
private fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: ScopeSession, requiredPhase: FirResolvePhase): FirTypeScope? {
|
||||
return when (this) {
|
||||
is ConeErrorType -> null
|
||||
is ConeClassLikeType -> {
|
||||
val fullyExpandedType = fullyExpandedType(useSiteSession)
|
||||
val fir = fullyExpandedType.lookupTag.toSymbol(useSiteSession)?.fir as? FirClass ?: return null
|
||||
|
||||
fir.symbol.lazyResolveToPhase(requiredPhase)
|
||||
|
||||
val substitutor = when {
|
||||
attributes.contains(CompilerConeAttributes.RawType) -> ConeRawScopeSubstitutor(useSiteSession)
|
||||
else -> substitutorByMap(
|
||||
createSubstitution(fir.typeParameters, fullyExpandedType, useSiteSession),
|
||||
useSiteSession,
|
||||
)
|
||||
}
|
||||
|
||||
fir.scopeForClass(substitutor, useSiteSession, scopeSession)
|
||||
}
|
||||
|
||||
is ConeClassLikeType -> classScope(useSiteSession, scopeSession, requiredPhase, derivedClassLookupTag = null)
|
||||
is ConeTypeParameterType -> {
|
||||
val symbol = lookupTag.symbol
|
||||
scopeSession.getOrBuild(symbol, TYPE_PARAMETER_SCOPE_KEY) {
|
||||
@@ -103,6 +96,28 @@ private fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: Scope
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConeClassLikeType.classScope(
|
||||
useSiteSession: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
requiredPhase: FirResolvePhase,
|
||||
derivedClassLookupTag: ConeClassLikeLookupTag?
|
||||
): FirTypeScope? {
|
||||
val fullyExpandedType = fullyExpandedType(useSiteSession)
|
||||
val fir = fullyExpandedType.lookupTag.toSymbol(useSiteSession)?.fir as? FirClass ?: return null
|
||||
|
||||
fir.symbol.lazyResolveToPhase(requiredPhase)
|
||||
|
||||
val substitutor = when {
|
||||
attributes.contains(CompilerConeAttributes.RawType) -> ConeRawScopeSubstitutor(useSiteSession)
|
||||
else -> substitutorByMap(
|
||||
createSubstitution(fir.typeParameters, fullyExpandedType, useSiteSession),
|
||||
useSiteSession,
|
||||
)
|
||||
}
|
||||
|
||||
return fir.scopeForClass(substitutor, useSiteSession, scopeSession, derivedClassLookupTag)
|
||||
}
|
||||
|
||||
private fun ConeClassLikeType.obtainFirOfClass(useSiteSession: FirSession, requiredPhase: FirResolvePhase): FirClass? {
|
||||
val fullyExpandedType = fullyExpandedType(useSiteSession)
|
||||
val fir = fullyExpandedType.lookupTag.toSymbol(useSiteSession)?.fir as? FirClass ?: return null
|
||||
|
||||
+12
-7
@@ -107,19 +107,21 @@ fun FirClassSymbol<*>.unsubstitutedScope(
|
||||
fun FirClass.scopeForClass(
|
||||
substitutor: ConeSubstitutor,
|
||||
useSiteSession: FirSession,
|
||||
scopeSession: ScopeSession
|
||||
scopeSession: ScopeSession,
|
||||
derivedClassLookupTag: ConeClassLikeLookupTag?
|
||||
): FirTypeScope = scopeForClassImpl(
|
||||
substitutor, useSiteSession, scopeSession,
|
||||
skipPrivateMembers = false,
|
||||
classFirDispatchReceiver = this,
|
||||
// TODO: why it's always false?
|
||||
isFromExpectClass = false
|
||||
isFromExpectClass = false,
|
||||
derivedClassLookupTag = derivedClassLookupTag
|
||||
)
|
||||
|
||||
fun ConeKotlinType.scopeForSupertype(
|
||||
useSiteSession: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
subClass: FirClass,
|
||||
derivedClass: FirClass,
|
||||
): FirTypeScope? {
|
||||
if (this !is ConeClassLikeType) return null
|
||||
if (this is ConeErrorType) return null
|
||||
@@ -136,8 +138,9 @@ fun ConeKotlinType.scopeForSupertype(
|
||||
useSiteSession,
|
||||
scopeSession,
|
||||
skipPrivateMembers = true,
|
||||
classFirDispatchReceiver = subClass,
|
||||
isFromExpectClass = (subClass as? FirRegularClass)?.isExpect == true
|
||||
classFirDispatchReceiver = derivedClass,
|
||||
isFromExpectClass = (derivedClass as? FirRegularClass)?.isExpect == true,
|
||||
derivedClassLookupTag = derivedClass.symbol.toLookupTag()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -153,7 +156,8 @@ private fun FirClass.scopeForClassImpl(
|
||||
scopeSession: ScopeSession,
|
||||
skipPrivateMembers: Boolean,
|
||||
classFirDispatchReceiver: FirClass,
|
||||
isFromExpectClass: Boolean
|
||||
isFromExpectClass: Boolean,
|
||||
derivedClassLookupTag: ConeClassLikeLookupTag?
|
||||
): FirTypeScope {
|
||||
val basicScope = unsubstitutedScope(useSiteSession, scopeSession, withForcedTypeCalculator = false)
|
||||
if (substitutor == ConeSubstitutor.Empty) return basicScope
|
||||
@@ -168,7 +172,8 @@ private fun FirClass.scopeForClassImpl(
|
||||
key, substitutor,
|
||||
substitutor.substituteOrSelf(classFirDispatchReceiver.defaultType()).lowerBoundIfFlexible() as ConeClassLikeType,
|
||||
skipPrivateMembers,
|
||||
makeExpect = isFromExpectClass
|
||||
makeExpect = isFromExpectClass,
|
||||
derivedClassLookupTag ?: classFirDispatchReceiver.symbol.toLookupTag()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+10
-4
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.resolve.substitution.chain
|
||||
import org.jetbrains.kotlin.fir.scopes.FakeOverrideSubstitution
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
@@ -34,7 +35,8 @@ class FirClassSubstitutionScope(
|
||||
private val substitutor: ConeSubstitutor,
|
||||
private val dispatchReceiverTypeForSubstitutedMembers: ConeClassLikeType,
|
||||
private val skipPrivateMembers: Boolean,
|
||||
private val makeExpect: Boolean = false
|
||||
private val makeExpect: Boolean = false,
|
||||
private val derivedClassLookupTag: ConeClassLikeLookupTag
|
||||
) : FirTypeScope() {
|
||||
|
||||
private val substitutionOverrideCache = session.substitutionOverrideStorage.substitutionOverrideCacheByScope.getValue(key, null)
|
||||
@@ -142,6 +144,7 @@ class FirClassSubstitutionScope(
|
||||
session,
|
||||
symbolForOverride,
|
||||
member,
|
||||
derivedClassLookupTag = derivedClassLookupTag,
|
||||
newDispatchReceiverType ?: dispatchReceiverTypeForSubstitutedMembers,
|
||||
isExpect = makeExpect,
|
||||
)
|
||||
@@ -158,6 +161,7 @@ class FirClassSubstitutionScope(
|
||||
session,
|
||||
symbolForOverride,
|
||||
member,
|
||||
derivedClassLookupTag,
|
||||
newDispatchReceiverType ?: dispatchReceiverTypeForSubstitutedMembers,
|
||||
newReceiverType,
|
||||
newContextReceiverTypes,
|
||||
@@ -202,6 +206,7 @@ class FirClassSubstitutionScope(
|
||||
symbolForOverride,
|
||||
session,
|
||||
constructor,
|
||||
derivedClassLookupTag,
|
||||
FirDeclarationOrigin.SubstitutionOverride,
|
||||
newDispatchReceiverType,
|
||||
// Constructors' return types are expected to be non-flexible (i.e., non raw)
|
||||
@@ -240,6 +245,7 @@ class FirClassSubstitutionScope(
|
||||
session,
|
||||
symbolForOverride,
|
||||
member,
|
||||
derivedClassLookupTag = derivedClassLookupTag,
|
||||
newDispatchReceiverType ?: dispatchReceiverTypeForSubstitutedMembers,
|
||||
isExpect = makeExpect,
|
||||
)
|
||||
@@ -252,6 +258,7 @@ class FirClassSubstitutionScope(
|
||||
session,
|
||||
symbolForOverride,
|
||||
member,
|
||||
derivedClassLookupTag,
|
||||
newDispatchReceiverType ?: dispatchReceiverTypeForSubstitutedMembers,
|
||||
newReceiverType,
|
||||
newContextReceiverTypes,
|
||||
@@ -310,9 +317,7 @@ class FirClassSubstitutionScope(
|
||||
// TODO: do we have fields with implicit type?
|
||||
val newReturnType = returnType?.substitute() ?: return original
|
||||
|
||||
return FirFakeOverrideGenerator.createSubstitutionOverrideField(
|
||||
session, member, original, newReturnType, newOwnerClassId
|
||||
)
|
||||
return FirFakeOverrideGenerator.createSubstitutionOverrideField(session, member, derivedClassLookupTag, newReturnType)
|
||||
}
|
||||
|
||||
fun createSubstitutionOverrideSyntheticProperty(original: FirSyntheticPropertySymbol): FirSyntheticPropertySymbol {
|
||||
@@ -347,6 +352,7 @@ class FirClassSubstitutionScope(
|
||||
return FirFakeOverrideGenerator.createSubstitutionOverrideSyntheticProperty(
|
||||
session,
|
||||
member,
|
||||
derivedClassLookupTag,
|
||||
original,
|
||||
substitutor.substituteOrSelf(dispatchReceiverTypeForSubstitutedMembers) as ConeSimpleKotlinType?,
|
||||
newContextReceiverTypes,
|
||||
|
||||
+2
@@ -92,6 +92,7 @@ class FirDelegatedMemberScope(
|
||||
functionSymbol.callableId,
|
||||
),
|
||||
original,
|
||||
derivedClassLookupTag = null,
|
||||
session,
|
||||
FirDeclarationOrigin.Delegated,
|
||||
newDispatchReceiverType = dispatchReceiverType,
|
||||
@@ -161,6 +162,7 @@ class FirDelegatedMemberScope(
|
||||
propertySymbol.callableId
|
||||
),
|
||||
original,
|
||||
derivedClassLookupTag = null,
|
||||
session,
|
||||
FirDeclarationOrigin.Delegated,
|
||||
newModality = Modality.OPEN,
|
||||
|
||||
+32
-19
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.scopes.FakeOverrideSubstitution
|
||||
import org.jetbrains.kotlin.fir.scopes.fakeOverrideSubstitution
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
@@ -36,6 +37,7 @@ object FirFakeOverrideGenerator {
|
||||
session: FirSession,
|
||||
symbolForSubstitutionOverride: FirNamedFunctionSymbol,
|
||||
baseFunction: FirSimpleFunction,
|
||||
derivedClassLookupTag: ConeClassLikeLookupTag?,
|
||||
newDispatchReceiverType: ConeSimpleKotlinType?,
|
||||
newReceiverType: ConeKotlinType? = null,
|
||||
newContextReceiverTypes: List<ConeKotlinType?>? = null,
|
||||
@@ -46,8 +48,8 @@ object FirFakeOverrideGenerator {
|
||||
fakeOverrideSubstitution: FakeOverrideSubstitution? = null
|
||||
): FirNamedFunctionSymbol {
|
||||
createSubstitutionOverrideFunction(
|
||||
symbolForSubstitutionOverride, session, baseFunction, newDispatchReceiverType, newReceiverType, newContextReceiverTypes,
|
||||
newReturnType, newParameterTypes, newTypeParameters, isExpect, fakeOverrideSubstitution
|
||||
symbolForSubstitutionOverride, session, baseFunction, derivedClassLookupTag, newDispatchReceiverType, newReceiverType,
|
||||
newContextReceiverTypes, newReturnType, newParameterTypes, newTypeParameters, isExpect, fakeOverrideSubstitution
|
||||
)
|
||||
return symbolForSubstitutionOverride
|
||||
}
|
||||
@@ -64,6 +66,7 @@ object FirFakeOverrideGenerator {
|
||||
fakeOverrideSymbol: FirNamedFunctionSymbol,
|
||||
session: FirSession,
|
||||
baseFunction: FirSimpleFunction,
|
||||
derivedClassLookupTag: ConeClassLikeLookupTag?,
|
||||
newDispatchReceiverType: ConeSimpleKotlinType?,
|
||||
newReceiverType: ConeKotlinType?,
|
||||
newContextReceiverTypes: List<ConeKotlinType?>?,
|
||||
@@ -78,6 +81,7 @@ object FirFakeOverrideGenerator {
|
||||
return createCopyForFirFunction(
|
||||
fakeOverrideSymbol,
|
||||
baseFunction,
|
||||
derivedClassLookupTag = derivedClassLookupTag,
|
||||
session,
|
||||
FirDeclarationOrigin.SubstitutionOverride,
|
||||
isExpect,
|
||||
@@ -90,15 +94,13 @@ object FirFakeOverrideGenerator {
|
||||
fakeOverrideSubstitution = fakeOverrideSubstitution
|
||||
).apply {
|
||||
originalForSubstitutionOverrideAttr = baseFunction
|
||||
if (isStatic) {
|
||||
containingClassForStaticMemberAttr = (newDispatchReceiverType as? ConeClassLikeType)?.lookupTag
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun createCopyForFirFunction(
|
||||
newSymbol: FirNamedFunctionSymbol,
|
||||
baseFunction: FirSimpleFunction,
|
||||
derivedClassLookupTag: ConeClassLikeLookupTag?,
|
||||
session: FirSession,
|
||||
origin: FirDeclarationOrigin,
|
||||
isExpect: Boolean = baseFunction.isExpect,
|
||||
@@ -128,6 +130,8 @@ object FirFakeOverrideGenerator {
|
||||
newReceiverType, newContextReceiverTypes, newReturnType, fakeOverrideSubstitution, newSymbol
|
||||
).filterIsInstance<FirTypeParameter>()
|
||||
deprecationsProvider = baseFunction.deprecationsProvider
|
||||
}.apply {
|
||||
containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseFunction) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,6 +139,7 @@ object FirFakeOverrideGenerator {
|
||||
fakeOverrideSymbol: FirConstructorSymbol,
|
||||
session: FirSession,
|
||||
baseConstructor: FirConstructor,
|
||||
derivedClassLookupTag: ConeClassLikeLookupTag?,
|
||||
origin: FirDeclarationOrigin,
|
||||
newDispatchReceiverType: ConeSimpleKotlinType?,
|
||||
newReturnType: ConeKotlinType?,
|
||||
@@ -179,6 +184,7 @@ object FirFakeOverrideGenerator {
|
||||
deprecationsProvider = baseConstructor.deprecationsProvider
|
||||
}.apply {
|
||||
originalForSubstitutionOverrideAttr = baseConstructor
|
||||
containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseConstructor) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,6 +309,7 @@ object FirFakeOverrideGenerator {
|
||||
session: FirSession,
|
||||
symbolForSubstitutionOverride: FirPropertySymbol,
|
||||
baseProperty: FirProperty,
|
||||
derivedClassLookupTag: ConeClassLikeLookupTag,
|
||||
newDispatchReceiverType: ConeSimpleKotlinType?,
|
||||
newReceiverType: ConeKotlinType? = null,
|
||||
newContextReceiverTypes: List<ConeKotlinType?>? = null,
|
||||
@@ -312,14 +319,11 @@ object FirFakeOverrideGenerator {
|
||||
fakeOverrideSubstitution: FakeOverrideSubstitution? = null
|
||||
): FirPropertySymbol {
|
||||
createCopyForFirProperty(
|
||||
symbolForSubstitutionOverride, baseProperty, session, FirDeclarationOrigin.SubstitutionOverride, isExpect,
|
||||
newDispatchReceiverType, newTypeParameters, newReceiverType, newContextReceiverTypes, newReturnType,
|
||||
symbolForSubstitutionOverride, baseProperty, derivedClassLookupTag, session, FirDeclarationOrigin.SubstitutionOverride,
|
||||
isExpect, newDispatchReceiverType, newTypeParameters, newReceiverType, newContextReceiverTypes, newReturnType,
|
||||
fakeOverrideSubstitution = fakeOverrideSubstitution
|
||||
).apply {
|
||||
originalForSubstitutionOverrideAttr = baseProperty
|
||||
if (isStatic) {
|
||||
containingClassForStaticMemberAttr = (newDispatchReceiverType as? ConeClassLikeType)?.lookupTag
|
||||
}
|
||||
}
|
||||
return symbolForSubstitutionOverride
|
||||
}
|
||||
@@ -335,6 +339,7 @@ object FirFakeOverrideGenerator {
|
||||
fun createCopyForFirProperty(
|
||||
newSymbol: FirPropertySymbol,
|
||||
baseProperty: FirProperty,
|
||||
derivedClassLookupTag: ConeClassLikeLookupTag?,
|
||||
session: FirSession,
|
||||
origin: FirDeclarationOrigin,
|
||||
isExpect: Boolean = baseProperty.isExpect,
|
||||
@@ -370,6 +375,8 @@ object FirFakeOverrideGenerator {
|
||||
fakeOverrideSubstitution
|
||||
)
|
||||
deprecationsProvider = baseProperty.deprecationsProvider
|
||||
}.apply {
|
||||
containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseProperty) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,13 +492,10 @@ object FirFakeOverrideGenerator {
|
||||
fun createSubstitutionOverrideField(
|
||||
session: FirSession,
|
||||
baseField: FirField,
|
||||
baseSymbol: FirFieldSymbol,
|
||||
newReturnType: ConeKotlinType?,
|
||||
derivedClassId: ClassId?
|
||||
derivedClassLookupTag: ConeClassLikeLookupTag,
|
||||
newReturnType: ConeKotlinType?
|
||||
): FirFieldSymbol {
|
||||
val symbol = FirFieldSymbol(
|
||||
CallableId(derivedClassId ?: baseSymbol.callableId.classId!!, baseField.name)
|
||||
)
|
||||
val symbol = FirFieldSymbol(CallableId(derivedClassLookupTag.classId, baseField.name))
|
||||
buildField {
|
||||
moduleData = session.moduleData
|
||||
this.symbol = symbol
|
||||
@@ -509,9 +513,7 @@ object FirFakeOverrideGenerator {
|
||||
dispatchReceiverType = baseField.dispatchReceiverType
|
||||
}.apply {
|
||||
originalForSubstitutionOverrideAttr = baseField
|
||||
if (isStatic && derivedClassId != null) {
|
||||
containingClassForStaticMemberAttr = ConeClassLikeLookupTagImpl(derivedClassId)
|
||||
}
|
||||
containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseField) }
|
||||
}
|
||||
return symbol
|
||||
}
|
||||
@@ -519,6 +521,7 @@ object FirFakeOverrideGenerator {
|
||||
fun createSubstitutionOverrideSyntheticProperty(
|
||||
session: FirSession,
|
||||
baseProperty: FirSyntheticProperty,
|
||||
derivedClassLookupTag: ConeClassLikeLookupTag,
|
||||
baseSymbol: FirSyntheticPropertySymbol,
|
||||
newDispatchReceiverType: ConeSimpleKotlinType?,
|
||||
newContextReceiverTypes: List<ConeKotlinType?>?,
|
||||
@@ -532,6 +535,7 @@ object FirFakeOverrideGenerator {
|
||||
getterSymbol,
|
||||
session,
|
||||
baseProperty.getter.delegate,
|
||||
derivedClassLookupTag,
|
||||
newDispatchReceiverType,
|
||||
newReceiverType = null,
|
||||
newContextReceiverTypes,
|
||||
@@ -546,6 +550,7 @@ object FirFakeOverrideGenerator {
|
||||
setterSymbol,
|
||||
session,
|
||||
baseSetter.delegate,
|
||||
derivedClassLookupTag,
|
||||
newDispatchReceiverType,
|
||||
newReceiverType = null,
|
||||
newContextReceiverTypes,
|
||||
@@ -562,6 +567,8 @@ object FirFakeOverrideGenerator {
|
||||
delegateSetter = setter
|
||||
status = baseProperty.status
|
||||
deprecationsProvider = getDeprecationsProviderFromAccessors(getter, setter, session.firCachesFactory)
|
||||
}.apply {
|
||||
containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseProperty) }
|
||||
}.symbol
|
||||
}
|
||||
|
||||
@@ -620,6 +627,12 @@ object FirFakeOverrideGenerator {
|
||||
)
|
||||
}
|
||||
|
||||
private fun shouldOverrideSetContainingClass(baseDeclaration: FirCallableDeclaration): Boolean {
|
||||
return baseDeclaration is FirConstructor
|
||||
|| baseDeclaration.isStatic
|
||||
|| baseDeclaration.containingClassForStaticMemberAttr != null
|
||||
}
|
||||
|
||||
private sealed class Maybe<out A> {
|
||||
class Value<out A>(val value: A) : Maybe<A>()
|
||||
object Nothing : Maybe<kotlin.Nothing>()
|
||||
|
||||
+5
-2
@@ -361,7 +361,9 @@ class FirTypeIntersectionScopeContext(
|
||||
)
|
||||
val newSymbol = FirIntersectionOverrideFunctionSymbol(callableId, overrides)
|
||||
FirFakeOverrideGenerator.createCopyForFirFunction(
|
||||
newSymbol, keyFir, session, FirDeclarationOrigin.IntersectionOverride, keyFir.isExpect,
|
||||
newSymbol, keyFir,
|
||||
derivedClassLookupTag = null,
|
||||
session, FirDeclarationOrigin.IntersectionOverride, keyFir.isExpect,
|
||||
newModality = newModality,
|
||||
newVisibility = newVisibility,
|
||||
newDispatchReceiverType = dispatchReceiverType,
|
||||
@@ -386,7 +388,8 @@ class FirTypeIntersectionScopeContext(
|
||||
)
|
||||
val newSymbol = FirIntersectionOverridePropertySymbol(callableId, overrides)
|
||||
FirFakeOverrideGenerator.createCopyForFirProperty(
|
||||
newSymbol, keyFir, session, FirDeclarationOrigin.IntersectionOverride,
|
||||
newSymbol, keyFir, derivedClassLookupTag = null, session,
|
||||
FirDeclarationOrigin.IntersectionOverride,
|
||||
newModality = newModality,
|
||||
newVisibility = newVisibility,
|
||||
newDispatchReceiverType = dispatchReceiverType,
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBod
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
@@ -470,7 +471,8 @@ class FirCallResolver(
|
||||
|
||||
fun resolveDelegatingConstructorCall(
|
||||
delegatedConstructorCall: FirDelegatedConstructorCall,
|
||||
constructedType: ConeClassLikeType?
|
||||
constructedType: ConeClassLikeType?,
|
||||
derivedClassLookupTag: ConeClassLikeLookupTag
|
||||
): FirDelegatedConstructorCall {
|
||||
val name = SpecialNames.INIT
|
||||
val symbol = constructedType?.lookupTag?.toSymbol(components.session)
|
||||
@@ -507,6 +509,7 @@ class FirCallResolver(
|
||||
val result = towerResolver.runResolverForDelegatingConstructor(
|
||||
callInfo,
|
||||
constructedType,
|
||||
derivedClassLookupTag,
|
||||
transformer.resolutionContext
|
||||
)
|
||||
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ class FirDefaultParametersResolver : FirSessionComponent {
|
||||
// imported from object case
|
||||
is FirAbstractImportingScope -> {
|
||||
val containingClass = function.getContainingClass(session) ?: return false
|
||||
containingClass.scopeForClass(ConeSubstitutor.Empty, session, scopeSession)
|
||||
containingClass.scopeForClass(ConeSubstitutor.Empty, session, scopeSession, derivedClassLookupTag = null)
|
||||
}
|
||||
else -> return false
|
||||
}
|
||||
|
||||
+10
-4
@@ -209,6 +209,7 @@ private fun FirTypeAliasSymbol.findSAMConstructorForTypeAlias(
|
||||
|
||||
return FirFakeOverrideGenerator.createSubstitutionOverrideFunction(
|
||||
session, symbolForOverride, samConstructorForClass,
|
||||
derivedClassLookupTag = null,
|
||||
newDispatchReceiverType = null,
|
||||
newReceiverType = null,
|
||||
newContextReceiverTypes,
|
||||
@@ -262,10 +263,15 @@ private fun processConstructors(
|
||||
}
|
||||
is FirClassSymbol -> {
|
||||
val firClass = matchedSymbol.fir as FirClass
|
||||
if (firClass.classKind == ClassKind.INTERFACE) null
|
||||
else firClass.scopeForClass(
|
||||
substitutor, session, bodyResolveComponents.scopeSession
|
||||
)
|
||||
when (firClass.classKind) {
|
||||
ClassKind.INTERFACE -> null
|
||||
else -> firClass.scopeForClass(
|
||||
substitutor,
|
||||
session,
|
||||
bodyResolveComponents.scopeSession,
|
||||
derivedClassLookupTag = null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -10,8 +10,8 @@ import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||
import org.jetbrains.kotlin.fir.resolve.scope
|
||||
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
|
||||
import org.jetbrains.kotlin.fir.resolve.delegatingConstructorScope
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.typeContext
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
@@ -91,10 +91,12 @@ class FirTowerResolver(
|
||||
fun runResolverForDelegatingConstructor(
|
||||
info: CallInfo,
|
||||
constructedType: ConeClassLikeType,
|
||||
derivedClassLookupTag: ConeClassLikeLookupTag,
|
||||
context: ResolutionContext
|
||||
): CandidateCollector {
|
||||
val outerType = components.outerClassManager.outerType(constructedType)
|
||||
val scope = constructedType.scope(components.session, components.scopeSession, FakeOverrideTypeCalculator.DoNothing) ?: return collector
|
||||
val scope = constructedType.delegatingConstructorScope(components.session, components.scopeSession, derivedClassLookupTag)
|
||||
?: return collector
|
||||
|
||||
val dispatchReceiver =
|
||||
if (outerType != null)
|
||||
|
||||
+3
-1
@@ -1144,7 +1144,9 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
||||
else -> null
|
||||
}
|
||||
|
||||
val resolvedCall = callResolver.resolveDelegatingConstructorCall(delegatedConstructorCall, constructorType)
|
||||
val resolvedCall = callResolver
|
||||
.resolveDelegatingConstructorCall(delegatedConstructorCall, constructorType, containingClass.symbol.toLookupTag())
|
||||
|
||||
if (reference is FirThisReference && reference.boundSymbol == null) {
|
||||
resolvedCall.dispatchReceiver.typeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag?.toSymbol(session)?.let {
|
||||
reference.replaceBoundSymbol(it)
|
||||
|
||||
Reference in New Issue
Block a user