diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirDeprecationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirDeprecationChecker.kt index ad48dda1132..6f3e3b3c0a2 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirDeprecationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirDeprecationChecker.kt @@ -20,19 +20,15 @@ import org.jetbrains.kotlin.fir.declarations.FutureApiDeprecationInfo import org.jetbrains.kotlin.fir.declarations.RequireKotlinDeprecationInfo import org.jetbrains.kotlin.fir.declarations.getDeprecation import org.jetbrains.kotlin.fir.declarations.getOwnDeprecation -import org.jetbrains.kotlin.fir.expressions.FirAnnotation -import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall -import org.jetbrains.kotlin.fir.expressions.FirStatement -import org.jetbrains.kotlin.fir.expressions.toReference +import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.references.resolved +import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeCallToDeprecatedOverrideOfHidden import org.jetbrains.kotlin.fir.resolve.firClassLike import org.jetbrains.kotlin.fir.scopes.impl.typeAliasForConstructor import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.SymbolInternals -import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol +import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue @@ -69,6 +65,39 @@ object FirDeprecationChecker : FirBasicExpressionChecker(MppCheckerKind.Common) } else { reportApiStatusIfNeeded(source, referencedSymbol, context, reporter, callSite = expression) } + + reportCallToDeprecatedOverrideOfHidden(expression, source, referencedSymbol, reporter, context) + } + + private fun reportCallToDeprecatedOverrideOfHidden( + expression: FirStatement, + source: KtSourceElement?, + referencedSymbol: FirBasedSymbol<*>, + reporter: DiagnosticReporter, + context: CheckerContext, + ) { + if (expression !is FirQualifiedAccessExpression) return + if (ConeCallToDeprecatedOverrideOfHidden in expression.nonFatalDiagnostics) { + val unwrappedSymbol = (referencedSymbol as? FirSyntheticPropertySymbol)?.getterSymbol?.delegateFunctionSymbol + ?: referencedSymbol as? FirCallableSymbol + val callableName = unwrappedSymbol?.callableId?.callableName?.asString() + val message = getDeprecatedOverrideOfHiddenMessage(callableName) + reporter.reportOn(source, FirErrors.DEPRECATION, referencedSymbol, message, context) + } + } + + internal val DeprecatedOverrideOfHiddenReplacements = mapOf( + "getFirst" to "first()", + "getLast" to "last()", + ) + + internal fun getDeprecatedOverrideOfHiddenMessage(callableName: String?): String { + val getFirstOrLastReplacement = DeprecatedOverrideOfHiddenReplacements[callableName] + return if (getFirstOrLastReplacement != null) { + "This declaration will be renamed in a future version of Kotlin. Please consider using the '$getFirstOrLastReplacement' stdlib extension if the collection supports fast random access." + } else { + "This declaration is redundant in Kotlin and might be removed soon." + } } /** Checks if this is an access to a delegated property inside the delegated property itself. 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 bb496188f4e..2c31d76338b 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 @@ -330,8 +330,8 @@ var FirCallableDeclaration.isHiddenEverywhereBesideSuperCalls: HiddenEverywhereB IsHiddenEverywhereBesideSuperCalls ) -enum class HiddenEverywhereBesideSuperCallsStatus(val affectsOverrides: Boolean) { - HIDDEN(true), HIDDEN_IN_DECLARING_CLASS_ONLY(false) +enum class HiddenEverywhereBesideSuperCallsStatus { + HIDDEN, HIDDEN_IN_DECLARING_CLASS_ONLY } private object IsHiddenToOvercomeSignatureClash : FirDeclarationDataKey() @@ -340,11 +340,25 @@ var FirCallableDeclaration.isHiddenToOvercomeSignatureClash: Boolean? by FirDecl IsHiddenToOvercomeSignatureClash ) -fun FirCallableSymbol<*>.isHidden(isSuperCall: Boolean, isOverridden: Boolean): Boolean { +enum class CallToPotentiallyHiddenSymbolResult { + Hidden, Visible, VisibleWithDeprecation, +} + +fun FirCallableSymbol<*>.isHidden(isSuperCall: Boolean, isOverridden: Boolean): CallToPotentiallyHiddenSymbolResult { val fir = fir - return when { - fir.isHiddenToOvercomeSignatureClash == true -> true - !isSuperCall && fir.isHiddenEverywhereBesideSuperCalls?.let { it.affectsOverrides || !isOverridden } == true -> true - else -> false + if (fir.isHiddenToOvercomeSignatureClash == true) { + return CallToPotentiallyHiddenSymbolResult.Hidden + } + + val status = fir.isHiddenEverywhereBesideSuperCalls ?: 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? + // The declaration can't get any more hidden. + HiddenEverywhereBesideSuperCallsStatus.HIDDEN -> if (isSuperCall) CallToPotentiallyHiddenSymbolResult.Visible else CallToPotentiallyHiddenSymbolResult.Hidden + // 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 } } \ 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 008f32a2efe..a49630b1fb0 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 @@ -124,7 +124,7 @@ class FirSyntheticPropertiesScope private constructor( if (getterReturnType?.isUnit == true && CompilerConeAttributes.EnhancedNullability !in getterReturnType.attributes) return // Should have Java among overridden _and_ don't have isHiddenEverywhereBesideSuperCalls among them - val getterCompatibility = getterSymbol.computeGetterCompatibility() + val (getterCompatibility, deprecatedOverrideOfHidden) = getterSymbol.computeGetterCompatibility() if (getterCompatibility == Incompatible) return var matchingSetter: FirSimpleFunction? = null @@ -143,13 +143,14 @@ class FirSyntheticPropertiesScope private constructor( }) } - val property = buildSyntheticProperty(propertyName, getter, matchingSetter, getterCompatibility) + val property = buildSyntheticProperty(propertyName, getter, matchingSetter, getterCompatibility, deprecatedOverrideOfHidden) getter.originalForSubstitutionOverride?.let { property.originalForSubstitutionOverrideAttr = buildSyntheticProperty( propertyName, it, matchingSetter?.originalForSubstitutionOverride ?: matchingSetter, - getterCompatibility + getterCompatibility, + deprecatedOverrideOfHidden, ) } val syntheticSymbol = property.symbol @@ -166,6 +167,7 @@ class FirSyntheticPropertiesScope private constructor( getter: FirSimpleFunction, setter: FirSimpleFunction?, getterCompatibility: SyntheticGetterCompatibility, + deprecatedOverrideOfHidden: Boolean, ): FirSyntheticProperty { val classLookupTag = getter.symbol.originalOrSelf().dispatchReceiverClassLookupTagOrNull() val packageName = classLookupTag?.classId?.packageFqName ?: getter.symbol.callableId.packageName @@ -185,6 +187,9 @@ class FirSyntheticPropertiesScope private constructor( if (getterCompatibility != HasJavaOrigin) { noJavaOrigin = true } + if (deprecatedOverrideOfHidden) { + this.deprecatedOverrideOfHidden = true + } } } @@ -250,6 +255,7 @@ class FirSyntheticPropertiesScope private constructor( HasJavaOrigin } + private data class GetterCompatibilityResult(val compatibility: SyntheticGetterCompatibility, val deprecatedOverrideOfHidden: Boolean) /** * This method computes if getter method can be used as base for synthetic property based on overridden hierarchy * There are three kinds of compatibility: @@ -257,16 +263,20 @@ class FirSyntheticPropertiesScope private constructor( * - `HasJavaOrigin` indicates that this getter is based on root java function (ok to create property) * - `HasKotlinOrigin` shows that there is no base java getter overridden. Property will be created only with some LV (KT-64358) */ - private fun FirNamedFunctionSymbol.computeGetterCompatibility(): SyntheticGetterCompatibility { + private fun FirNamedFunctionSymbol.computeGetterCompatibility(): GetterCompatibilityResult { val kotlinBaseAllowed = !session.languageVersionSettings.supportsFeature(ForbidSyntheticPropertiesWithoutBaseJavaGetter) var isHiddenEverywhereBesideSuperCalls = false + var isDeprecatedOverrideOfHidden = false var result = Incompatible val visited = mutableSetOf>() fun checkJavaOrigin(symbol: FirNamedFunctionSymbol, scope: FirTypeScope, isOverridden: Boolean) { - if (symbol.isHidden(isSuperCall = false, isOverridden = isOverridden)) { - isHiddenEverywhereBesideSuperCalls = true + val hidden = symbol.isHidden(isSuperCall = false, isOverridden = isOverridden) + when (hidden) { + CallToPotentiallyHiddenSymbolResult.Hidden -> isHiddenEverywhereBesideSuperCalls = true + CallToPotentiallyHiddenSymbolResult.VisibleWithDeprecation -> isDeprecatedOverrideOfHidden = true + CallToPotentiallyHiddenSymbolResult.Visible -> {} } val overriddenWithScope = scope.getDirectOverriddenFunctionsWithBaseScope(symbol) @@ -292,7 +302,7 @@ class FirSyntheticPropertiesScope private constructor( checkJavaOrigin(this, baseScope, isOverridden = false) - return when { + val syntheticGetterCompatibility = when { isHiddenEverywhereBesideSuperCalls -> Incompatible result != Incompatible -> result !kotlinBaseAllowed -> Incompatible @@ -300,6 +310,7 @@ class FirSyntheticPropertiesScope private constructor( isJavaTypeOnThePath(this.dispatchReceiverType) -> HasKotlinOrigin else -> Incompatible } + return GetterCompatibilityResult(syntheticGetterCompatibility, isDeprecatedOverrideOfHidden) } /* @@ -365,3 +376,9 @@ private var FirSyntheticProperty.noJavaOrigin: Boolean? by FirDeclarationDataReg val FirSimpleSyntheticPropertySymbol.noJavaOrigin: Boolean get() = (fir as FirSyntheticProperty).noJavaOrigin == true +private object DeprecatedOverrideOfHidden : FirDeclarationDataKey() +private var FirSyntheticProperty.deprecatedOverrideOfHidden: Boolean? by FirDeclarationDataRegistry.data(DeprecatedOverrideOfHidden) + +val FirSimpleSyntheticPropertySymbol.deprecatedOverrideOfHidden: Boolean + get() = (fir as FirSyntheticProperty).deprecatedOverrideOfHidden == true + diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index 526ce7c7461..7bc914fce04 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.fir.resolve.inference.ResolvedCallableReferenceAtom import org.jetbrains.kotlin.fir.resolve.inference.csBuilder import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor +import org.jetbrains.kotlin.fir.resolve.transformers.addNonFatalDiagnostic import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformer import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType @@ -391,6 +392,10 @@ class FirCallResolver( replaceDispatchReceiver(candidate.dispatchReceiverExpression()) replaceExtensionReceiver(candidate.chosenExtensionReceiverExpression()) replaceContextReceiverArguments(candidate.contextReceiverArguments()) + + if (CallToDeprecatedOverrideOfHidden in candidate.diagnostics) { + addNonFatalDiagnostic(ConeCallToDeprecatedOverrideOfHidden) + } } } transformer.storeTypeFromCallee(qualifiedAccess, isLhsOfAssignment = callSite is FirVariableAssignment) 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 caf02484377..2e8eb93e28c 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 @@ -755,7 +755,7 @@ internal object CheckHiddenDeclaration : ResolutionStage() { /** Actual declarations are checked by [FirDeprecationChecker] */ if (symbol.isActual) return val deprecation = symbol.getDeprecation(context.session, callInfo.callSite) - if (deprecation?.deprecationLevel == DeprecationLevelValue.HIDDEN || isHiddenForThisCallSite(symbol, callInfo, candidate, context.session)) { + if (deprecation?.deprecationLevel == DeprecationLevelValue.HIDDEN || isHiddenForThisCallSite(symbol, callInfo, candidate, context.session, sink)) { sink.yieldDiagnostic(HiddenCandidate) } } @@ -764,25 +764,43 @@ internal object CheckHiddenDeclaration : ResolutionStage() { symbol: FirCallableSymbol<*>, callInfo: CallInfo, candidate: Candidate, - session: FirSession + session: FirSession, + sink: CheckerSink, ): Boolean { - val isSuperCall = callInfo.callSite.isSuperCall(session) + /** + * The logic for synthetic properties itself is in [FirSyntheticPropertiesScope.computeGetterCompatibility]. + */ + if (symbol is FirSimpleSyntheticPropertySymbol && symbol.deprecatedOverrideOfHidden) { + sink.reportDiagnostic(CallToDeprecatedOverrideOfHidden) + } + if (symbol.fir.dispatchReceiverType == null || symbol !is FirNamedFunctionSymbol) return false - if (symbol.isHidden(isSuperCall, isOverridden = false)) return true + val isSuperCall = callInfo.callSite.isSuperCall(session) + if (symbol.isHidden(isSuperCall, isOverridden = false) == CallToPotentiallyHiddenSymbolResult.Hidden) return true val scope = candidate.originScope as? FirTypeScope ?: return false - var result = false + var hidden = false + var deprecated = false scope.processOverriddenFunctions(symbol) { - if (it.isHidden(isSuperCall, isOverridden = true)) { - result = true + val result = it.isHidden(isSuperCall, isOverridden = true) + if (result != CallToPotentiallyHiddenSymbolResult.Visible) { + if (result == CallToPotentiallyHiddenSymbolResult.Hidden) { + hidden = true + } else if (result == CallToPotentiallyHiddenSymbolResult.VisibleWithDeprecation) { + deprecated = true + } ProcessorAction.STOP } else { ProcessorAction.NEXT } } - return result + if (deprecated) { + sink.reportDiagnostic(CallToDeprecatedOverrideOfHidden) + } + + return hidden } private fun FirElement.isSuperCall(session: FirSession): Boolean = diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt index 0f72939ce98..74f5ae78cad 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt @@ -328,9 +328,7 @@ class FirCallCompletionResultsWriterTransformer( result.replaceConeTypeOrNull(resultType) session.lookupTracker?.recordTypeResolveAsLookup(resultType, qualifiedAccessExpression.source, context.file.source) - if (calleeReference.candidate.doesResolutionResultOverrideOtherToPreserveCompatibility()) { - result.addNonFatalDiagnostic(ConeResolutionResultOverridesOtherToPreserveCompatibility) - } + result.addNonFatalDiagnostics(calleeReference) return result } @@ -384,12 +382,20 @@ class FirCallCompletionResultsWriterTransformer( return arrayOfCallTransformer.transformFunctionCall(result, session) } - if (calleeReference.candidate.doesResolutionResultOverrideOtherToPreserveCompatibility()) { - result.addNonFatalDiagnostic(ConeResolutionResultOverridesOtherToPreserveCompatibility) - } + result.addNonFatalDiagnostics(calleeReference) return result } + private fun FirQualifiedAccessExpression.addNonFatalDiagnostics(calleeReference: FirNamedReferenceWithCandidate) { + if (calleeReference.candidate.doesResolutionResultOverrideOtherToPreserveCompatibility()) { + addNonFatalDiagnostic(ConeResolutionResultOverridesOtherToPreserveCompatibility) + } + + if (CallToDeprecatedOverrideOfHidden in calleeReference.candidate.diagnostics) { + addNonFatalDiagnostic(ConeCallToDeprecatedOverrideOfHidden) + } + } + private fun FirCall.transformWithExpectedTypes(expectedArgumentsTypeMapping: ExpectedArgumentType.ArgumentsMap?) { class SamConversionInsertionTransformer : FirTransformer() { override fun transformElement(element: E, data: Nothing?): E { @@ -579,9 +585,7 @@ class FirCallCompletionResultsWriterTransformer( replaceCalleeReference(resolvedReference) replaceDispatchReceiver(dispatchReceiver) replaceExtensionReceiver(extensionReceiver) - if (calleeReference.candidate.doesResolutionResultOverrideOtherToPreserveCompatibility()) { - addNonFatalDiagnostic(ConeResolutionResultOverridesOtherToPreserveCompatibility) - } + addNonFatalDiagnostics(calleeReference) } } diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt index 25d58dc7edb..5c62f82d11d 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt @@ -163,4 +163,6 @@ object TypeParameterAsExpression : ResolutionDiagnostic(INAPPLICABLE) class TypeVariableAsExplicitReceiver( val explicitReceiver: FirExpression, val typeParameter: FirTypeParameter, -) : ResolutionDiagnostic(RESOLVED_WITH_ERROR) \ No newline at end of file +) : ResolutionDiagnostic(RESOLVED_WITH_ERROR) + +object CallToDeprecatedOverrideOfHidden : ResolutionDiagnostic(RESOLVED) \ No newline at end of file diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt index 4d37cee7280..b598fbe4b7b 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt @@ -404,3 +404,8 @@ object ConeResolutionResultOverridesOtherToPreserveCompatibility : ConeDiagnosti get() = "Resolution result overrides another result to preserve compatibility, result maybe changed in future versions" } + +object ConeCallToDeprecatedOverrideOfHidden : ConeDiagnostic { + override val reason: String + get() = "Call to deprecated override of hidden" +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/testWithModifiedMockJdk/notConsideredMethod.fir.kt b/compiler/testData/diagnostics/tests/testWithModifiedMockJdk/notConsideredMethod.fir.kt index b9509073d89..f281dc4d3de 100644 --- a/compiler/testData/diagnostics/tests/testWithModifiedMockJdk/notConsideredMethod.fir.kt +++ b/compiler/testData/diagnostics/tests/testWithModifiedMockJdk/notConsideredMethod.fir.kt @@ -9,5 +9,5 @@ interface A : MutableCollection { fun foo(x: MutableCollection, y: Collection, z: A) { x.nonExistingMethod(1).checkType { _<String>() } y.nonExistingMethod("") - z.nonExistingMethod("") + z.nonExistingMethod("") } diff --git a/compiler/testData/diagnostics/tests/testsWithJava21/implementationsForSequencedCollection.fir.kt b/compiler/testData/diagnostics/tests/testsWithJava21/implementationsForSequencedCollection.fir.kt index 56f73add22c..75371e2f192 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() @@ -46,4 +46,4 @@ fun foo(ll: java.util.LinkedList, al: ArrayList, ad: ArrayDeque< jad.removeFirst() jad.removeLast() jad.reversed() -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.diag.txt b/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.diag.txt index 5062245c524..995b80c10b4 100644 --- a/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.diag.txt +++ b/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.diag.txt @@ -1,3 +1,7 @@ +/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:(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'. /newListMethods.fir.kt:(613,618): error: Function invocation 'first()' expected. @@ -5,3 +9,19 @@ /newListMethods.fir.kt:(704,711): error: Unresolved reference 'getLast'. /newListMethods.fir.kt:(720,724): error: Function invocation 'last()' expected. + +/newListMethods.fir.kt:(838,846): warning: 'fun getFirst(): String!' 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:(855,860): warning: 'val first: String!' 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:(881,888): warning: 'fun getLast(): String!' 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:(897,901): warning: 'val last: String!' 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:(1015,1023): warning: 'fun getFirst(): String' 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:(1032,1037): warning: 'val first: String' 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:(1058,1065): warning: 'fun getLast(): String' 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:(1074,1078): warning: 'val last: String' 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. diff --git a/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.kt b/compiler/testData/diagnostics/tests/testsWithJava21/newListMethods.fir.kt index d9ca4002fc9..706991ef131 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() @@ -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()