K2 resolve: prefer derived class property to base class field
#KT-50082 Fixed
This commit is contained in:
committed by
teamcity
parent
642bbd38ba
commit
59bafedd8a
@@ -194,7 +194,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
||||
if (isStatic && containingClass != null) {
|
||||
containingUseSiteDeclarations.firstNotNullOfOrNull {
|
||||
if (it !is FirClass) return@firstNotNullOfOrNull null
|
||||
it.takeIf { it.isSubClass(containingLookupTag, session, supertypeSupplier) }
|
||||
it.takeIf { it.isSubclassOf(containingLookupTag, session, isStrict = false, supertypeSupplier) }
|
||||
}?.let { return it }
|
||||
}
|
||||
|
||||
@@ -380,10 +380,6 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
||||
return false
|
||||
}
|
||||
|
||||
// 'local' isn't taken into account here
|
||||
private fun ClassId.isSame(other: ClassId): Boolean =
|
||||
packageFqName == other.packageFqName && relativeClassName == other.relativeClassName
|
||||
|
||||
private fun ConeClassLikeLookupTag.ownerIfCompanion(session: FirSession): ConeClassLikeLookupTag? {
|
||||
if (classId.isLocal) return null
|
||||
val outerClassId = classId.outerClassId ?: return null
|
||||
@@ -405,11 +401,11 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
||||
supertypeSupplier: SupertypeSupplier
|
||||
): Boolean {
|
||||
dispatchReceiver?.ownerIfCompanion(session)?.let { companionOwnerLookupTag ->
|
||||
if (containingUseSiteClass.isSubClass(companionOwnerLookupTag, session, supertypeSupplier)) return true
|
||||
if (containingUseSiteClass.isSubclassOf(companionOwnerLookupTag, session, isStrict = false, supertypeSupplier)) return true
|
||||
}
|
||||
|
||||
return when {
|
||||
!containingUseSiteClass.isSubClass(ownerLookupTag, session, supertypeSupplier) -> false
|
||||
!containingUseSiteClass.isSubclassOf(ownerLookupTag, session, isStrict = false, supertypeSupplier) -> false
|
||||
isVariableOrNamedFunction -> doesReceiverFitForProtectedVisibility(
|
||||
dispatchReceiver,
|
||||
containingUseSiteClass,
|
||||
@@ -460,26 +456,6 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
||||
return false
|
||||
}
|
||||
|
||||
private fun FirClass.isSubClass(
|
||||
ownerLookupTag: ConeClassLikeLookupTag,
|
||||
session: FirSession,
|
||||
supertypeSupplier: SupertypeSupplier
|
||||
): Boolean {
|
||||
if (classId.isSame(ownerLookupTag.classId)) return true
|
||||
|
||||
return lookupSuperTypes(
|
||||
this,
|
||||
lookupInterfaces = true,
|
||||
deep = true,
|
||||
session,
|
||||
substituteTypes = false,
|
||||
supertypeSupplier
|
||||
).any { superType ->
|
||||
// Note: We check just classId here, so type substitution isn't needed ^ (we aren't interested in type arguments)
|
||||
(superType as? ConeClassLikeType)?.fullyExpandedType(session)?.lookupTag?.classId?.isSame(ownerLookupTag.classId) == true
|
||||
}
|
||||
}
|
||||
|
||||
private fun ReceiverValue?.ownerIfCompanion(session: FirSession): ConeClassLikeLookupTag? =
|
||||
(this?.type as? ConeClassLikeType)?.lookupTag?.ownerIfCompanion(session)
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.expandedConeType
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
|
||||
@@ -21,6 +22,7 @@ import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.types.model.CaptureStatus
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.kotlin.utils.SmartSet
|
||||
@@ -90,6 +92,33 @@ fun lookupSuperTypes(
|
||||
}
|
||||
}
|
||||
|
||||
fun FirClass.isSubclassOf(
|
||||
ownerLookupTag: ConeClassLikeLookupTag,
|
||||
session: FirSession,
|
||||
isStrict: Boolean,
|
||||
supertypeSupplier: SupertypeSupplier = SupertypeSupplier.Default
|
||||
): Boolean {
|
||||
if (classId.isSame(ownerLookupTag.classId)) {
|
||||
return !isStrict
|
||||
}
|
||||
|
||||
return lookupSuperTypes(
|
||||
this,
|
||||
lookupInterfaces = true,
|
||||
deep = true,
|
||||
session,
|
||||
substituteTypes = false,
|
||||
supertypeSupplier
|
||||
).any { superType ->
|
||||
// Note: We check just classId here, so type substitution isn't needed
|
||||
superType.lookupTag.classId.isSame(ownerLookupTag.classId)
|
||||
}
|
||||
}
|
||||
|
||||
// 'local' isn't taken into account here
|
||||
fun ClassId.isSame(other: ClassId): Boolean =
|
||||
packageFqName == other.packageFqName && relativeClassName == other.relativeClassName
|
||||
|
||||
fun FirClass.isThereLoopInSupertypes(session: FirSession): Boolean {
|
||||
val visitedSymbols: MutableSet<FirClassifierSymbol<*>> = SmartSet.create()
|
||||
val inProcess: MutableSet<FirClassifierSymbol<*>> = mutableSetOf()
|
||||
|
||||
Reference in New Issue
Block a user