[FIR] Use SupertypeSupplier in type resolver for calculating supertypes

This is needed to avoid problems with checking visibility of types which
  are used in supertypes during supertypes resolution in IDE, when
  supertypes of some class can be already computed, but not saved in
  class itself, but still lay in supertypeComputationSession

There were 4 failing tests before this changes (all in
  `DiagnosisCompilerTestFE10TestdataTestGenerated$Tests$Exposed`):
- testInternal
- testInternalAndProtected
- testProtected
- testProtectedSameWay
This commit is contained in:
Dmitriy Novozhilov
2021-11-16 10:43:10 +03:00
committed by TeamCityServer
parent 499b97d51e
commit e7c9d76163
6 changed files with 52 additions and 18 deletions
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.resolve.SupertypeSupplier
import org.jetbrains.kotlin.fir.resolve.calls.FirSimpleSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.resolve.calls.ReceiverValue
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
@@ -30,6 +31,7 @@ object FirJavaVisibilityChecker : FirVisibilityChecker() {
dispatchReceiver: ReceiverValue?,
session: FirSession,
isCallToPropertySetter: Boolean,
supertypeSupplier: SupertypeSupplier
): Boolean {
return when (declarationVisibility) {
JavaVisibilities.ProtectedAndPackage, JavaVisibilities.ProtectedStaticVisibility -> {
@@ -40,7 +42,8 @@ object FirJavaVisibilityChecker : FirVisibilityChecker() {
if (canSeeProtectedMemberOf(
containingDeclarations, dispatchReceiver, ownerLookupTag, session,
isVariableOrNamedFunction = symbol is FirVariableSymbol || symbol is FirNamedFunctionSymbol || symbol is FirPropertyAccessorSymbol,
isSyntheticProperty = symbol.fir is FirSyntheticPropertyAccessor
isSyntheticProperty = symbol.fir is FirSyntheticPropertyAccessor,
supertypeSupplier
)
) return true
@@ -50,6 +50,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
dispatchReceiver: ReceiverValue?,
session: FirSession,
isCallToPropertySetter: Boolean,
supertypeSupplier: SupertypeSupplier
): Boolean {
return true
}
@@ -67,6 +68,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
// Such flag is not necessary in FE1.0, since there are full structure of fake overrides and containing declaration for overridden
// is always visible since it's a supertype of a derived class.
skipCheckForContainingClassVisibility: Boolean = false,
supertypeSupplier: SupertypeSupplier = SupertypeSupplier.Default
): Boolean {
if (!isSpecificDeclarationVisible(
declaration,
@@ -74,7 +76,8 @@ abstract class FirVisibilityChecker : FirSessionComponent {
useSiteFile,
containingDeclarations,
dispatchReceiver,
isCallToPropertySetter
isCallToPropertySetter,
supertypeSupplier
)
) {
return false
@@ -90,7 +93,8 @@ abstract class FirVisibilityChecker : FirSessionComponent {
useSiteFile,
containingDeclarations,
dispatchReceiver,
isCallToPropertySetter
isCallToPropertySetter,
supertypeSupplier
)
}
}
@@ -132,6 +136,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
containingDeclarations: List<FirDeclaration>,
dispatchReceiver: ReceiverValue?,
isCallToPropertySetter: Boolean = false,
supertypeSupplier: SupertypeSupplier
): Boolean {
val symbol = declaration.symbol
val provider = session.firProvider
@@ -176,7 +181,8 @@ abstract class FirVisibilityChecker : FirSessionComponent {
ownerId != null && canSeeProtectedMemberOf(
containingDeclarations, dispatchReceiver, ownerId, session,
isVariableOrNamedFunction = symbol is FirVariableSymbol || symbol is FirNamedFunctionSymbol || symbol is FirPropertyAccessorSymbol,
symbol.fir is FirSyntheticPropertyAccessor
symbol.fir is FirSyntheticPropertyAccessor,
supertypeSupplier
)
}
@@ -188,6 +194,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
dispatchReceiver,
session,
isCallToPropertySetter,
supertypeSupplier
)
}
}
@@ -200,6 +207,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
dispatchReceiver: ReceiverValue?,
session: FirSession,
isCallToPropertySetter: Boolean,
supertypeSupplier: SupertypeSupplier
): Boolean
private fun canSeePrivateMemberOf(
@@ -243,14 +251,15 @@ abstract class FirVisibilityChecker : FirSessionComponent {
ownerLookupTag: ConeClassLikeLookupTag,
session: FirSession,
isVariableOrNamedFunction: Boolean,
isSyntheticProperty: Boolean
isSyntheticProperty: Boolean,
supertypeSupplier: SupertypeSupplier
): Boolean {
dispatchReceiver?.ownerIfCompanion(session)?.let { companionOwnerLookupTag ->
if (containingUseSiteClass.isSubClass(companionOwnerLookupTag, session)) return true
if (containingUseSiteClass.isSubClass(companionOwnerLookupTag, session, supertypeSupplier)) return true
}
return when {
!containingUseSiteClass.isSubClass(ownerLookupTag, session) -> false
!containingUseSiteClass.isSubClass(ownerLookupTag, session, supertypeSupplier) -> false
isVariableOrNamedFunction -> doesReceiverFitForProtectedVisibility(
dispatchReceiver,
containingUseSiteClass,
@@ -299,10 +308,21 @@ abstract class FirVisibilityChecker : FirSessionComponent {
return false
}
private fun FirClass.isSubClass(ownerLookupTag: ConeClassLikeLookupTag, session: FirSession): Boolean {
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).any { superType ->
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
}
@@ -327,7 +347,8 @@ abstract class FirVisibilityChecker : FirSessionComponent {
ownerLookupTag: ConeClassLikeLookupTag,
session: FirSession,
isVariableOrNamedFunction: Boolean,
isSyntheticProperty: Boolean
isSyntheticProperty: Boolean,
supertypeSupplier: SupertypeSupplier
): Boolean {
if (canSeePrivateMemberOf(containingDeclarationOfUseSite, ownerLookupTag, session)) return true
@@ -340,7 +361,8 @@ abstract class FirVisibilityChecker : FirSessionComponent {
ownerLookupTag,
session,
isVariableOrNamedFunction,
isSyntheticProperty
isSyntheticProperty,
supertypeSupplier
)
) return true
} else if (containingDeclaration is FirFile) {
@@ -18,7 +18,8 @@ abstract class FirTypeResolver : FirSessionComponent {
scopeClassDeclaration: ScopeClassDeclaration,
areBareTypesAllowed: Boolean,
isOperandOfIsOperator: Boolean,
useSiteFile: FirFile?
useSiteFile: FirFile?,
supertypeSupplier: SupertypeSupplier
): ConeKotlinType
}
@@ -78,6 +78,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
private fun FirBasedSymbol<*>?.isVisible(
useSiteFile: FirFile?,
containingDeclarations: List<FirDeclaration>,
supertypeSupplier: SupertypeSupplier
): Boolean {
val declaration = this?.fir
return if (useSiteFile != null && declaration is FirMemberDeclaration) {
@@ -86,8 +87,9 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
session,
useSiteFile,
containingDeclarations,
null,
false,
dispatchReceiver = null,
isCallToPropertySetter = false,
supertypeSupplier = supertypeSupplier
)
} else {
true
@@ -98,6 +100,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
typeRef: FirTypeRef,
scopeClassDeclaration: ScopeClassDeclaration,
useSiteFile: FirFile?,
supertypeSupplier: SupertypeSupplier
): Pair<FirBasedSymbol<*>?, ConeSubstitutor?> {
return when (typeRef) {
is FirResolvedTypeRef -> {
@@ -125,7 +128,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
val resolvedSymbol = resolveSymbol(symbol, qualifier, qualifierResolver)
if (resolvedSymbol.isVisible(useSiteFile, containingDeclarations)) {
if (resolvedSymbol.isVisible(useSiteFile, containingDeclarations, supertypeSupplier)) {
acceptedSymbol = resolvedSymbol
substitutor = substitutorFromScope
} else {
@@ -451,11 +454,12 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
areBareTypesAllowed: Boolean,
isOperandOfIsOperator: Boolean,
useSiteFile: FirFile?,
supertypeSupplier: SupertypeSupplier
): ConeKotlinType {
return when (typeRef) {
is FirResolvedTypeRef -> typeRef.type
is FirUserTypeRef -> {
val (symbol, substitutor) = resolveToSymbol(typeRef, scopeClassDeclaration, useSiteFile)
val (symbol, substitutor) = resolveToSymbol(typeRef, scopeClassDeclaration, useSiteFile, supertypeSupplier)
resolveUserType(
typeRef,
symbol,
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.ConeUnexpectedTypeArgumentsError
import org.jetbrains.kotlin.fir.resolve.SupertypeSupplier
import org.jetbrains.kotlin.fir.resolve.typeResolver
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
@@ -21,7 +22,8 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class FirSpecificTypeResolverTransformer(
override val session: FirSession,
private val errorTypeAsResolved: Boolean = true
private val errorTypeAsResolved: Boolean = true,
private val supertypeSupplier: SupertypeSupplier = SupertypeSupplier.Default
) : FirAbstractTreeTransformer<ScopeClassDeclaration>(phase = FirResolvePhase.SUPER_TYPES) {
private val typeResolver = session.typeResolver
@@ -83,6 +85,7 @@ class FirSpecificTypeResolverTransformer(
areBareTypesAllowed,
isOperandOfIsOperator,
currentFile,
supertypeSupplier
)
)
}
@@ -101,6 +104,7 @@ class FirSpecificTypeResolverTransformer(
areBareTypesAllowed,
isOperandOfIsOperator,
currentFile,
supertypeSupplier
).takeIfAcceptable()
return if (resolvedType != null && resolvedType !is ConeClassErrorType) {
buildResolvedTypeRef {
@@ -344,7 +344,7 @@ open class FirSupertypeResolverVisitor(
supertypeComputationSession.startComputingSupertypes(classLikeDeclaration)
val scopes = prepareScopes(classLikeDeclaration)
val transformer = FirSpecificTypeResolverTransformer(session)
val transformer = FirSpecificTypeResolverTransformer(session, supertypeSupplier = supertypeComputationSession.supertypesSupplier)
val resolvedTypesRefs = transformer.withFile(useSiteFile) {
resolveSuperTypeRefs(
transformer,