[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:
committed by
TeamCityServer
parent
499b97d51e
commit
e7c9d76163
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
|
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
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.FirSimpleSyntheticPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ReceiverValue
|
import org.jetbrains.kotlin.fir.resolve.calls.ReceiverValue
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
@@ -30,6 +31,7 @@ object FirJavaVisibilityChecker : FirVisibilityChecker() {
|
|||||||
dispatchReceiver: ReceiverValue?,
|
dispatchReceiver: ReceiverValue?,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
isCallToPropertySetter: Boolean,
|
isCallToPropertySetter: Boolean,
|
||||||
|
supertypeSupplier: SupertypeSupplier
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return when (declarationVisibility) {
|
return when (declarationVisibility) {
|
||||||
JavaVisibilities.ProtectedAndPackage, JavaVisibilities.ProtectedStaticVisibility -> {
|
JavaVisibilities.ProtectedAndPackage, JavaVisibilities.ProtectedStaticVisibility -> {
|
||||||
@@ -40,7 +42,8 @@ object FirJavaVisibilityChecker : FirVisibilityChecker() {
|
|||||||
if (canSeeProtectedMemberOf(
|
if (canSeeProtectedMemberOf(
|
||||||
containingDeclarations, dispatchReceiver, ownerLookupTag, session,
|
containingDeclarations, dispatchReceiver, ownerLookupTag, session,
|
||||||
isVariableOrNamedFunction = symbol is FirVariableSymbol || symbol is FirNamedFunctionSymbol || symbol is FirPropertyAccessorSymbol,
|
isVariableOrNamedFunction = symbol is FirVariableSymbol || symbol is FirNamedFunctionSymbol || symbol is FirPropertyAccessorSymbol,
|
||||||
isSyntheticProperty = symbol.fir is FirSyntheticPropertyAccessor
|
isSyntheticProperty = symbol.fir is FirSyntheticPropertyAccessor,
|
||||||
|
supertypeSupplier
|
||||||
)
|
)
|
||||||
) return true
|
) return true
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
dispatchReceiver: ReceiverValue?,
|
dispatchReceiver: ReceiverValue?,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
isCallToPropertySetter: Boolean,
|
isCallToPropertySetter: Boolean,
|
||||||
|
supertypeSupplier: SupertypeSupplier
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return true
|
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
|
// 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.
|
// is always visible since it's a supertype of a derived class.
|
||||||
skipCheckForContainingClassVisibility: Boolean = false,
|
skipCheckForContainingClassVisibility: Boolean = false,
|
||||||
|
supertypeSupplier: SupertypeSupplier = SupertypeSupplier.Default
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (!isSpecificDeclarationVisible(
|
if (!isSpecificDeclarationVisible(
|
||||||
declaration,
|
declaration,
|
||||||
@@ -74,7 +76,8 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
useSiteFile,
|
useSiteFile,
|
||||||
containingDeclarations,
|
containingDeclarations,
|
||||||
dispatchReceiver,
|
dispatchReceiver,
|
||||||
isCallToPropertySetter
|
isCallToPropertySetter,
|
||||||
|
supertypeSupplier
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
return false
|
return false
|
||||||
@@ -90,7 +93,8 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
useSiteFile,
|
useSiteFile,
|
||||||
containingDeclarations,
|
containingDeclarations,
|
||||||
dispatchReceiver,
|
dispatchReceiver,
|
||||||
isCallToPropertySetter
|
isCallToPropertySetter,
|
||||||
|
supertypeSupplier
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,6 +136,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
containingDeclarations: List<FirDeclaration>,
|
containingDeclarations: List<FirDeclaration>,
|
||||||
dispatchReceiver: ReceiverValue?,
|
dispatchReceiver: ReceiverValue?,
|
||||||
isCallToPropertySetter: Boolean = false,
|
isCallToPropertySetter: Boolean = false,
|
||||||
|
supertypeSupplier: SupertypeSupplier
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val symbol = declaration.symbol
|
val symbol = declaration.symbol
|
||||||
val provider = session.firProvider
|
val provider = session.firProvider
|
||||||
@@ -176,7 +181,8 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
ownerId != null && canSeeProtectedMemberOf(
|
ownerId != null && canSeeProtectedMemberOf(
|
||||||
containingDeclarations, dispatchReceiver, ownerId, session,
|
containingDeclarations, dispatchReceiver, ownerId, session,
|
||||||
isVariableOrNamedFunction = symbol is FirVariableSymbol || symbol is FirNamedFunctionSymbol || symbol is FirPropertyAccessorSymbol,
|
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,
|
dispatchReceiver,
|
||||||
session,
|
session,
|
||||||
isCallToPropertySetter,
|
isCallToPropertySetter,
|
||||||
|
supertypeSupplier
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,6 +207,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
dispatchReceiver: ReceiverValue?,
|
dispatchReceiver: ReceiverValue?,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
isCallToPropertySetter: Boolean,
|
isCallToPropertySetter: Boolean,
|
||||||
|
supertypeSupplier: SupertypeSupplier
|
||||||
): Boolean
|
): Boolean
|
||||||
|
|
||||||
private fun canSeePrivateMemberOf(
|
private fun canSeePrivateMemberOf(
|
||||||
@@ -243,14 +251,15 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
ownerLookupTag: ConeClassLikeLookupTag,
|
ownerLookupTag: ConeClassLikeLookupTag,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
isVariableOrNamedFunction: Boolean,
|
isVariableOrNamedFunction: Boolean,
|
||||||
isSyntheticProperty: Boolean
|
isSyntheticProperty: Boolean,
|
||||||
|
supertypeSupplier: SupertypeSupplier
|
||||||
): Boolean {
|
): Boolean {
|
||||||
dispatchReceiver?.ownerIfCompanion(session)?.let { companionOwnerLookupTag ->
|
dispatchReceiver?.ownerIfCompanion(session)?.let { companionOwnerLookupTag ->
|
||||||
if (containingUseSiteClass.isSubClass(companionOwnerLookupTag, session)) return true
|
if (containingUseSiteClass.isSubClass(companionOwnerLookupTag, session, supertypeSupplier)) return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
!containingUseSiteClass.isSubClass(ownerLookupTag, session) -> false
|
!containingUseSiteClass.isSubClass(ownerLookupTag, session, supertypeSupplier) -> false
|
||||||
isVariableOrNamedFunction -> doesReceiverFitForProtectedVisibility(
|
isVariableOrNamedFunction -> doesReceiverFitForProtectedVisibility(
|
||||||
dispatchReceiver,
|
dispatchReceiver,
|
||||||
containingUseSiteClass,
|
containingUseSiteClass,
|
||||||
@@ -299,10 +308,21 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
return false
|
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
|
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)
|
// 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
|
(superType as? ConeClassLikeType)?.fullyExpandedType(session)?.lookupTag?.classId?.isSame(ownerLookupTag.classId) == true
|
||||||
}
|
}
|
||||||
@@ -327,7 +347,8 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
ownerLookupTag: ConeClassLikeLookupTag,
|
ownerLookupTag: ConeClassLikeLookupTag,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
isVariableOrNamedFunction: Boolean,
|
isVariableOrNamedFunction: Boolean,
|
||||||
isSyntheticProperty: Boolean
|
isSyntheticProperty: Boolean,
|
||||||
|
supertypeSupplier: SupertypeSupplier
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (canSeePrivateMemberOf(containingDeclarationOfUseSite, ownerLookupTag, session)) return true
|
if (canSeePrivateMemberOf(containingDeclarationOfUseSite, ownerLookupTag, session)) return true
|
||||||
|
|
||||||
@@ -340,7 +361,8 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
ownerLookupTag,
|
ownerLookupTag,
|
||||||
session,
|
session,
|
||||||
isVariableOrNamedFunction,
|
isVariableOrNamedFunction,
|
||||||
isSyntheticProperty
|
isSyntheticProperty,
|
||||||
|
supertypeSupplier
|
||||||
)
|
)
|
||||||
) return true
|
) return true
|
||||||
} else if (containingDeclaration is FirFile) {
|
} else if (containingDeclaration is FirFile) {
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ abstract class FirTypeResolver : FirSessionComponent {
|
|||||||
scopeClassDeclaration: ScopeClassDeclaration,
|
scopeClassDeclaration: ScopeClassDeclaration,
|
||||||
areBareTypesAllowed: Boolean,
|
areBareTypesAllowed: Boolean,
|
||||||
isOperandOfIsOperator: Boolean,
|
isOperandOfIsOperator: Boolean,
|
||||||
useSiteFile: FirFile?
|
useSiteFile: FirFile?,
|
||||||
|
supertypeSupplier: SupertypeSupplier
|
||||||
): ConeKotlinType
|
): ConeKotlinType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-4
@@ -78,6 +78,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
|||||||
private fun FirBasedSymbol<*>?.isVisible(
|
private fun FirBasedSymbol<*>?.isVisible(
|
||||||
useSiteFile: FirFile?,
|
useSiteFile: FirFile?,
|
||||||
containingDeclarations: List<FirDeclaration>,
|
containingDeclarations: List<FirDeclaration>,
|
||||||
|
supertypeSupplier: SupertypeSupplier
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val declaration = this?.fir
|
val declaration = this?.fir
|
||||||
return if (useSiteFile != null && declaration is FirMemberDeclaration) {
|
return if (useSiteFile != null && declaration is FirMemberDeclaration) {
|
||||||
@@ -86,8 +87,9 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
|||||||
session,
|
session,
|
||||||
useSiteFile,
|
useSiteFile,
|
||||||
containingDeclarations,
|
containingDeclarations,
|
||||||
null,
|
dispatchReceiver = null,
|
||||||
false,
|
isCallToPropertySetter = false,
|
||||||
|
supertypeSupplier = supertypeSupplier
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
@@ -98,6 +100,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
|||||||
typeRef: FirTypeRef,
|
typeRef: FirTypeRef,
|
||||||
scopeClassDeclaration: ScopeClassDeclaration,
|
scopeClassDeclaration: ScopeClassDeclaration,
|
||||||
useSiteFile: FirFile?,
|
useSiteFile: FirFile?,
|
||||||
|
supertypeSupplier: SupertypeSupplier
|
||||||
): Pair<FirBasedSymbol<*>?, ConeSubstitutor?> {
|
): Pair<FirBasedSymbol<*>?, ConeSubstitutor?> {
|
||||||
return when (typeRef) {
|
return when (typeRef) {
|
||||||
is FirResolvedTypeRef -> {
|
is FirResolvedTypeRef -> {
|
||||||
@@ -125,7 +128,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
|||||||
|
|
||||||
val resolvedSymbol = resolveSymbol(symbol, qualifier, qualifierResolver)
|
val resolvedSymbol = resolveSymbol(symbol, qualifier, qualifierResolver)
|
||||||
|
|
||||||
if (resolvedSymbol.isVisible(useSiteFile, containingDeclarations)) {
|
if (resolvedSymbol.isVisible(useSiteFile, containingDeclarations, supertypeSupplier)) {
|
||||||
acceptedSymbol = resolvedSymbol
|
acceptedSymbol = resolvedSymbol
|
||||||
substitutor = substitutorFromScope
|
substitutor = substitutorFromScope
|
||||||
} else {
|
} else {
|
||||||
@@ -451,11 +454,12 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
|||||||
areBareTypesAllowed: Boolean,
|
areBareTypesAllowed: Boolean,
|
||||||
isOperandOfIsOperator: Boolean,
|
isOperandOfIsOperator: Boolean,
|
||||||
useSiteFile: FirFile?,
|
useSiteFile: FirFile?,
|
||||||
|
supertypeSupplier: SupertypeSupplier
|
||||||
): ConeKotlinType {
|
): ConeKotlinType {
|
||||||
return when (typeRef) {
|
return when (typeRef) {
|
||||||
is FirResolvedTypeRef -> typeRef.type
|
is FirResolvedTypeRef -> typeRef.type
|
||||||
is FirUserTypeRef -> {
|
is FirUserTypeRef -> {
|
||||||
val (symbol, substitutor) = resolveToSymbol(typeRef, scopeClassDeclaration, useSiteFile)
|
val (symbol, substitutor) = resolveToSymbol(typeRef, scopeClassDeclaration, useSiteFile, supertypeSupplier)
|
||||||
resolveUserType(
|
resolveUserType(
|
||||||
typeRef,
|
typeRef,
|
||||||
symbol,
|
symbol,
|
||||||
|
|||||||
+5
-1
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirFile
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeUnexpectedTypeArgumentsError
|
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.resolve.typeResolver
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||||
@@ -21,7 +22,8 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
|||||||
|
|
||||||
class FirSpecificTypeResolverTransformer(
|
class FirSpecificTypeResolverTransformer(
|
||||||
override val session: FirSession,
|
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) {
|
) : FirAbstractTreeTransformer<ScopeClassDeclaration>(phase = FirResolvePhase.SUPER_TYPES) {
|
||||||
private val typeResolver = session.typeResolver
|
private val typeResolver = session.typeResolver
|
||||||
|
|
||||||
@@ -83,6 +85,7 @@ class FirSpecificTypeResolverTransformer(
|
|||||||
areBareTypesAllowed,
|
areBareTypesAllowed,
|
||||||
isOperandOfIsOperator,
|
isOperandOfIsOperator,
|
||||||
currentFile,
|
currentFile,
|
||||||
|
supertypeSupplier
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -101,6 +104,7 @@ class FirSpecificTypeResolverTransformer(
|
|||||||
areBareTypesAllowed,
|
areBareTypesAllowed,
|
||||||
isOperandOfIsOperator,
|
isOperandOfIsOperator,
|
||||||
currentFile,
|
currentFile,
|
||||||
|
supertypeSupplier
|
||||||
).takeIfAcceptable()
|
).takeIfAcceptable()
|
||||||
return if (resolvedType != null && resolvedType !is ConeClassErrorType) {
|
return if (resolvedType != null && resolvedType !is ConeClassErrorType) {
|
||||||
buildResolvedTypeRef {
|
buildResolvedTypeRef {
|
||||||
|
|||||||
+1
-1
@@ -344,7 +344,7 @@ open class FirSupertypeResolverVisitor(
|
|||||||
supertypeComputationSession.startComputingSupertypes(classLikeDeclaration)
|
supertypeComputationSession.startComputingSupertypes(classLikeDeclaration)
|
||||||
val scopes = prepareScopes(classLikeDeclaration)
|
val scopes = prepareScopes(classLikeDeclaration)
|
||||||
|
|
||||||
val transformer = FirSpecificTypeResolverTransformer(session)
|
val transformer = FirSpecificTypeResolverTransformer(session, supertypeSupplier = supertypeComputationSession.supertypesSupplier)
|
||||||
val resolvedTypesRefs = transformer.withFile(useSiteFile) {
|
val resolvedTypesRefs = transformer.withFile(useSiteFile) {
|
||||||
resolveSuperTypeRefs(
|
resolveSuperTypeRefs(
|
||||||
transformer,
|
transformer,
|
||||||
|
|||||||
Reference in New Issue
Block a user