From 09f895efe66d26ba23b45c42366a9445536ebb83 Mon Sep 17 00:00:00 2001 From: Kirill Rakhman Date: Fri, 4 Aug 2023 17:20:49 +0200 Subject: [PATCH] [FIR] Implement VERSION_REQUIREMENT_DEPRECATION diagnostics --- .../fir/generator/HLDiagnosticConverter.kt | 2 + .../diagnostics/KtFirDataClassConverters.kt | 20 ++++++++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 17 +++++++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 19 ++++++++ .../diagnostics/FirDiagnosticsList.kt | 15 ++++++ .../fir/analysis/diagnostics/FirErrors.kt | 3 ++ .../expression/FirDeprecationChecker.kt | 48 ++++++++++++++++--- .../diagnostics/FirDiagnosticRenderers.kt | 12 ++++- .../diagnostics/FirErrorsDefaultMessages.kt | 6 +++ .../deserialization/ClassDeserialization.kt | 9 ++-- .../FirDeserializationUtils.kt | 17 +++++++ .../deserialization/FirMemberDeserializer.kt | 22 +++++---- .../fir/declarations/deprecationUtils.kt | 24 ++++++++-- .../fir/declarations/DeprecationsProvider.kt | 35 ++++++++++++-- .../FirVersionRequirementsTableKey.kt | 6 +-- .../fir/symbols/impl/FirClassLikeSymbol.kt | 2 +- .../deprecation/CommonDeprecationUtils.kt | 34 +++++++++++++ .../deprecation/DeprecationResolver.kt | 19 +------- .../jvm/requireKotlinCompilerVersionK2.args | 7 +++ .../jvm/requireKotlinCompilerVersionK2.out | 8 ++++ ...peAliasesInvisibleWithApiVersion1_0.fir.kt | 7 ++- ...onTypeAliasesInvisibleWithApiVersion1_0.kt | 3 ++ .../kotlin/cli/CliTestGenerated.java | 5 ++ 23 files changed, 285 insertions(+), 55 deletions(-) create mode 100644 compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirDeserializationUtils.kt rename compiler/fir/{semantics => tree}/src/org/jetbrains/kotlin/fir/declarations/FirVersionRequirementsTableKey.kt (60%) create mode 100644 compiler/frontend.common/src/org/jetbrains/kotlin/resolve/deprecation/CommonDeprecationUtils.kt create mode 100644 compiler/testData/cli/jvm/requireKotlinCompilerVersionK2.args create mode 100644 compiler/testData/cli/jvm/requireKotlinCompilerVersionK2.out diff --git a/analysis/analysis-api-fir/analysis-api-fir-generator/src/org/jetbrains/kotlin/analysis/api/fir/generator/HLDiagnosticConverter.kt b/analysis/analysis-api-fir/analysis-api-fir-generator/src/org/jetbrains/kotlin/analysis/api/fir/generator/HLDiagnosticConverter.kt index 64949035a4b..95e45cdbbb7 100644 --- a/analysis/analysis-api-fir/analysis-api-fir-generator/src/org/jetbrains/kotlin/analysis/api/fir/generator/HLDiagnosticConverter.kt +++ b/analysis/analysis-api-fir/analysis-api-fir-generator/src/org/jetbrains/kotlin/analysis/api/fir/generator/HLDiagnosticConverter.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.lexer.KtKeywordToken import org.jetbrains.kotlin.lexer.KtModifierKeywordToken +import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName @@ -370,6 +371,7 @@ internal object FirToKtConversionCreator { CallableId::class, ClassKind::class, FunctionTypeKind::class, + VersionRequirement.Version::class, ) private val KType.kClass: KClass<*> diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index eafffc788ff..0b5471d01d5 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -327,6 +327,26 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.VERSION_REQUIREMENT_DEPRECATION_ERROR) { firDiagnostic -> + VersionRequirementDeprecationErrorImpl( + firSymbolBuilder.buildSymbol(firDiagnostic.a), + firDiagnostic.b, + firDiagnostic.c, + firDiagnostic.d, + firDiagnostic as KtPsiDiagnostic, + token, + ) + } + add(FirErrors.VERSION_REQUIREMENT_DEPRECATION) { firDiagnostic -> + VersionRequirementDeprecationImpl( + firSymbolBuilder.buildSymbol(firDiagnostic.a), + firDiagnostic.b, + firDiagnostic.c, + firDiagnostic.d, + firDiagnostic as KtPsiDiagnostic, + token, + ) + } add(FirErrors.TYPEALIAS_EXPANSION_DEPRECATION_ERROR) { firDiagnostic -> TypealiasExpansionDeprecationErrorImpl( firSymbolBuilder.buildSymbol(firDiagnostic.a), diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index 73bd7a9e581..87d4b9bfdb1 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.lexer.KtKeywordToken import org.jetbrains.kotlin.lexer.KtModifierKeywordToken +import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement.Version import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName @@ -271,6 +272,22 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { val message: String } + interface VersionRequirementDeprecationError : KtFirDiagnostic { + override val diagnosticClass get() = VersionRequirementDeprecationError::class + val reference: KtSymbol + val version: Version + val currentVersion: String + val message: String + } + + interface VersionRequirementDeprecation : KtFirDiagnostic { + override val diagnosticClass get() = VersionRequirementDeprecation::class + val reference: KtSymbol + val version: Version + val currentVersion: String + val message: String + } + interface TypealiasExpansionDeprecationError : KtFirDiagnostic { override val diagnosticClass get() = TypealiasExpansionDeprecationError::class val alias: KtSymbol diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 642e1b9774f..43ab619b961 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -31,6 +31,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.lexer.KtKeywordToken import org.jetbrains.kotlin.lexer.KtModifierKeywordToken +import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement.Version import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName @@ -311,6 +312,24 @@ internal class DeprecationImpl( token: KtLifetimeToken, ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.Deprecation +internal class VersionRequirementDeprecationErrorImpl( + override val reference: KtSymbol, + override val version: Version, + override val currentVersion: String, + override val message: String, + firDiagnostic: KtPsiDiagnostic, + token: KtLifetimeToken, +) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.VersionRequirementDeprecationError + +internal class VersionRequirementDeprecationImpl( + override val reference: KtSymbol, + override val version: Version, + override val currentVersion: String, + override val message: String, + firDiagnostic: KtPsiDiagnostic, + token: KtLifetimeToken, +) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.VersionRequirementDeprecation + internal class TypealiasExpansionDeprecationErrorImpl( override val alias: KtSymbol, override val reference: KtSymbol, diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index 538369002c0..fcf9929190f 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.lexer.KtKeywordToken import org.jetbrains.kotlin.lexer.KtModifierKeywordToken +import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName @@ -130,6 +131,20 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { parameter("message") } + val VERSION_REQUIREMENT_DEPRECATION_ERROR by error(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED) { + parameter("reference") + parameter("version") + parameter("currentVersion") + parameter("message") + } + + val VERSION_REQUIREMENT_DEPRECATION by warning(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED) { + parameter("reference") + parameter("version") + parameter("currentVersion") + parameter("message") + } + val TYPEALIAS_EXPANSION_DEPRECATION_ERROR by error(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED) { parameter("alias") parameter("reference") diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 4b5f84397c9..79ca54221fb 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -53,6 +53,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.lexer.KtKeywordToken import org.jetbrains.kotlin.lexer.KtModifierKeywordToken +import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement.Version import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName @@ -161,6 +162,8 @@ object FirErrors { val NO_THIS by error0() val DEPRECATION_ERROR by error2, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED) val DEPRECATION by warning2, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED) + val VERSION_REQUIREMENT_DEPRECATION_ERROR by error4, Version, String, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED) + val VERSION_REQUIREMENT_DEPRECATION by warning4, Version, String, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED) val TYPEALIAS_EXPANSION_DEPRECATION_ERROR by error3, FirBasedSymbol<*>, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED) val TYPEALIAS_EXPANSION_DEPRECATION by warning3, FirBasedSymbol<*>, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED) val API_NOT_AVAILABLE by error2(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED) 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 516176d08fb..c70a02a5360 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 @@ -8,17 +8,23 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.KtRealSourceElementKind import org.jetbrains.kotlin.KtSourceElement +import org.jetbrains.kotlin.config.KotlinCompilerVersion import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.isLhsOfAssignment import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.declarations.FutureApiDeprecationInfo -import org.jetbrains.kotlin.fir.analysis.checkers.isLhsOfAssignment +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.* +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.calleeReference +import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.references.resolved import org.jetbrains.kotlin.fir.resolve.firClassLike import org.jetbrains.kotlin.fir.resolve.typeAliasForConstructor @@ -26,6 +32,7 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol 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.metadata.ProtoBuf import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue @@ -97,13 +104,42 @@ object FirDeprecationChecker : FirBasicExpressionChecker() { reporter: DiagnosticReporter, context: CheckerContext, ) { - if (deprecationInfo is FutureApiDeprecationInfo) { - reportApiNotAvailable(source, deprecationInfo, reporter, context) - } else { - reportDeprecation(source, referencedSymbol, isTypealiasExpansion, deprecationInfo, reporter, context) + when (deprecationInfo) { + is FutureApiDeprecationInfo -> reportApiNotAvailable(source, deprecationInfo, reporter, context) + is RequireKotlinDeprecationInfo -> reportVersionRequirementDeprecation(source, referencedSymbol, deprecationInfo, reporter, context) + else -> reportDeprecation(source, referencedSymbol, isTypealiasExpansion, deprecationInfo, reporter, context) } } + private fun reportVersionRequirementDeprecation( + source: KtSourceElement?, + referencedSymbol: FirBasedSymbol<*>, + deprecationInfo: RequireKotlinDeprecationInfo, + reporter: DiagnosticReporter, + context: CheckerContext, + ) { + val diagnostic = when (deprecationInfo.deprecationLevel) { + DeprecationLevelValue.WARNING -> FirErrors.VERSION_REQUIREMENT_DEPRECATION + else -> FirErrors.VERSION_REQUIREMENT_DEPRECATION_ERROR + } + val languageVersionSettings = context.session.languageVersionSettings + val currentVersionString = when (deprecationInfo.versionRequirement.kind) { + ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION -> KotlinCompilerVersion.VERSION + ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION -> languageVersionSettings.languageVersion.versionString + ProtoBuf.VersionRequirement.VersionKind.API_VERSION -> languageVersionSettings.apiVersion.versionString + } + + reporter.reportOn( + source, + diagnostic, + referencedSymbol, + deprecationInfo.versionRequirement.version, + currentVersionString, + deprecationInfo.message ?: "", + context + ) + } + private fun reportDeprecation( source: KtSourceElement?, referencedSymbol: FirBasedSymbol<*>, diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt index b7cf757770c..a795ba51f6f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.renderReadableWithFqNames +import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId @@ -33,7 +34,8 @@ object FirDiagnosticRenderers { val SYMBOL = Renderer { symbol: FirBasedSymbol<*> -> when (symbol) { is FirClassLikeSymbol<*>, - is FirCallableSymbol<*> -> FirRenderer( + is FirCallableSymbol<*>, + -> FirRenderer( typeRenderer = ConeTypeRenderer(), idRenderer = ConeIdShortRenderer(), classMemberRenderer = FirNoClassMemberRenderer(), @@ -179,4 +181,12 @@ object FirDiagnosticRenderers { } val FUNCTIONAL_TYPE_KINDS = KtDiagnosticRenderers.COLLECTION(FUNCTIONAL_TYPE_KIND) + + val REQUIRE_KOTLIN_VERSION = Renderer { version: VersionRequirement.Version -> + if (version == VersionRequirement.Version.INFINITY) "" else " is only available since Kotlin ${version.asString()} and" + } + + val OPTIONAL_SENTENCE = Renderer { it: String? -> + if (!it.isNullOrBlank()) " $it." else "" + } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt index f92a545fc9b..e3afe17b6d9 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt @@ -27,10 +27,12 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FUNC import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.MODULE_DATA import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NAME_OF_CONTAINING_DECLARATION_OR_FILE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NAME_OF_DECLARATION_OR_FILE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.OPTIONAL_SENTENCE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT_NAME import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_COLLECTION_OF_TYPES import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_TYPE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.REQUIRE_KOTLIN_VERSION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOLS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOLS_ON_NEWLINE_WITH_INDENT @@ -183,6 +185,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_SINCE_ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_TYPE_PARAMETER_SYNTAX import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATION_ERROR +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VERSION_REQUIREMENT_DEPRECATION +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VERSION_REQUIREMENT_DEPRECATION_ERROR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DESERIALIZATION_ERROR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DIVISION_BY_ZERO import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DSL_SCOPE_VIOLATION @@ -697,6 +701,8 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() { map.put(VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER, "''{0}'' on secondary constructor parameter is not allowed", TO_STRING) map.put(DEPRECATION, "''{0}'' is deprecated. {1}", SYMBOL, STRING) map.put(DEPRECATION_ERROR, "''{0}'' is deprecated. {1}", SYMBOL, STRING) + map.put(VERSION_REQUIREMENT_DEPRECATION, "''{0}''{1} should not be used in Kotlin {2}.{3}", SYMBOL, REQUIRE_KOTLIN_VERSION, STRING, OPTIONAL_SENTENCE) + map.put(VERSION_REQUIREMENT_DEPRECATION_ERROR, "''{0}''{1} cannot be used in Kotlin {2}.{3}", SYMBOL, REQUIRE_KOTLIN_VERSION, STRING, OPTIONAL_SENTENCE) map.put(TYPEALIAS_EXPANSION_DEPRECATION, "''{0}'' uses ''{1}'', which is deprecated. {2}", SYMBOL, SYMBOL, STRING) map.put(TYPEALIAS_EXPANSION_DEPRECATION_ERROR, "''{0}'' uses ''{1}'', which is an error. {2}", SYMBOL, SYMBOL, STRING) diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt index 95eda35e7e0..1f14856b1dd 100644 --- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt +++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt @@ -113,6 +113,8 @@ fun deserializeClassToSymbol( } } + val versionRequirements = VersionRequirement.create(classProto, context) + buildRegularClass { this.moduleData = moduleData this.origin = origin @@ -140,7 +142,7 @@ fun deserializeClassToSymbol( ) addDeclarations( - classProto.propertiesInOrder(context).map { + classProto.propertiesInOrder(versionRequirements).map { classDeserializer.loadProperty(it, classProto, symbol) } ) @@ -225,7 +227,7 @@ fun deserializeClassToSymbol( context.annotationDeserializer.loadClassAnnotations(classProto, context.nameResolver) ) - versionRequirementsTable = context.versionRequirementTable + this.versionRequirements = versionRequirements sourceElement = containerSource @@ -296,9 +298,8 @@ fun FirRegularClassBuilder.addCloneForArrayIfNeeded(classId: ClassId, dispatchRe } } -private fun ProtoBuf.ClassOrBuilder.propertiesInOrder(context: FirDeserializationContext): List { +private fun ProtoBuf.ClassOrBuilder.propertiesInOrder(versionRequirements: List): List { val properties = propertyList - val versionRequirements = VersionRequirement.create(this, context.nameResolver, context.versionRequirementTable) if (versionRequirements.any { it.version.major >= 2 }) return properties val order = getExtension(SerializationPluginMetadataExtensions.propertiesNamesInProgramOrder) .takeIf { it.isNotEmpty() } diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirDeserializationUtils.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirDeserializationUtils.kt new file mode 100644 index 00000000000..8db180332fc --- /dev/null +++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirDeserializationUtils.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.deserialization + +import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement +import org.jetbrains.kotlin.protobuf.MessageLiteOrBuilder + +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +internal fun VersionRequirement.Companion.create(proto: MessageLiteOrBuilder, context: FirDeserializationContext): List = + create(proto, context.nameResolver, context.versionRequirementTable) diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt index 9569fd91569..867cd9999a9 100644 --- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt +++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt @@ -204,6 +204,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { val classId = ClassId(c.packageFqName, name) val symbol = preComputedSymbol ?: FirTypeAliasSymbol(classId) val local = c.childContext(proto.typeParameterList, containingDeclarationSymbol = symbol) + val versionRequirements = VersionRequirement.create(proto, c) return buildTypeAlias { moduleData = c.moduleData origin = FirDeclarationOrigin.Library @@ -223,8 +224,9 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { expandedTypeRef = proto.underlyingType(c.typeTable).toTypeRef(local) resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES typeParameters += local.typeDeserializer.ownTypeParameters.map { it.fir } + deprecationsProvider = annotations.getDeprecationsProviderFromAnnotations(c.session, fromJava = false, versionRequirements) }.apply { - versionRequirementsTable = c.versionRequirementTable + this.versionRequirements = versionRequirements sourceElement = c.containerSource } } @@ -257,7 +259,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { dispatchReceiverType = c.dispatchReceiver this.propertySymbol = propertySymbol }.apply { - versionRequirementsTable = c.versionRequirementTable + this.versionRequirements = VersionRequirement.create(proto, c) } } else { FirDefaultPropertyGetter( @@ -317,7 +319,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { ) this.propertySymbol = propertySymbol }.apply { - versionRequirementsTable = c.versionRequirementTable + this.versionRequirements = VersionRequirement.create(proto, c) } } else { FirDefaultPropertySetter( @@ -375,6 +377,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { val propertyModality = ProtoEnumFlags.modality(Flags.MODALITY.get(flags)) val isVar = Flags.IS_VAR.get(flags) + val versionRequirements = VersionRequirement.create(proto, c) return buildProperty { moduleData = c.moduleData origin = FirDeclarationOrigin.Library @@ -463,12 +466,12 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { } else -> null } - deprecationsProvider = annotations.getDeprecationsProviderFromAnnotations(c.session, fromJava = false) proto.contextReceiverTypes(c.typeTable).mapTo(contextReceivers, ::loadContextReceiver) }.apply { initializer?.replaceTypeRef(returnTypeRef) - versionRequirementsTable = c.versionRequirementTable + this.versionRequirements = versionRequirements + replaceDeprecationsProvider(getDeprecationsProvider(c.session)) setLazyPublishedVisibility(c.session) getter?.setLazyPublishedVisibility(annotations, this, c.session) setter?.setLazyPublishedVisibility(annotations, this, c.session) @@ -509,6 +512,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { val symbol = FirNamedFunctionSymbol(callableId) val local = c.childContext(proto.typeParameterList, containingDeclarationSymbol = symbol) + val versionRequirements = VersionRequirement.create(proto, c) val simpleFunction = buildSimpleFunction { moduleData = c.moduleData origin = deserializationOrigin @@ -551,12 +555,12 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { ) annotations += c.annotationDeserializer.loadFunctionAnnotations(c.containerSource, proto, local.nameResolver, local.typeTable) - deprecationsProvider = annotations.getDeprecationsProviderFromAnnotations(c.session, fromJava = false) + deprecationsProvider = annotations.getDeprecationsProviderFromAnnotations(c.session, fromJava = false, versionRequirements) this.containerSource = c.containerSource proto.contextReceiverTypes(c.typeTable).mapTo(contextReceivers, ::loadContextReceiver) }.apply { - versionRequirementsTable = c.versionRequirementTable + this.versionRequirements = versionRequirements setLazyPublishedVisibility(c.session) } if (proto.hasContract()) { @@ -640,7 +644,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { contextReceivers.addAll(createContextReceiversForClass(classProto)) }.build().apply { containingClassForStaticMemberAttr = c.dispatchReceiver!!.lookupTag - versionRequirementsTable = c.versionRequirementTable + this.versionRequirements = VersionRequirement.create(proto, c) setLazyPublishedVisibility(c.session) } } @@ -688,8 +692,6 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { callableKind, index, ) - }.apply { - versionRequirementsTable = c.versionRequirementTable } }.toList() } 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 4706e4135a0..5931a5c302a 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 @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.forEachType import org.jetbrains.kotlin.fir.types.toSymbol +import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds.Annotations.ParameterNames @@ -115,9 +116,14 @@ fun FirAnnotationContainer.extractDeprecationInfoPerUseSite( getterAnnotations: List? = null, setterAnnotations: List? = null, ): DeprecationAnnotationInfoPerUseSiteStorage { - val fromJava = this is FirDeclaration && this.isJavaOrEnhancement + var fromJava = false + var versionRequirements: List? = null + if (this is FirDeclaration) { + fromJava = this.isJavaOrEnhancement + versionRequirements = this.versionRequirements + } return buildDeprecationAnnotationInfoPerUseSiteStorage { - add((customAnnotations ?: annotations).extractDeprecationAnnotationInfoPerUseSite(fromJava)) + add((customAnnotations ?: annotations).extractDeprecationAnnotationInfoPerUseSite(fromJava, versionRequirements)) if (this@extractDeprecationInfoPerUseSite is FirProperty) { add( getDeprecationsAnnotationInfoByUseSiteFromAccessors( @@ -170,9 +176,10 @@ fun getDeprecationsAnnotationInfoByUseSiteFromAccessors( fun List.getDeprecationsProviderFromAnnotations( session: FirSession, - fromJava: Boolean + fromJava: Boolean, + versionRequirements: List? = null, ): DeprecationsProvider { - val deprecationAnnotationByUseSite = extractDeprecationAnnotationInfoPerUseSite(fromJava) + val deprecationAnnotationByUseSite = extractDeprecationAnnotationInfoPerUseSite(fromJava, versionRequirements) return deprecationAnnotationByUseSite.toDeprecationsProvider(session.firCachesFactory) } @@ -251,7 +258,10 @@ val deprecationAnnotationSimpleNames: Set = setOf( StandardClassIds.Annotations.SinceKotlin.shortClassName.asString(), ) -private fun List.extractDeprecationAnnotationInfoPerUseSite(fromJava: Boolean): DeprecationAnnotationInfoPerUseSiteStorage { +private fun List.extractDeprecationAnnotationInfoPerUseSite( + fromJava: Boolean, + versionRequirements: List?, +): DeprecationAnnotationInfoPerUseSiteStorage { // NB: We can't expand typealiases (`toAnnotationClassId`), because it // requires `lookupTag.tySymbol()`, but we can have cycles in annotations. // See the commit message for an example. @@ -298,6 +308,10 @@ private fun List.extractDeprecationAnnotationInfoPerUseSite(fromJ add(deprecated.useSiteTarget, deprecatedInfo) } } + + versionRequirements?.forEach { + add(null, RequireKotlinInfo(it)) + } } } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/DeprecationsProvider.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/DeprecationsProvider.kt index b5982b5e9cf..ce46501c3a3 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/DeprecationsProvider.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/DeprecationsProvider.kt @@ -11,9 +11,11 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.fir.caches.FirCache import org.jetbrains.kotlin.fir.caches.FirCachesFactory import org.jetbrains.kotlin.fir.caches.createCache +import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue import org.jetbrains.kotlin.resolve.deprecation.SimpleDeprecationInfo +import org.jetbrains.kotlin.resolve.deprecation.isFulfilled import org.jetbrains.kotlin.utils.addToStdlib.runUnless abstract class DeprecationsProvider { @@ -55,8 +57,8 @@ object UnresolvedDeprecationProvider : DeprecationsProvider() { } } -sealed interface DeprecationAnnotationInfo { - fun computeDeprecationInfo(languageVersionSettings: LanguageVersionSettings): DeprecationInfo? +sealed class DeprecationAnnotationInfo { + abstract fun computeDeprecationInfo(languageVersionSettings: LanguageVersionSettings): DeprecationInfo? } data class FutureApiDeprecationInfo( @@ -67,7 +69,30 @@ data class FutureApiDeprecationInfo( override val message: String? get() = null } -class SinceKotlinInfo(val sinceVersion: ApiVersion) : DeprecationAnnotationInfo { +data class RequireKotlinDeprecationInfo( + override val deprecationLevel: DeprecationLevelValue, + val versionRequirement: VersionRequirement +) : DeprecationInfo() { + override val message: String? get() = versionRequirement.message + override val propagatesToOverrides: Boolean get() = false +} + +class RequireKotlinInfo(private val versionRequirement: VersionRequirement) : DeprecationAnnotationInfo() { + override fun computeDeprecationInfo(languageVersionSettings: LanguageVersionSettings): DeprecationInfo? { + return runUnless(versionRequirement.isFulfilled(languageVersionSettings)) { + RequireKotlinDeprecationInfo( + deprecationLevel = when (versionRequirement.level) { + DeprecationLevel.WARNING -> DeprecationLevelValue.WARNING + DeprecationLevel.ERROR -> DeprecationLevelValue.ERROR + DeprecationLevel.HIDDEN -> DeprecationLevelValue.HIDDEN + }, + versionRequirement = versionRequirement + ) + } + } +} + +class SinceKotlinInfo(val sinceVersion: ApiVersion) : DeprecationAnnotationInfo() { override fun computeDeprecationInfo(languageVersionSettings: LanguageVersionSettings): DeprecationInfo? { return runUnless(sinceVersion <= languageVersionSettings.apiVersion) { FutureApiDeprecationInfo( @@ -83,7 +108,7 @@ class DeprecatedInfo( val level: DeprecationLevelValue, val propagatesToOverride: Boolean, val message: String? -) : DeprecationAnnotationInfo { +) : DeprecationAnnotationInfo() { override fun computeDeprecationInfo(languageVersionSettings: LanguageVersionSettings): DeprecationInfo { return SimpleDeprecationInfo( level, @@ -99,7 +124,7 @@ class DeprecatedSinceKotlinInfo( val hiddenVersion: ApiVersion?, val message: String?, val propagatesToOverride: Boolean -) : DeprecationAnnotationInfo { +) : DeprecationAnnotationInfo() { override fun computeDeprecationInfo(languageVersionSettings: LanguageVersionSettings): DeprecationInfo? { fun ApiVersion.takeLevelIfDeprecated(level: DeprecationLevelValue) = level.takeIf { this <= languageVersionSettings.apiVersion } diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/declarations/FirVersionRequirementsTableKey.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirVersionRequirementsTableKey.kt similarity index 60% rename from compiler/fir/semantics/src/org/jetbrains/kotlin/fir/declarations/FirVersionRequirementsTableKey.kt rename to compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirVersionRequirementsTableKey.kt index b3742196f76..64306a5af06 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/declarations/FirVersionRequirementsTableKey.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirVersionRequirementsTableKey.kt @@ -1,12 +1,12 @@ /* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.fir.declarations -import org.jetbrains.kotlin.metadata.deserialization.VersionRequirementTable +import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement object FirVersionRequirementsTableKey : FirDeclarationDataKey() -var FirDeclaration.versionRequirementsTable: VersionRequirementTable? by FirDeclarationDataRegistry.data(FirVersionRequirementsTableKey) +var FirDeclaration.versionRequirements: List? by FirDeclarationDataRegistry.data(FirVersionRequirementsTableKey) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirClassLikeSymbol.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirClassLikeSymbol.kt index 7f9ccb14273..1f6d3e08ea9 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirClassLikeSymbol.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirClassLikeSymbol.kt @@ -30,7 +30,7 @@ sealed class FirClassLikeSymbol( val name get() = classId.shortClassName fun getOwnDeprecation(languageVersionSettings: LanguageVersionSettings): DeprecationsPerUseSite? { - if (annotations.isEmpty()) return null + if (annotations.isEmpty() && fir.versionRequirements.isNullOrEmpty()) return null lazyResolveToPhase(FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS) return fir.deprecationsProvider.getDeprecationsInfo(languageVersionSettings) } diff --git a/compiler/frontend.common/src/org/jetbrains/kotlin/resolve/deprecation/CommonDeprecationUtils.kt b/compiler/frontend.common/src/org/jetbrains/kotlin/resolve/deprecation/CommonDeprecationUtils.kt new file mode 100644 index 00000000000..954ef66abe6 --- /dev/null +++ b/compiler/frontend.common/src/org/jetbrains/kotlin/resolve/deprecation/CommonDeprecationUtils.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.resolve.deprecation + +import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.config.MavenComparableVersion +import org.jetbrains.kotlin.metadata.ProtoBuf +import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement + +fun VersionRequirement.isFulfilled(languageVersionSettings: LanguageVersionSettings): Boolean { + val requiredVersion = createVersion(version.asString()) + + val currentVersion = when (kind) { + ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION -> + MavenComparableVersion(languageVersionSettings.languageVersion.versionString) + ProtoBuf.VersionRequirement.VersionKind.API_VERSION -> + languageVersionSettings.apiVersion.version + ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION -> + KotlinCompilerVersion.getVersion()?.substringBefore('-')?.let(::createVersion) + else -> null + } + + return currentVersion == null || currentVersion >= requiredVersion +} + +private fun createVersion(version: String): MavenComparableVersion? = try { + MavenComparableVersion(version) +} catch (e: Exception) { + null +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/DeprecationResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/DeprecationResolver.kt index f6323a6acd9..5d9083662e8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/DeprecationResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/DeprecationResolver.kt @@ -11,7 +11,6 @@ import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.impl.DescriptorDerivedFromTypeAlias import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor -import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.Call import org.jetbrains.kotlin.psi.KtElement @@ -300,29 +299,13 @@ class DeprecationResolver( (target as? CallableDescriptor)?.getUserData(DEPRECATED_FUNCTION_KEY) private fun getDeprecationByVersionRequirement(target: DeclarationDescriptor): List { - fun createVersion(version: String): MavenComparableVersion? = try { - MavenComparableVersion(version) - } catch (e: Exception) { - null - } - val versionRequirements = (target as? DeserializedMemberDescriptor)?.versionRequirements ?: (target as? DeserializedClassDescriptor)?.versionRequirements ?: return emptyList() return versionRequirements.mapNotNull { versionRequirement -> - val requiredVersion = createVersion(versionRequirement.version.asString()) - val currentVersion = when (versionRequirement.kind) { - ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION -> - MavenComparableVersion(languageVersionSettings.languageVersion.versionString) - ProtoBuf.VersionRequirement.VersionKind.API_VERSION -> - languageVersionSettings.apiVersion.version - ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION -> - KotlinCompilerVersion.getVersion()?.substringBefore('-')?.let(::createVersion) - else -> null - } - if (currentVersion != null && currentVersion < requiredVersion) + if (!versionRequirement.isFulfilled(this.languageVersionSettings)) DeprecatedByVersionRequirement(versionRequirement, target) else null diff --git a/compiler/testData/cli/jvm/requireKotlinCompilerVersionK2.args b/compiler/testData/cli/jvm/requireKotlinCompilerVersionK2.args new file mode 100644 index 00000000000..b05930b28d0 --- /dev/null +++ b/compiler/testData/cli/jvm/requireKotlinCompilerVersionK2.args @@ -0,0 +1,7 @@ +$TESTDATA_DIR$/requireKotlinCompilerVersion.kt +-classpath +$TESTDATA_DIR$/requireKotlinCompilerVersion +-d +$TEMP_DIR$ +-language-version +2.0 diff --git a/compiler/testData/cli/jvm/requireKotlinCompilerVersionK2.out b/compiler/testData/cli/jvm/requireKotlinCompilerVersionK2.out new file mode 100644 index 00000000000..d9729c6a851 --- /dev/null +++ b/compiler/testData/cli/jvm/requireKotlinCompilerVersionK2.out @@ -0,0 +1,8 @@ +warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features +compiler/testData/cli/jvm/requireKotlinCompilerVersion.kt:12:8: error: 'class Foo : Any' is only available since Kotlin 9.9.90 and cannot be used in Kotlin $VERSION$. +import test.access.Foo + ^ +compiler/testData/cli/jvm/requireKotlinCompilerVersion.kt:15:5: error: 'constructor(): Foo' is only available since Kotlin 9.9.90 and cannot be used in Kotlin $VERSION$. + Foo() + ^ +COMPILATION_ERROR diff --git a/compiler/testData/diagnostics/testsWithStdLib/typealias/exceptionTypeAliasesInvisibleWithApiVersion1_0.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/typealias/exceptionTypeAliasesInvisibleWithApiVersion1_0.fir.kt index ac7a8639686..71525705c96 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/typealias/exceptionTypeAliasesInvisibleWithApiVersion1_0.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/typealias/exceptionTypeAliasesInvisibleWithApiVersion1_0.fir.kt @@ -1,5 +1,8 @@ // !LANGUAGE: +TypeAliases // !API_VERSION: 1.0 +// IGNORE_DIAGNOSTIC_API +// IGNORE_REVERSED_RESOLVE +// ^KT-60996 // FILE: test.kt -val fooException = Exception("foo") -val barException = kotlin.Exception("bar") +val fooException = Exception("foo") +val barException = kotlin.Exception("bar") diff --git a/compiler/testData/diagnostics/testsWithStdLib/typealias/exceptionTypeAliasesInvisibleWithApiVersion1_0.kt b/compiler/testData/diagnostics/testsWithStdLib/typealias/exceptionTypeAliasesInvisibleWithApiVersion1_0.kt index 80cc7440061..8e8fe871cc6 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/typealias/exceptionTypeAliasesInvisibleWithApiVersion1_0.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/typealias/exceptionTypeAliasesInvisibleWithApiVersion1_0.kt @@ -1,5 +1,8 @@ // !LANGUAGE: +TypeAliases // !API_VERSION: 1.0 +// IGNORE_DIAGNOSTIC_API +// IGNORE_REVERSED_RESOLVE +// ^KT-60996 // FILE: test.kt val fooException = Exception("foo") val barException = kotlin.Exception("bar") diff --git a/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java index 2833be66f95..de2172a7ac5 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java @@ -1100,6 +1100,11 @@ public class CliTestGenerated extends AbstractCliTest { runTest("compiler/testData/cli/jvm/requireKotlinCompilerVersion.args"); } + @TestMetadata("requireKotlinCompilerVersionK2.args") + public void testRequireKotlinCompilerVersionK2() throws Exception { + runTest("compiler/testData/cli/jvm/requireKotlinCompilerVersionK2.args"); + } + @TestMetadata("resultInReturnTypeSupportedByDefault15.args") public void testResultInReturnTypeSupportedByDefault15() throws Exception { runTest("compiler/testData/cli/jvm/resultInReturnTypeSupportedByDefault15.args");