From 35e9170af165e97c93cb1dbaa468b3f1ba43e364 Mon Sep 17 00:00:00 2001 From: Kirill Rakhman Date: Tue, 13 Feb 2024 16:52:48 +0100 Subject: [PATCH] [FIR] Rename hidden methods around HiddenEverywhereBesideSuperCalls and add documentation. --- .../declaration/FirOverrideChecker.kt | 2 +- .../kotlin/fir/scopes/jvm/JvmMappedScope.kt | 6 +-- .../fir/declarations/deprecationUtils.kt | 41 ++++++++++++++++--- .../kotlin/fir/resolve/calls/Synthetics.kt | 2 +- .../fir/resolve/calls/ResolutionStages.kt | 4 +- .../fir/handlers/FirScopeDumpHandler.kt | 4 +- 6 files changed, 45 insertions(+), 14 deletions(-) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt index 4bf8dda3d23..10d92d3bd76 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt @@ -244,7 +244,7 @@ sealed class FirOverrideChecker(mppKind: MppCheckerKind) : FirAbstractOverrideCh if (callableName in FirDeprecationChecker.DeprecatedOverrideOfHiddenReplacements) { firTypeScope.processOverriddenFunctions(this) { - if (it.isHidden(isSuperCall = false, isOverridden = true) == VisibleWithDeprecation) { + if (it.hiddenStatusOfCall(isSuperCall = false, isCallToOverride = true) == VisibleWithDeprecation) { val message = FirDeprecationChecker.getDeprecatedOverrideOfHiddenMessage(callableName) val deprecationInfo = SimpleDeprecationInfo(DeprecationLevelValue.WARNING, propagatesToOverrides = false, message) diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/scopes/jvm/JvmMappedScope.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/scopes/jvm/JvmMappedScope.kt index c862734579b..37ecc1ada04 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/scopes/jvm/JvmMappedScope.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/scopes/jvm/JvmMappedScope.kt @@ -195,7 +195,7 @@ class JvmMappedScope( symbol = FirNamedFunctionSymbol(CallableId(firKotlinClass.classId, name)) resolvePhase = FirResolvePhase.BODY_RESOLVE }.apply { - isHiddenEverywhereBesideSuperCalls = HiddenEverywhereBesideSuperCallsStatus.HIDDEN_FAKE + hiddenEverywhereBesideSuperCallsStatus = HiddenEverywhereBesideSuperCallsStatus.HIDDEN_FAKE }.symbol } @@ -293,9 +293,9 @@ class JvmMappedScope( private fun FirCallableDeclaration.setHiddenAttributeIfNecessary(jdkMemberStatus: JDKMemberStatus) { if (jdkMemberStatus == JDKMemberStatus.HIDDEN) { - isHiddenEverywhereBesideSuperCalls = HiddenEverywhereBesideSuperCallsStatus.HIDDEN + hiddenEverywhereBesideSuperCallsStatus = HiddenEverywhereBesideSuperCallsStatus.HIDDEN } else if (jdkMemberStatus == JDKMemberStatus.HIDDEN_IN_DECLARING_CLASS_ONLY) { - isHiddenEverywhereBesideSuperCalls = HiddenEverywhereBesideSuperCallsStatus.HIDDEN_IN_DECLARING_CLASS_ONLY + hiddenEverywhereBesideSuperCallsStatus = HiddenEverywhereBesideSuperCallsStatus.HIDDEN_IN_DECLARING_CLASS_ONLY } } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/deprecationUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/deprecationUtils.kt index ff107dd9ceb..99d26a677df 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/deprecationUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/deprecationUtils.kt @@ -326,7 +326,7 @@ fun FirBasedSymbol<*>.isDeprecationLevelHidden(languageVersionSettings: Language private object IsHiddenEverywhereBesideSuperCalls : FirDeclarationDataKey() -var FirCallableDeclaration.isHiddenEverywhereBesideSuperCalls: HiddenEverywhereBesideSuperCallsStatus? by FirDeclarationDataRegistry.data( +var FirCallableDeclaration.hiddenEverywhereBesideSuperCallsStatus: HiddenEverywhereBesideSuperCallsStatus? by FirDeclarationDataRegistry.data( IsHiddenEverywhereBesideSuperCalls ) @@ -344,13 +344,44 @@ enum class CallToPotentiallyHiddenSymbolResult { Hidden, Visible, VisibleWithDeprecation, } -fun FirCallableSymbol<*>.isHidden(isSuperCall: Boolean, isOverridden: Boolean): CallToPotentiallyHiddenSymbolResult { +/** + * To check whether a symbol is visible and if it's deprecated, the method needs to be called for the symbol and all its + * overridden symbols. + * [isSuperCall] must be set to `true` when the receiver is `super`. + * [isCallToOverride] must be set to `false` for the original symbol and to `true` for all its overridden symbols. + * + * Given the following hierarchy + * + * ``` + * public class A { + * public String getX() { return ""; } // HIDDEN + * public String getY() { return ""; } // HIDDEN_IN_DECLARING_CLASS_ONLY + * public String getZ() { return ""; } // HIDDEN_FAKE + * } + * + * class B extends A { + * @Override public String getX() { return super.getX(); } + * @Override public String getY() { return super.getY(); } + * @Override public String getZ() { return super.getZ(); } + * } + * ``` + * + * the results will be as follows + * + * | Receiver \ Symbol | getX | getY | getZ | + * |-------------------|---------|------------------------|------------------------| + * | A | Hidden | Hidden | Hidden | + * | super | Visible | VisibleWithDeprecation | Hidden | + * | B | Hidden | VisibleWithDeprecation | VisibleWithDeprecation | + * + */ +fun FirCallableSymbol<*>.hiddenStatusOfCall(isSuperCall: Boolean, isCallToOverride: Boolean): CallToPotentiallyHiddenSymbolResult { val fir = fir if (fir.isHiddenToOvercomeSignatureClash == true) { return CallToPotentiallyHiddenSymbolResult.Hidden } - val status = fir.isHiddenEverywhereBesideSuperCalls ?: return CallToPotentiallyHiddenSymbolResult.Visible + val status = fir.hiddenEverywhereBesideSuperCallsStatus ?: return CallToPotentiallyHiddenSymbolResult.Visible return when (status) { // If the declaration is HIDDEN, we don't need a deprecation on supercalls because what are we warning the user about? @@ -359,8 +390,8 @@ fun FirCallableSymbol<*>.isHidden(isSuperCall: Boolean, isOverridden: Boolean): // However, on HIDDEN_IN_DECLARING_CLASS_ONLY, // we report a deprecation warning on super calls because we might want to rename the method in the future // (getFirst -> first). - HiddenEverywhereBesideSuperCallsStatus.HIDDEN_IN_DECLARING_CLASS_ONLY -> if (isSuperCall || isOverridden) CallToPotentiallyHiddenSymbolResult.VisibleWithDeprecation else CallToPotentiallyHiddenSymbolResult.Hidden + HiddenEverywhereBesideSuperCallsStatus.HIDDEN_IN_DECLARING_CLASS_ONLY -> if (isSuperCall || isCallToOverride) CallToPotentiallyHiddenSymbolResult.VisibleWithDeprecation else CallToPotentiallyHiddenSymbolResult.Hidden // HIDDEN_FAKE is always hidden (even for super calls), unless overridden. - HiddenEverywhereBesideSuperCallsStatus.HIDDEN_FAKE -> if (isOverridden) CallToPotentiallyHiddenSymbolResult.VisibleWithDeprecation else CallToPotentiallyHiddenSymbolResult.Hidden + HiddenEverywhereBesideSuperCallsStatus.HIDDEN_FAKE -> if (isCallToOverride) CallToPotentiallyHiddenSymbolResult.VisibleWithDeprecation else CallToPotentiallyHiddenSymbolResult.Hidden } } \ No newline at end of file diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/calls/Synthetics.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/calls/Synthetics.kt index a49630b1fb0..df79ac8646b 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/calls/Synthetics.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/calls/Synthetics.kt @@ -272,7 +272,7 @@ class FirSyntheticPropertiesScope private constructor( val visited = mutableSetOf>() fun checkJavaOrigin(symbol: FirNamedFunctionSymbol, scope: FirTypeScope, isOverridden: Boolean) { - val hidden = symbol.isHidden(isSuperCall = false, isOverridden = isOverridden) + val hidden = symbol.hiddenStatusOfCall(isSuperCall = false, isCallToOverride = isOverridden) when (hidden) { CallToPotentiallyHiddenSymbolResult.Hidden -> isHiddenEverywhereBesideSuperCalls = true CallToPotentiallyHiddenSymbolResult.VisibleWithDeprecation -> isDeprecatedOverrideOfHidden = true diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index 15cf4cb33e2..e0b1e5cba04 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -775,7 +775,7 @@ internal object CheckHiddenDeclaration : ResolutionStage() { } val isSuperCall = callInfo.callSite.isSuperCall(session) - if (symbol.isHidden(isSuperCall, isOverridden = false) == CallToPotentiallyHiddenSymbolResult.Hidden) return true + if (symbol.hiddenStatusOfCall(isSuperCall, isCallToOverride = false) == CallToPotentiallyHiddenSymbolResult.Hidden) return true if (symbol.fir.dispatchReceiverType == null || symbol !is FirNamedFunctionSymbol) return false val scope = candidate.originScope as? FirTypeScope ?: return false @@ -783,7 +783,7 @@ internal object CheckHiddenDeclaration : ResolutionStage() { var hidden = false var deprecated = false scope.processOverriddenFunctions(symbol) { - val result = it.isHidden(isSuperCall, isOverridden = true) + val result = it.hiddenStatusOfCall(isSuperCall, isCallToOverride = true) if (result != CallToPotentiallyHiddenSymbolResult.Visible) { if (result == CallToPotentiallyHiddenSymbolResult.Hidden) { hidden = true diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirScopeDumpHandler.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirScopeDumpHandler.kt index 97d838f7517..af93d49e009 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirScopeDumpHandler.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirScopeDumpHandler.kt @@ -9,7 +9,7 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirRegularClass -import org.jetbrains.kotlin.fir.declarations.isHiddenEverywhereBesideSuperCalls +import org.jetbrains.kotlin.fir.declarations.hiddenEverywhereBesideSuperCallsStatus import org.jetbrains.kotlin.fir.declarations.isHiddenToOvercomeSignatureClash import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.renderer.FirRenderer @@ -146,7 +146,7 @@ class FirScopeDumpHandler(testServices: TestServices) : FirAnalysisHandler(testS private fun SmartPrinter.printInfo(declaration: FirCallableDeclaration, scope: FirTypeScope, counter: SymbolCounter) { val origin = declaration.origin.takeUnless { it == FirDeclarationOrigin.BuiltIns } ?: FirDeclarationOrigin.Library print("[$origin]: ") - if (declaration.isHiddenEverywhereBesideSuperCalls != null) { + if (declaration.hiddenEverywhereBesideSuperCallsStatus != null) { print("/* hidden beside supers */ ") } else if (declaration.isHiddenToOvercomeSignatureClash == true) { print("/* hidden due to clash */ ")