From e8cbd8a1cd4839a1ea12547c73d00ef57f28ab06 Mon Sep 17 00:00:00 2001 From: Kirill Rakhman Date: Tue, 6 Feb 2024 16:03:29 +0100 Subject: [PATCH] [FIR] Report OVERRIDE_DEPRECATION for overrides of HIDDEN_IN_DECLARING_CLASS_ONLY #KT-65438 Fixed --- .../declaration/FirOverrideChecker.kt | 34 +++++++++++++++---- .../newListMethods.fir.diag.txt | 4 +++ .../testsWithJava21/newListMethods.fir.kt | 4 +-- 3 files changed, 34 insertions(+), 8 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 72aab34e9fe..4bf8dda3d23 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 @@ -12,24 +12,25 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.reportOn -import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind +import org.jetbrains.kotlin.fir.analysis.checkers.* import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirDeprecationChecker import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirOptInUsageBaseChecker import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirOptInUsageBaseChecker.Experimentality -import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol -import org.jetbrains.kotlin.fir.analysis.checkers.hasModifier -import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.overridesBackwardCompatibilityHelper import org.jetbrains.kotlin.fir.containingClassLookupTag import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.CallToPotentiallyHiddenSymbolResult.VisibleWithDeprecation import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.originalOrSelf import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.scopes.FirTypeScope +import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.impl.toConeType +import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions import org.jetbrains.kotlin.fir.scopes.retrieveDirectOverriddenOf import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.impl.* @@ -40,6 +41,8 @@ import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.typeContext import org.jetbrains.kotlin.fir.visibilityChecker import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue +import org.jetbrains.kotlin.resolve.deprecation.SimpleDeprecationInfo import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.TypeCheckerState @@ -221,7 +224,8 @@ sealed class FirOverrideChecker(mppKind: MppCheckerKind) : FirAbstractOverrideCh private fun FirCallableSymbol<*>.checkDeprecation( reporter: DiagnosticReporter, overriddenSymbols: List>, - context: CheckerContext + context: CheckerContext, + firTypeScope: FirTypeScope, ) { val ownDeprecation = this.getDeprecation(context.session.languageVersionSettings) if (ownDeprecation == null || ownDeprecation.isNotEmpty()) return @@ -234,6 +238,24 @@ sealed class FirOverrideChecker(mppKind: MppCheckerKind) : FirAbstractOverrideCh reporter.reportOn(source, FirErrors.OVERRIDE_DEPRECATION, overriddenSymbol, deprecationFromOverriddenSymbol, context) return } + + if (this is FirNamedFunctionSymbol) { + val callableName = this.name.asString() + + if (callableName in FirDeprecationChecker.DeprecatedOverrideOfHiddenReplacements) { + firTypeScope.processOverriddenFunctions(this) { + if (it.isHidden(isSuperCall = false, isOverridden = true) == VisibleWithDeprecation) { + val message = FirDeprecationChecker.getDeprecatedOverrideOfHiddenMessage(callableName) + val deprecationInfo = + SimpleDeprecationInfo(DeprecationLevelValue.WARNING, propagatesToOverrides = false, message) + reporter.reportOn(source, FirErrors.OVERRIDE_DEPRECATION, it, deprecationInfo, context) + return@processOverriddenFunctions ProcessorAction.STOP + } + + ProcessorAction.NEXT + } + } + } } private fun FirFunctionSymbol<*>.checkDefaultValues( @@ -342,7 +364,7 @@ sealed class FirOverrideChecker(mppKind: MppCheckerKind) : FirAbstractOverrideCh member.checkVisibility(containingClass, reporter, overriddenMemberSymbols, context) - member.checkDeprecation(reporter, overriddenMemberSymbols, context) + member.checkDeprecation(reporter, overriddenMemberSymbols, context, firTypeScope) if (member is FirFunctionSymbol) { member.checkDefaultValues(reporter, context) diff --git a/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.diag.txt b/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.diag.txt index 995b80c10b4..db91fb1a339 100644 --- a/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.diag.txt +++ b/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.diag.txt @@ -1,5 +1,9 @@ +/newListMethods.fir.kt:(231,239): warning: This declaration overrides a deprecated member but is not marked as deprecated itself. Please add the '@Deprecated' annotation or suppress the diagnostic. + /newListMethods.fir.kt:(253,261): warning: 'fun getFirst(): T!' is deprecated. This declaration will be renamed in a future version of Kotlin. Please consider using the 'first()' stdlib extension if the collection supports fast random access. +/newListMethods.fir.kt:(281,288): warning: This declaration overrides a deprecated member but is not marked as deprecated itself. Please add the '@Deprecated' annotation or suppress the diagnostic. + /newListMethods.fir.kt:(302,309): warning: 'fun getLast(): T!' is deprecated. This declaration will be renamed in a future version of Kotlin. Please consider using the 'last()' stdlib extension if the collection supports fast random access. /newListMethods.fir.kt:(596,604): error: Unresolved reference 'getFirst'. diff --git a/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.kt b/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.kt index 706991ef131..e4106a05399 100644 --- a/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.kt +++ b/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.kt @@ -10,8 +10,8 @@ class A : ArrayList() { super.addLast(t) } - override fun getFirst(): T = super.getFirst() - override fun getLast(): T = super.getLast() + override fun getFirst(): T = super.getFirst() + override fun getLast(): T = super.getLast() override fun removeFirst(): T = super.removeFirst() override fun removeLast(): T = super.removeLast()