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 67e1dbb9495..783aa963981 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 @@ -134,7 +134,7 @@ class JvmMappedScope( if (jdkMemberStatus == JDKMemberStatus.DROP) return@processor // hidden methods in final class can't be overridden or called with 'super' - if (jdkMemberStatus == JDKMemberStatus.HIDDEN && firKotlinClass.isFinal) return@processor + if ((jdkMemberStatus == JDKMemberStatus.HIDDEN || jdkMemberStatus == JDKMemberStatus.HIDDEN_IN_DECLARING_CLASS_ONLY) && firKotlinClass.isFinal) return@processor val newSymbol = mappedSymbolCache.mappedFunctions.getValue(symbol, this to jdkMemberStatus) processor(newSymbol) @@ -201,12 +201,13 @@ class JvmMappedScope( } } - // For unknown methods, we use HIDDEN policy by default - return JDKMemberStatus.HIDDEN + // For unknown methods, we use HIDDEN_IN_DECLARING_CLASS_ONLY policy by default, + // meaning they are hidden in the declaring class but visible with deprecation in overrides. + return JDKMemberStatus.HIDDEN_IN_DECLARING_CLASS_ONLY } internal enum class JDKMemberStatus { - HIDDEN, VISIBLE, DROP + HIDDEN, VISIBLE, DROP, HIDDEN_IN_DECLARING_CLASS_ONLY, } override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { @@ -228,7 +229,9 @@ class JvmMappedScope( newSource = oldFunction.source, ).apply { if (jdkMemberStatus == JDKMemberStatus.HIDDEN) { - isHiddenEverywhereBesideSuperCalls = true + isHiddenEverywhereBesideSuperCalls = HiddenEverywhereBesideSuperCallsStatus.HIDDEN + } else if (jdkMemberStatus == JDKMemberStatus.HIDDEN_IN_DECLARING_CLASS_ONLY) { + isHiddenEverywhereBesideSuperCalls = HiddenEverywhereBesideSuperCallsStatus.HIDDEN_IN_DECLARING_CLASS_ONLY } } return newSymbol 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 77dd28578c4..bb496188f4e 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 @@ -15,7 +15,6 @@ import org.jetbrains.kotlin.fir.caches.FirCachesFactory import org.jetbrains.kotlin.fir.caches.firCachesFactory import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.languageVersionSettings -import org.jetbrains.kotlin.fir.references.FirNamedReference import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol @@ -327,12 +326,25 @@ fun FirBasedSymbol<*>.isDeprecationLevelHidden(languageVersionSettings: Language private object IsHiddenEverywhereBesideSuperCalls : FirDeclarationDataKey() -var FirCallableDeclaration.isHiddenEverywhereBesideSuperCalls: Boolean? by FirDeclarationDataRegistry.data( +var FirCallableDeclaration.isHiddenEverywhereBesideSuperCalls: HiddenEverywhereBesideSuperCallsStatus? by FirDeclarationDataRegistry.data( IsHiddenEverywhereBesideSuperCalls ) +enum class HiddenEverywhereBesideSuperCallsStatus(val affectsOverrides: Boolean) { + HIDDEN(true), HIDDEN_IN_DECLARING_CLASS_ONLY(false) +} + private object IsHiddenToOvercomeSignatureClash : FirDeclarationDataKey() var FirCallableDeclaration.isHiddenToOvercomeSignatureClash: Boolean? by FirDeclarationDataRegistry.data( IsHiddenToOvercomeSignatureClash ) + +fun FirCallableSymbol<*>.isHidden(isSuperCall: Boolean, isOverridden: Boolean): Boolean { + val fir = fir + return when { + fir.isHiddenToOvercomeSignatureClash == true -> true + !isSuperCall && fir.isHiddenEverywhereBesideSuperCalls?.let { it.affectsOverrides || !isOverridden } == true -> true + else -> false + } +} \ 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 1db4b71160b..008f32a2efe 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 @@ -264,8 +264,8 @@ class FirSyntheticPropertiesScope private constructor( var result = Incompatible val visited = mutableSetOf>() - fun checkJavaOrigin(symbol: FirNamedFunctionSymbol, scope: FirTypeScope) { - if (symbol.fir.isHiddenEverywhereBesideSuperCalls == true) { + fun checkJavaOrigin(symbol: FirNamedFunctionSymbol, scope: FirTypeScope, isOverridden: Boolean) { + if (symbol.isHidden(isSuperCall = false, isOverridden = isOverridden)) { isHiddenEverywhereBesideSuperCalls = true } @@ -286,11 +286,11 @@ class FirSyntheticPropertiesScope private constructor( overriddenWithScope.forEach { if (!visited.add(it)) return@forEach - checkJavaOrigin(it.member, it.baseScope) + checkJavaOrigin(it.member, it.baseScope, isOverridden = true) } } - checkJavaOrigin(this, baseScope) + checkJavaOrigin(this, baseScope, isOverridden = false) return when { isHiddenEverywhereBesideSuperCalls -> Incompatible 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 101ff9e7575..caf02484377 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 @@ -768,13 +768,13 @@ internal object CheckHiddenDeclaration : ResolutionStage() { ): Boolean { val isSuperCall = callInfo.callSite.isSuperCall(session) if (symbol.fir.dispatchReceiverType == null || symbol !is FirNamedFunctionSymbol) return false - if (symbol.isHidden(isSuperCall)) return true + if (symbol.isHidden(isSuperCall, isOverridden = false)) return true val scope = candidate.originScope as? FirTypeScope ?: return false var result = false scope.processOverriddenFunctions(symbol) { - if (it.isHidden(isSuperCall)) { + if (it.isHidden(isSuperCall, isOverridden = true)) { result = true ProcessorAction.STOP } else { @@ -788,10 +788,6 @@ internal object CheckHiddenDeclaration : ResolutionStage() { private fun FirElement.isSuperCall(session: FirSession): Boolean = this is FirQualifiedAccessExpression && explicitReceiver?.toReference(session) is FirSuperReference - private fun FirCallableSymbol<*>.isHidden(isSuperCall: Boolean): Boolean { - val fir = fir - return !isSuperCall && fir.isHiddenEverywhereBesideSuperCalls == true || fir.isHiddenToOvercomeSignatureClash == true - } } private val DYNAMIC_EXTENSION_ANNOTATION_CLASS_ID: ClassId = ClassId.topLevel(DYNAMIC_EXTENSION_FQ_NAME) diff --git a/compiler/testData/diagnostics/tests/testsWithJava21/implementationsForSequencedCollection.fir.kt b/compiler/testData/diagnostics/tests/testsWithJava21/implementationsForSequencedCollection.fir.kt index 9535f08cc56..56f73add22c 100644 --- a/compiler/testData/diagnostics/tests/testsWithJava21/implementationsForSequencedCollection.fir.kt +++ b/compiler/testData/diagnostics/tests/testsWithJava21/implementationsForSequencedCollection.fir.kt @@ -1,11 +1,11 @@ fun foo(ll: java.util.LinkedList, al: ArrayList, ad: ArrayDeque, jad: java.util.ArrayDeque) { ll.addFirst("") ll.addLast("") - ll.getFirst() - ll.first // synthetic property for getFirst() + ll.getFirst() + ll.first // synthetic property for getFirst() ll.first() // stdlib extension on List - ll.getLast() - ll.last + ll.getLast() + ll.last ll.last() ll.removeFirst() ll.removeLast() @@ -13,11 +13,11 @@ fun foo(ll: java.util.LinkedList, al: ArrayList, ad: ArrayDeque< al.addFirst("") al.addLast("") - al.getFirst() - al.first + al.getFirst() + al.first al.first() - al.getLast() - al.last + al.getLast() + al.last al.last() al.removeFirst() al.removeLast() diff --git a/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.diag.txt b/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.diag.txt index ab89cdbee72..5062245c524 100644 --- a/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.diag.txt +++ b/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.diag.txt @@ -5,19 +5,3 @@ /newListMethods.fir.kt:(704,711): error: Unresolved reference 'getLast'. /newListMethods.fir.kt:(720,724): error: Function invocation 'last()' expected. - -/newListMethods.fir.kt:(838,846): error: Unresolved reference 'getFirst'. - -/newListMethods.fir.kt:(855,860): error: Function invocation 'first()' expected. - -/newListMethods.fir.kt:(881,888): error: Unresolved reference 'getLast'. - -/newListMethods.fir.kt:(897,901): error: Function invocation 'last()' expected. - -/newListMethods.fir.kt:(1015,1023): error: Unresolved reference 'getFirst'. - -/newListMethods.fir.kt:(1032,1037): error: Function invocation 'first()' expected. - -/newListMethods.fir.kt:(1058,1065): error: Unresolved reference 'getLast'. - -/newListMethods.fir.kt:(1074,1078): error: Function invocation 'last()' expected. diff --git a/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.kt b/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.kt index fbce321a2af..d9ca4002fc9 100644 --- a/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.kt +++ b/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.kt @@ -34,11 +34,11 @@ fun foo(x: MutableList, y: ArrayList, z: A) { y.addFirst("") y.addLast("") - y.getFirst() - y.first + y.getFirst() + y.first y.first() - y.getLast() - y.last + y.getLast() + y.last y.last() y.removeFirst() y.removeLast() @@ -46,11 +46,11 @@ fun foo(x: MutableList, y: ArrayList, z: A) { z.addFirst("") z.addLast("") - z.getFirst() - z.first + z.getFirst() + z.first z.first() - z.getLast() - z.last + z.getLast() + z.last z.last() z.removeFirst() z.removeLast() 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 f282d864344..97d838f7517 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 @@ -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 == true) { + if (declaration.isHiddenEverywhereBesideSuperCalls != null) { print("/* hidden beside supers */ ") } else if (declaration.isHiddenToOvercomeSignatureClash == true) { print("/* hidden due to clash */ ")