[FE] Fix 'containingClassForStaticMemberAttr' for fake overrides (KTIJ-22808)

This commit is contained in:
Yan Zhulanow
2022-10-24 15:35:38 +09:00
committed by Space Team
parent 2e9f9f987b
commit fe69b21aed
19 changed files with 176 additions and 84 deletions
@@ -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,
@@ -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)
@@ -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
@@ -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
@@ -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()
)
}
}
@@ -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,
@@ -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,
@@ -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>()
@@ -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
)
@@ -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
}
@@ -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
)
}
}
}
@@ -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)
@@ -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)