From 16ab36e167aa7c54197629f8d596662fd011182d Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Fri, 6 Oct 2023 12:40:43 +0300 Subject: [PATCH] [FIR] Don't create synthetic overriden property if base property is invisible ^KT-62393 Fixed --- .../fir/analysis/checkers/FirHelpers.kt | 24 ++++++++++++------- .../scopes/JavaClassUseSiteMemberScope.kt | 11 +++++++-- .../jvm/FirJvmDelegatedMembersFilter.kt | 4 ++-- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt index daccb8ab80f..932eea6b2ba 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt @@ -306,19 +306,27 @@ fun isSubtypeForTypeMismatch(context: ConeInferenceContext, subtype: ConeKotlinT } fun FirCallableDeclaration.isVisibleInClass(parentClass: FirClass): Boolean { - return symbol.isVisibleInClass(parentClass.symbol) + return symbol.isVisibleInClass(parentClass.symbol, symbol.resolvedStatus) } fun FirBasedSymbol<*>.isVisibleInClass(parentClassSymbol: FirClassSymbol<*>): Boolean { - val classPackage = parentClassSymbol.classId.packageFqName - val (visibility, packageName) = when (this) { - is FirCallableSymbol<*> -> visibility to callableId.packageName - is FirClassLikeSymbol<*> -> visibility to classId.packageFqName + val status = when (this) { + is FirCallableSymbol<*> -> resolvedStatus + is FirClassLikeSymbol -> resolvedStatus else -> return true } - if (visibility == Visibilities.Private || - !visibility.visibleFromPackage(classPackage, packageName) - ) return false + return isVisibleInClass(parentClassSymbol, status) +} + +fun FirBasedSymbol<*>.isVisibleInClass(parentClassSymbol: FirClassSymbol<*>, status: FirDeclarationStatus): Boolean { + val classPackage = parentClassSymbol.classId.packageFqName + val packageName = when (this) { + is FirCallableSymbol<*> -> callableId.packageName + is FirClassLikeSymbol<*> -> classId.packageFqName + else -> return true + } + val visibility = status.visibility + if (visibility == Visibilities.Private || !visibility.visibleFromPackage(classPackage, packageName)) return false if ( visibility == Visibilities.Internal && (moduleData != parentClassSymbol.moduleData || parentClassSymbol.moduleData in moduleData.friendDependencies) diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt index 8dccda0a629..93ea9463851 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.* +import org.jetbrains.kotlin.fir.analysis.checkers.isVisibleInClass import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunctionCopy import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl @@ -49,7 +50,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addToStdlib.runIf class JavaClassUseSiteMemberScope( - klass: FirJavaClass, + private val klass: FirJavaClass, session: FirSession, superTypeScopes: List, declaredMemberScope: FirContainingNamesAwareScope @@ -153,6 +154,9 @@ class JavaClassUseSiteMemberScope( internal fun syntheticPropertyFromOverride(overriddenProperty: ResultOfIntersection): FirSyntheticPropertySymbol? { val overrideInClass = overriddenProperty.overriddenMembers.firstNotNullOfOrNull { (symbol, _) -> + // We may call this function at the STATUS phase, which means that using resolved status may lead to cycle + // So we need to use raw status here + if (!symbol.isVisibleInClass(klass.symbol, symbol.rawStatus)) return@firstNotNullOfOrNull null symbol.createOverridePropertyIfExists(declaredMemberScope, takeModalityFromGetter = true) ?: superTypeScopes.firstNotNullOfOrNull { scope -> symbol.createOverridePropertyIfExists(scope, takeModalityFromGetter = false) @@ -260,7 +264,10 @@ class JavaClassUseSiteMemberScope( getProperties(propertyName).any l@{ propertySymbol -> // TODO: add magic overrides from LazyJavaClassMemberScope.isVisibleAsFunctionInCurrentClass if (propertySymbol !is FirPropertySymbol) return@l false - propertySymbol.isOverriddenInClassBy(this) + // We may call this function at the STATUS phase, which means that using resolved status may lead to cycle + // so we need to use raw status here + propertySymbol.isVisibleInClass(this@JavaClassUseSiteMemberScope.klass.symbol, propertySymbol.rawStatus) && + propertySymbol.isOverriddenInClassBy(this) } } if (hasCorrespondingProperty) return false diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/scopes/jvm/FirJvmDelegatedMembersFilter.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/scopes/jvm/FirJvmDelegatedMembersFilter.kt index 42469c4e4bb..26067f1fba9 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/scopes/jvm/FirJvmDelegatedMembersFilter.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/scopes/jvm/FirJvmDelegatedMembersFilter.kt @@ -33,7 +33,7 @@ class FirJvmDelegatedMembersFilter(private val session: FirSession) : FirDelegat // If java interface method is not abstract, then it's a default method. private fun FirCallableSymbol<*>.isNonAbstractJavaMethod(): Boolean { - return origin == FirDeclarationOrigin.Enhancement && modality != Modality.ABSTRACT + return origin == FirDeclarationOrigin.Enhancement && fir.modality != Modality.ABSTRACT } private fun FirCallableSymbol<*>.hasJvmDefaultAnnotation(): Boolean { @@ -41,7 +41,7 @@ class FirJvmDelegatedMembersFilter(private val session: FirSession) : FirDelegat } private fun FirCallableSymbol<*>.isBuiltInMemberMappedToJavaDefault(): Boolean { - return modality != Modality.ABSTRACT && + return fir.modality != Modality.ABSTRACT && annotations.hasAnnotation(PLATFORM_DEPENDENT_ANNOTATION_CLASS_ID, session) } }