[FIR] Implement VERSION_REQUIREMENT_DEPRECATION diagnostics
This commit is contained in:
committed by
Space Team
parent
65ea9697ab
commit
09f895efe6
+2
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
|||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
|
import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -370,6 +371,7 @@ internal object FirToKtConversionCreator {
|
|||||||
CallableId::class,
|
CallableId::class,
|
||||||
ClassKind::class,
|
ClassKind::class,
|
||||||
FunctionTypeKind::class,
|
FunctionTypeKind::class,
|
||||||
|
VersionRequirement.Version::class,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val KType.kClass: KClass<*>
|
private val KType.kClass: KClass<*>
|
||||||
|
|||||||
+20
@@ -327,6 +327,26 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
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 ->
|
add(FirErrors.TYPEALIAS_EXPANSION_DEPRECATION_ERROR) { firDiagnostic ->
|
||||||
TypealiasExpansionDeprecationErrorImpl(
|
TypealiasExpansionDeprecationErrorImpl(
|
||||||
firSymbolBuilder.buildSymbol(firDiagnostic.a),
|
firSymbolBuilder.buildSymbol(firDiagnostic.a),
|
||||||
|
|||||||
+17
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
|||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
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.CallableId
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -271,6 +272,22 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
val message: String
|
val message: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface VersionRequirementDeprecationError : KtFirDiagnostic<PsiElement> {
|
||||||
|
override val diagnosticClass get() = VersionRequirementDeprecationError::class
|
||||||
|
val reference: KtSymbol
|
||||||
|
val version: Version
|
||||||
|
val currentVersion: String
|
||||||
|
val message: String
|
||||||
|
}
|
||||||
|
|
||||||
|
interface VersionRequirementDeprecation : KtFirDiagnostic<PsiElement> {
|
||||||
|
override val diagnosticClass get() = VersionRequirementDeprecation::class
|
||||||
|
val reference: KtSymbol
|
||||||
|
val version: Version
|
||||||
|
val currentVersion: String
|
||||||
|
val message: String
|
||||||
|
}
|
||||||
|
|
||||||
interface TypealiasExpansionDeprecationError : KtFirDiagnostic<PsiElement> {
|
interface TypealiasExpansionDeprecationError : KtFirDiagnostic<PsiElement> {
|
||||||
override val diagnosticClass get() = TypealiasExpansionDeprecationError::class
|
override val diagnosticClass get() = TypealiasExpansionDeprecationError::class
|
||||||
val alias: KtSymbol
|
val alias: KtSymbol
|
||||||
|
|||||||
+19
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
|||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
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.CallableId
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -311,6 +312,24 @@ internal class DeprecationImpl(
|
|||||||
token: KtLifetimeToken,
|
token: KtLifetimeToken,
|
||||||
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.Deprecation
|
) : KtAbstractFirDiagnostic<PsiElement>(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<PsiElement>(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<PsiElement>(firDiagnostic, token), KtFirDiagnostic.VersionRequirementDeprecation
|
||||||
|
|
||||||
internal class TypealiasExpansionDeprecationErrorImpl(
|
internal class TypealiasExpansionDeprecationErrorImpl(
|
||||||
override val alias: KtSymbol,
|
override val alias: KtSymbol,
|
||||||
override val reference: KtSymbol,
|
override val reference: KtSymbol,
|
||||||
|
|||||||
+15
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.*
|
|||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
|
import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -130,6 +131,20 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
parameter<String>("message")
|
parameter<String>("message")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val VERSION_REQUIREMENT_DEPRECATION_ERROR by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED) {
|
||||||
|
parameter<Symbol>("reference")
|
||||||
|
parameter<VersionRequirement.Version>("version")
|
||||||
|
parameter<String>("currentVersion")
|
||||||
|
parameter<String>("message")
|
||||||
|
}
|
||||||
|
|
||||||
|
val VERSION_REQUIREMENT_DEPRECATION by warning<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED) {
|
||||||
|
parameter<Symbol>("reference")
|
||||||
|
parameter<VersionRequirement.Version>("version")
|
||||||
|
parameter<String>("currentVersion")
|
||||||
|
parameter<String>("message")
|
||||||
|
}
|
||||||
|
|
||||||
val TYPEALIAS_EXPANSION_DEPRECATION_ERROR by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED) {
|
val TYPEALIAS_EXPANSION_DEPRECATION_ERROR by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED) {
|
||||||
parameter<Symbol>("alias")
|
parameter<Symbol>("alias")
|
||||||
parameter<Symbol>("reference")
|
parameter<Symbol>("reference")
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
|||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
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.CallableId
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -161,6 +162,8 @@ object FirErrors {
|
|||||||
val NO_THIS by error0<PsiElement>()
|
val NO_THIS by error0<PsiElement>()
|
||||||
val DEPRECATION_ERROR by error2<PsiElement, FirBasedSymbol<*>, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
val DEPRECATION_ERROR by error2<PsiElement, FirBasedSymbol<*>, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
val DEPRECATION by warning2<PsiElement, FirBasedSymbol<*>, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
val DEPRECATION by warning2<PsiElement, FirBasedSymbol<*>, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
|
val VERSION_REQUIREMENT_DEPRECATION_ERROR by error4<PsiElement, FirBasedSymbol<*>, Version, String, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
|
val VERSION_REQUIREMENT_DEPRECATION by warning4<PsiElement, FirBasedSymbol<*>, Version, String, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
val TYPEALIAS_EXPANSION_DEPRECATION_ERROR by error3<PsiElement, FirBasedSymbol<*>, FirBasedSymbol<*>, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
val TYPEALIAS_EXPANSION_DEPRECATION_ERROR by error3<PsiElement, FirBasedSymbol<*>, FirBasedSymbol<*>, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
val TYPEALIAS_EXPANSION_DEPRECATION by warning3<PsiElement, FirBasedSymbol<*>, FirBasedSymbol<*>, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
val TYPEALIAS_EXPANSION_DEPRECATION by warning3<PsiElement, FirBasedSymbol<*>, FirBasedSymbol<*>, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
val API_NOT_AVAILABLE by error2<PsiElement, ApiVersion, ApiVersion>(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED)
|
val API_NOT_AVAILABLE by error2<PsiElement, ApiVersion, ApiVersion>(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED)
|
||||||
|
|||||||
+42
-6
@@ -8,17 +8,23 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
|||||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||||
import org.jetbrains.kotlin.KtRealSourceElementKind
|
import org.jetbrains.kotlin.KtRealSourceElementKind
|
||||||
import org.jetbrains.kotlin.KtSourceElement
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
|
import org.jetbrains.kotlin.config.KotlinCompilerVersion
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
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.checkers.toRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.declarations.FutureApiDeprecationInfo
|
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.getDeprecation
|
||||||
import org.jetbrains.kotlin.fir.declarations.getOwnDeprecation
|
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.references.resolved
|
||||||
import org.jetbrains.kotlin.fir.resolve.firClassLike
|
import org.jetbrains.kotlin.fir.resolve.firClassLike
|
||||||
import org.jetbrains.kotlin.fir.resolve.typeAliasForConstructor
|
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.FirClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
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.DeprecationInfo
|
||||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
|
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
|
||||||
|
|
||||||
@@ -97,13 +104,42 @@ object FirDeprecationChecker : FirBasicExpressionChecker() {
|
|||||||
reporter: DiagnosticReporter,
|
reporter: DiagnosticReporter,
|
||||||
context: CheckerContext,
|
context: CheckerContext,
|
||||||
) {
|
) {
|
||||||
if (deprecationInfo is FutureApiDeprecationInfo) {
|
when (deprecationInfo) {
|
||||||
reportApiNotAvailable(source, deprecationInfo, reporter, context)
|
is FutureApiDeprecationInfo -> reportApiNotAvailable(source, deprecationInfo, reporter, context)
|
||||||
} else {
|
is RequireKotlinDeprecationInfo -> reportVersionRequirementDeprecation(source, referencedSymbol, deprecationInfo, reporter, context)
|
||||||
reportDeprecation(source, referencedSymbol, isTypealiasExpansion, 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(
|
private fun reportDeprecation(
|
||||||
source: KtSourceElement?,
|
source: KtSourceElement?,
|
||||||
referencedSymbol: FirBasedSymbol<*>,
|
referencedSymbol: FirBasedSymbol<*>,
|
||||||
|
|||||||
+11
-1
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.renderReadableWithFqNames
|
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.CallableId
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
|
||||||
@@ -33,7 +34,8 @@ object FirDiagnosticRenderers {
|
|||||||
val SYMBOL = Renderer { symbol: FirBasedSymbol<*> ->
|
val SYMBOL = Renderer { symbol: FirBasedSymbol<*> ->
|
||||||
when (symbol) {
|
when (symbol) {
|
||||||
is FirClassLikeSymbol<*>,
|
is FirClassLikeSymbol<*>,
|
||||||
is FirCallableSymbol<*> -> FirRenderer(
|
is FirCallableSymbol<*>,
|
||||||
|
-> FirRenderer(
|
||||||
typeRenderer = ConeTypeRenderer(),
|
typeRenderer = ConeTypeRenderer(),
|
||||||
idRenderer = ConeIdShortRenderer(),
|
idRenderer = ConeIdShortRenderer(),
|
||||||
classMemberRenderer = FirNoClassMemberRenderer(),
|
classMemberRenderer = FirNoClassMemberRenderer(),
|
||||||
@@ -179,4 +181,12 @@ object FirDiagnosticRenderers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val FUNCTIONAL_TYPE_KINDS = KtDiagnosticRenderers.COLLECTION(FUNCTIONAL_TYPE_KIND)
|
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 ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -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.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_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.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
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT_NAME
|
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_COLLECTION_OF_TYPES
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_TYPE
|
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.SYMBOL
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOLS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOLS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOLS_ON_NEWLINE_WITH_INDENT
|
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.DEPRECATED_TYPE_PARAMETER_SYNTAX
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATION
|
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.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.DESERIALIZATION_ERROR
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DIVISION_BY_ZERO
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DIVISION_BY_ZERO
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DSL_SCOPE_VIOLATION
|
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(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, "''{0}'' is deprecated. {1}", SYMBOL, STRING)
|
||||||
map.put(DEPRECATION_ERROR, "''{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, "''{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)
|
map.put(TYPEALIAS_EXPANSION_DEPRECATION_ERROR, "''{0}'' uses ''{1}'', which is an error. {2}", SYMBOL, SYMBOL, STRING)
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -113,6 +113,8 @@ fun deserializeClassToSymbol(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val versionRequirements = VersionRequirement.create(classProto, context)
|
||||||
|
|
||||||
buildRegularClass {
|
buildRegularClass {
|
||||||
this.moduleData = moduleData
|
this.moduleData = moduleData
|
||||||
this.origin = origin
|
this.origin = origin
|
||||||
@@ -140,7 +142,7 @@ fun deserializeClassToSymbol(
|
|||||||
)
|
)
|
||||||
|
|
||||||
addDeclarations(
|
addDeclarations(
|
||||||
classProto.propertiesInOrder(context).map {
|
classProto.propertiesInOrder(versionRequirements).map {
|
||||||
classDeserializer.loadProperty(it, classProto, symbol)
|
classDeserializer.loadProperty(it, classProto, symbol)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -225,7 +227,7 @@ fun deserializeClassToSymbol(
|
|||||||
context.annotationDeserializer.loadClassAnnotations(classProto, context.nameResolver)
|
context.annotationDeserializer.loadClassAnnotations(classProto, context.nameResolver)
|
||||||
)
|
)
|
||||||
|
|
||||||
versionRequirementsTable = context.versionRequirementTable
|
this.versionRequirements = versionRequirements
|
||||||
|
|
||||||
sourceElement = containerSource
|
sourceElement = containerSource
|
||||||
|
|
||||||
@@ -296,9 +298,8 @@ fun FirRegularClassBuilder.addCloneForArrayIfNeeded(classId: ClassId, dispatchRe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ProtoBuf.ClassOrBuilder.propertiesInOrder(context: FirDeserializationContext): List<ProtoBuf.Property> {
|
private fun ProtoBuf.ClassOrBuilder.propertiesInOrder(versionRequirements: List<VersionRequirement>): List<ProtoBuf.Property> {
|
||||||
val properties = propertyList
|
val properties = propertyList
|
||||||
val versionRequirements = VersionRequirement.create(this, context.nameResolver, context.versionRequirementTable)
|
|
||||||
if (versionRequirements.any { it.version.major >= 2 }) return properties
|
if (versionRequirements.any { it.version.major >= 2 }) return properties
|
||||||
val order = getExtension(SerializationPluginMetadataExtensions.propertiesNamesInProgramOrder)
|
val order = getExtension(SerializationPluginMetadataExtensions.propertiesNamesInProgramOrder)
|
||||||
.takeIf { it.isNotEmpty() }
|
.takeIf { it.isNotEmpty() }
|
||||||
|
|||||||
+17
@@ -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<VersionRequirement> =
|
||||||
|
create(proto, context.nameResolver, context.versionRequirementTable)
|
||||||
+12
-10
@@ -204,6 +204,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
|
|||||||
val classId = ClassId(c.packageFqName, name)
|
val classId = ClassId(c.packageFqName, name)
|
||||||
val symbol = preComputedSymbol ?: FirTypeAliasSymbol(classId)
|
val symbol = preComputedSymbol ?: FirTypeAliasSymbol(classId)
|
||||||
val local = c.childContext(proto.typeParameterList, containingDeclarationSymbol = symbol)
|
val local = c.childContext(proto.typeParameterList, containingDeclarationSymbol = symbol)
|
||||||
|
val versionRequirements = VersionRequirement.create(proto, c)
|
||||||
return buildTypeAlias {
|
return buildTypeAlias {
|
||||||
moduleData = c.moduleData
|
moduleData = c.moduleData
|
||||||
origin = FirDeclarationOrigin.Library
|
origin = FirDeclarationOrigin.Library
|
||||||
@@ -223,8 +224,9 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
|
|||||||
expandedTypeRef = proto.underlyingType(c.typeTable).toTypeRef(local)
|
expandedTypeRef = proto.underlyingType(c.typeTable).toTypeRef(local)
|
||||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
||||||
typeParameters += local.typeDeserializer.ownTypeParameters.map { it.fir }
|
typeParameters += local.typeDeserializer.ownTypeParameters.map { it.fir }
|
||||||
|
deprecationsProvider = annotations.getDeprecationsProviderFromAnnotations(c.session, fromJava = false, versionRequirements)
|
||||||
}.apply {
|
}.apply {
|
||||||
versionRequirementsTable = c.versionRequirementTable
|
this.versionRequirements = versionRequirements
|
||||||
sourceElement = c.containerSource
|
sourceElement = c.containerSource
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,7 +259,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
|
|||||||
dispatchReceiverType = c.dispatchReceiver
|
dispatchReceiverType = c.dispatchReceiver
|
||||||
this.propertySymbol = propertySymbol
|
this.propertySymbol = propertySymbol
|
||||||
}.apply {
|
}.apply {
|
||||||
versionRequirementsTable = c.versionRequirementTable
|
this.versionRequirements = VersionRequirement.create(proto, c)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
FirDefaultPropertyGetter(
|
FirDefaultPropertyGetter(
|
||||||
@@ -317,7 +319,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
|
|||||||
)
|
)
|
||||||
this.propertySymbol = propertySymbol
|
this.propertySymbol = propertySymbol
|
||||||
}.apply {
|
}.apply {
|
||||||
versionRequirementsTable = c.versionRequirementTable
|
this.versionRequirements = VersionRequirement.create(proto, c)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
FirDefaultPropertySetter(
|
FirDefaultPropertySetter(
|
||||||
@@ -375,6 +377,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
|
|||||||
val propertyModality = ProtoEnumFlags.modality(Flags.MODALITY.get(flags))
|
val propertyModality = ProtoEnumFlags.modality(Flags.MODALITY.get(flags))
|
||||||
|
|
||||||
val isVar = Flags.IS_VAR.get(flags)
|
val isVar = Flags.IS_VAR.get(flags)
|
||||||
|
val versionRequirements = VersionRequirement.create(proto, c)
|
||||||
return buildProperty {
|
return buildProperty {
|
||||||
moduleData = c.moduleData
|
moduleData = c.moduleData
|
||||||
origin = FirDeclarationOrigin.Library
|
origin = FirDeclarationOrigin.Library
|
||||||
@@ -463,12 +466,12 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
|
|||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
deprecationsProvider = annotations.getDeprecationsProviderFromAnnotations(c.session, fromJava = false)
|
|
||||||
|
|
||||||
proto.contextReceiverTypes(c.typeTable).mapTo(contextReceivers, ::loadContextReceiver)
|
proto.contextReceiverTypes(c.typeTable).mapTo(contextReceivers, ::loadContextReceiver)
|
||||||
}.apply {
|
}.apply {
|
||||||
initializer?.replaceTypeRef(returnTypeRef)
|
initializer?.replaceTypeRef(returnTypeRef)
|
||||||
versionRequirementsTable = c.versionRequirementTable
|
this.versionRequirements = versionRequirements
|
||||||
|
replaceDeprecationsProvider(getDeprecationsProvider(c.session))
|
||||||
setLazyPublishedVisibility(c.session)
|
setLazyPublishedVisibility(c.session)
|
||||||
getter?.setLazyPublishedVisibility(annotations, this, c.session)
|
getter?.setLazyPublishedVisibility(annotations, this, c.session)
|
||||||
setter?.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 symbol = FirNamedFunctionSymbol(callableId)
|
||||||
val local = c.childContext(proto.typeParameterList, containingDeclarationSymbol = symbol)
|
val local = c.childContext(proto.typeParameterList, containingDeclarationSymbol = symbol)
|
||||||
|
|
||||||
|
val versionRequirements = VersionRequirement.create(proto, c)
|
||||||
val simpleFunction = buildSimpleFunction {
|
val simpleFunction = buildSimpleFunction {
|
||||||
moduleData = c.moduleData
|
moduleData = c.moduleData
|
||||||
origin = deserializationOrigin
|
origin = deserializationOrigin
|
||||||
@@ -551,12 +555,12 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
|
|||||||
)
|
)
|
||||||
annotations +=
|
annotations +=
|
||||||
c.annotationDeserializer.loadFunctionAnnotations(c.containerSource, proto, local.nameResolver, local.typeTable)
|
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
|
this.containerSource = c.containerSource
|
||||||
|
|
||||||
proto.contextReceiverTypes(c.typeTable).mapTo(contextReceivers, ::loadContextReceiver)
|
proto.contextReceiverTypes(c.typeTable).mapTo(contextReceivers, ::loadContextReceiver)
|
||||||
}.apply {
|
}.apply {
|
||||||
versionRequirementsTable = c.versionRequirementTable
|
this.versionRequirements = versionRequirements
|
||||||
setLazyPublishedVisibility(c.session)
|
setLazyPublishedVisibility(c.session)
|
||||||
}
|
}
|
||||||
if (proto.hasContract()) {
|
if (proto.hasContract()) {
|
||||||
@@ -640,7 +644,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
|
|||||||
contextReceivers.addAll(createContextReceiversForClass(classProto))
|
contextReceivers.addAll(createContextReceiversForClass(classProto))
|
||||||
}.build().apply {
|
}.build().apply {
|
||||||
containingClassForStaticMemberAttr = c.dispatchReceiver!!.lookupTag
|
containingClassForStaticMemberAttr = c.dispatchReceiver!!.lookupTag
|
||||||
versionRequirementsTable = c.versionRequirementTable
|
this.versionRequirements = VersionRequirement.create(proto, c)
|
||||||
setLazyPublishedVisibility(c.session)
|
setLazyPublishedVisibility(c.session)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -688,8 +692,6 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
|
|||||||
callableKind,
|
callableKind,
|
||||||
index,
|
index,
|
||||||
)
|
)
|
||||||
}.apply {
|
|
||||||
versionRequirementsTable = c.versionRequirementTable
|
|
||||||
}
|
}
|
||||||
}.toList()
|
}.toList()
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-5
@@ -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.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.forEachType
|
import org.jetbrains.kotlin.fir.types.forEachType
|
||||||
import org.jetbrains.kotlin.fir.types.toSymbol
|
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.Name
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.ParameterNames
|
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.ParameterNames
|
||||||
@@ -115,9 +116,14 @@ fun FirAnnotationContainer.extractDeprecationInfoPerUseSite(
|
|||||||
getterAnnotations: List<FirAnnotation>? = null,
|
getterAnnotations: List<FirAnnotation>? = null,
|
||||||
setterAnnotations: List<FirAnnotation>? = null,
|
setterAnnotations: List<FirAnnotation>? = null,
|
||||||
): DeprecationAnnotationInfoPerUseSiteStorage {
|
): DeprecationAnnotationInfoPerUseSiteStorage {
|
||||||
val fromJava = this is FirDeclaration && this.isJavaOrEnhancement
|
var fromJava = false
|
||||||
|
var versionRequirements: List<VersionRequirement>? = null
|
||||||
|
if (this is FirDeclaration) {
|
||||||
|
fromJava = this.isJavaOrEnhancement
|
||||||
|
versionRequirements = this.versionRequirements
|
||||||
|
}
|
||||||
return buildDeprecationAnnotationInfoPerUseSiteStorage {
|
return buildDeprecationAnnotationInfoPerUseSiteStorage {
|
||||||
add((customAnnotations ?: annotations).extractDeprecationAnnotationInfoPerUseSite(fromJava))
|
add((customAnnotations ?: annotations).extractDeprecationAnnotationInfoPerUseSite(fromJava, versionRequirements))
|
||||||
if (this@extractDeprecationInfoPerUseSite is FirProperty) {
|
if (this@extractDeprecationInfoPerUseSite is FirProperty) {
|
||||||
add(
|
add(
|
||||||
getDeprecationsAnnotationInfoByUseSiteFromAccessors(
|
getDeprecationsAnnotationInfoByUseSiteFromAccessors(
|
||||||
@@ -170,9 +176,10 @@ fun getDeprecationsAnnotationInfoByUseSiteFromAccessors(
|
|||||||
|
|
||||||
fun List<FirAnnotation>.getDeprecationsProviderFromAnnotations(
|
fun List<FirAnnotation>.getDeprecationsProviderFromAnnotations(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
fromJava: Boolean
|
fromJava: Boolean,
|
||||||
|
versionRequirements: List<VersionRequirement>? = null,
|
||||||
): DeprecationsProvider {
|
): DeprecationsProvider {
|
||||||
val deprecationAnnotationByUseSite = extractDeprecationAnnotationInfoPerUseSite(fromJava)
|
val deprecationAnnotationByUseSite = extractDeprecationAnnotationInfoPerUseSite(fromJava, versionRequirements)
|
||||||
return deprecationAnnotationByUseSite.toDeprecationsProvider(session.firCachesFactory)
|
return deprecationAnnotationByUseSite.toDeprecationsProvider(session.firCachesFactory)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,7 +258,10 @@ val deprecationAnnotationSimpleNames: Set<String> = setOf(
|
|||||||
StandardClassIds.Annotations.SinceKotlin.shortClassName.asString(),
|
StandardClassIds.Annotations.SinceKotlin.shortClassName.asString(),
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun List<FirAnnotation>.extractDeprecationAnnotationInfoPerUseSite(fromJava: Boolean): DeprecationAnnotationInfoPerUseSiteStorage {
|
private fun List<FirAnnotation>.extractDeprecationAnnotationInfoPerUseSite(
|
||||||
|
fromJava: Boolean,
|
||||||
|
versionRequirements: List<VersionRequirement>?,
|
||||||
|
): DeprecationAnnotationInfoPerUseSiteStorage {
|
||||||
// NB: We can't expand typealiases (`toAnnotationClassId`), because it
|
// NB: We can't expand typealiases (`toAnnotationClassId`), because it
|
||||||
// requires `lookupTag.tySymbol()`, but we can have cycles in annotations.
|
// requires `lookupTag.tySymbol()`, but we can have cycles in annotations.
|
||||||
// See the commit message for an example.
|
// See the commit message for an example.
|
||||||
@@ -298,6 +308,10 @@ private fun List<FirAnnotation>.extractDeprecationAnnotationInfoPerUseSite(fromJ
|
|||||||
add(deprecated.useSiteTarget, deprecatedInfo)
|
add(deprecated.useSiteTarget, deprecatedInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
versionRequirements?.forEach {
|
||||||
|
add(null, RequireKotlinInfo(it))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+30
-5
@@ -11,9 +11,11 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
|||||||
import org.jetbrains.kotlin.fir.caches.FirCache
|
import org.jetbrains.kotlin.fir.caches.FirCache
|
||||||
import org.jetbrains.kotlin.fir.caches.FirCachesFactory
|
import org.jetbrains.kotlin.fir.caches.FirCachesFactory
|
||||||
import org.jetbrains.kotlin.fir.caches.createCache
|
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.DeprecationInfo
|
||||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
|
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
|
||||||
import org.jetbrains.kotlin.resolve.deprecation.SimpleDeprecationInfo
|
import org.jetbrains.kotlin.resolve.deprecation.SimpleDeprecationInfo
|
||||||
|
import org.jetbrains.kotlin.resolve.deprecation.isFulfilled
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.runUnless
|
import org.jetbrains.kotlin.utils.addToStdlib.runUnless
|
||||||
|
|
||||||
abstract class DeprecationsProvider {
|
abstract class DeprecationsProvider {
|
||||||
@@ -55,8 +57,8 @@ object UnresolvedDeprecationProvider : DeprecationsProvider() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed interface DeprecationAnnotationInfo {
|
sealed class DeprecationAnnotationInfo {
|
||||||
fun computeDeprecationInfo(languageVersionSettings: LanguageVersionSettings): DeprecationInfo?
|
abstract fun computeDeprecationInfo(languageVersionSettings: LanguageVersionSettings): DeprecationInfo?
|
||||||
}
|
}
|
||||||
|
|
||||||
data class FutureApiDeprecationInfo(
|
data class FutureApiDeprecationInfo(
|
||||||
@@ -67,7 +69,30 @@ data class FutureApiDeprecationInfo(
|
|||||||
override val message: String? get() = null
|
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? {
|
override fun computeDeprecationInfo(languageVersionSettings: LanguageVersionSettings): DeprecationInfo? {
|
||||||
return runUnless(sinceVersion <= languageVersionSettings.apiVersion) {
|
return runUnless(sinceVersion <= languageVersionSettings.apiVersion) {
|
||||||
FutureApiDeprecationInfo(
|
FutureApiDeprecationInfo(
|
||||||
@@ -83,7 +108,7 @@ class DeprecatedInfo(
|
|||||||
val level: DeprecationLevelValue,
|
val level: DeprecationLevelValue,
|
||||||
val propagatesToOverride: Boolean,
|
val propagatesToOverride: Boolean,
|
||||||
val message: String?
|
val message: String?
|
||||||
) : DeprecationAnnotationInfo {
|
) : DeprecationAnnotationInfo() {
|
||||||
override fun computeDeprecationInfo(languageVersionSettings: LanguageVersionSettings): DeprecationInfo {
|
override fun computeDeprecationInfo(languageVersionSettings: LanguageVersionSettings): DeprecationInfo {
|
||||||
return SimpleDeprecationInfo(
|
return SimpleDeprecationInfo(
|
||||||
level,
|
level,
|
||||||
@@ -99,7 +124,7 @@ class DeprecatedSinceKotlinInfo(
|
|||||||
val hiddenVersion: ApiVersion?,
|
val hiddenVersion: ApiVersion?,
|
||||||
val message: String?,
|
val message: String?,
|
||||||
val propagatesToOverride: Boolean
|
val propagatesToOverride: Boolean
|
||||||
) : DeprecationAnnotationInfo {
|
) : DeprecationAnnotationInfo() {
|
||||||
override fun computeDeprecationInfo(languageVersionSettings: LanguageVersionSettings): DeprecationInfo? {
|
override fun computeDeprecationInfo(languageVersionSettings: LanguageVersionSettings): DeprecationInfo? {
|
||||||
fun ApiVersion.takeLevelIfDeprecated(level: DeprecationLevelValue) = level.takeIf { this <= languageVersionSettings.apiVersion }
|
fun ApiVersion.takeLevelIfDeprecated(level: DeprecationLevelValue) = level.takeIf { this <= languageVersionSettings.apiVersion }
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -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.
|
* 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
|
package org.jetbrains.kotlin.fir.declarations
|
||||||
|
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.VersionRequirementTable
|
import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement
|
||||||
|
|
||||||
object FirVersionRequirementsTableKey : FirDeclarationDataKey()
|
object FirVersionRequirementsTableKey : FirDeclarationDataKey()
|
||||||
|
|
||||||
var FirDeclaration.versionRequirementsTable: VersionRequirementTable? by FirDeclarationDataRegistry.data(FirVersionRequirementsTableKey)
|
var FirDeclaration.versionRequirements: List<VersionRequirement>? by FirDeclarationDataRegistry.data(FirVersionRequirementsTableKey)
|
||||||
@@ -30,7 +30,7 @@ sealed class FirClassLikeSymbol<D : FirClassLikeDeclaration>(
|
|||||||
val name get() = classId.shortClassName
|
val name get() = classId.shortClassName
|
||||||
|
|
||||||
fun getOwnDeprecation(languageVersionSettings: LanguageVersionSettings): DeprecationsPerUseSite? {
|
fun getOwnDeprecation(languageVersionSettings: LanguageVersionSettings): DeprecationsPerUseSite? {
|
||||||
if (annotations.isEmpty()) return null
|
if (annotations.isEmpty() && fir.versionRequirements.isNullOrEmpty()) return null
|
||||||
lazyResolveToPhase(FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS)
|
lazyResolveToPhase(FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS)
|
||||||
return fir.deprecationsProvider.getDeprecationsInfo(languageVersionSettings)
|
return fir.deprecationsProvider.getDeprecationsInfo(languageVersionSettings)
|
||||||
}
|
}
|
||||||
|
|||||||
+34
@@ -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
|
||||||
|
}
|
||||||
+1
-18
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.config.*
|
|||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.impl.DescriptorDerivedFromTypeAlias
|
import org.jetbrains.kotlin.descriptors.impl.DescriptorDerivedFromTypeAlias
|
||||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.Call
|
import org.jetbrains.kotlin.psi.Call
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
@@ -300,29 +299,13 @@ class DeprecationResolver(
|
|||||||
(target as? CallableDescriptor)?.getUserData(DEPRECATED_FUNCTION_KEY)
|
(target as? CallableDescriptor)?.getUserData(DEPRECATED_FUNCTION_KEY)
|
||||||
|
|
||||||
private fun getDeprecationByVersionRequirement(target: DeclarationDescriptor): List<DeprecatedByVersionRequirement> {
|
private fun getDeprecationByVersionRequirement(target: DeclarationDescriptor): List<DeprecatedByVersionRequirement> {
|
||||||
fun createVersion(version: String): MavenComparableVersion? = try {
|
|
||||||
MavenComparableVersion(version)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
val versionRequirements =
|
val versionRequirements =
|
||||||
(target as? DeserializedMemberDescriptor)?.versionRequirements
|
(target as? DeserializedMemberDescriptor)?.versionRequirements
|
||||||
?: (target as? DeserializedClassDescriptor)?.versionRequirements
|
?: (target as? DeserializedClassDescriptor)?.versionRequirements
|
||||||
?: return emptyList()
|
?: return emptyList()
|
||||||
|
|
||||||
return versionRequirements.mapNotNull { versionRequirement ->
|
return versionRequirements.mapNotNull { versionRequirement ->
|
||||||
val requiredVersion = createVersion(versionRequirement.version.asString())
|
if (!versionRequirement.isFulfilled(this.languageVersionSettings))
|
||||||
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)
|
|
||||||
DeprecatedByVersionRequirement(versionRequirement, target)
|
DeprecatedByVersionRequirement(versionRequirement, target)
|
||||||
else
|
else
|
||||||
null
|
null
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
$TESTDATA_DIR$/requireKotlinCompilerVersion.kt
|
||||||
|
-classpath
|
||||||
|
$TESTDATA_DIR$/requireKotlinCompilerVersion
|
||||||
|
-d
|
||||||
|
$TEMP_DIR$
|
||||||
|
-language-version
|
||||||
|
2.0
|
||||||
@@ -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
|
||||||
+5
-2
@@ -1,5 +1,8 @@
|
|||||||
// !LANGUAGE: +TypeAliases
|
// !LANGUAGE: +TypeAliases
|
||||||
// !API_VERSION: 1.0
|
// !API_VERSION: 1.0
|
||||||
|
// IGNORE_DIAGNOSTIC_API
|
||||||
|
// IGNORE_REVERSED_RESOLVE
|
||||||
|
// ^KT-60996
|
||||||
// FILE: test.kt
|
// FILE: test.kt
|
||||||
val fooException = Exception("foo")
|
val fooException = <!API_NOT_AVAILABLE!>Exception<!>("foo")
|
||||||
val barException = kotlin.Exception("bar")
|
val barException = kotlin.<!API_NOT_AVAILABLE!>Exception<!>("bar")
|
||||||
|
|||||||
+3
@@ -1,5 +1,8 @@
|
|||||||
// !LANGUAGE: +TypeAliases
|
// !LANGUAGE: +TypeAliases
|
||||||
// !API_VERSION: 1.0
|
// !API_VERSION: 1.0
|
||||||
|
// IGNORE_DIAGNOSTIC_API
|
||||||
|
// IGNORE_REVERSED_RESOLVE
|
||||||
|
// ^KT-60996
|
||||||
// FILE: test.kt
|
// FILE: test.kt
|
||||||
val fooException = Exception("foo")
|
val fooException = Exception("foo")
|
||||||
val barException = kotlin.<!UNRESOLVED_REFERENCE!>Exception<!>("bar")
|
val barException = kotlin.<!UNRESOLVED_REFERENCE!>Exception<!>("bar")
|
||||||
|
|||||||
@@ -1100,6 +1100,11 @@ public class CliTestGenerated extends AbstractCliTest {
|
|||||||
runTest("compiler/testData/cli/jvm/requireKotlinCompilerVersion.args");
|
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")
|
@TestMetadata("resultInReturnTypeSupportedByDefault15.args")
|
||||||
public void testResultInReturnTypeSupportedByDefault15() throws Exception {
|
public void testResultInReturnTypeSupportedByDefault15() throws Exception {
|
||||||
runTest("compiler/testData/cli/jvm/resultInReturnTypeSupportedByDefault15.args");
|
runTest("compiler/testData/cli/jvm/resultInReturnTypeSupportedByDefault15.args");
|
||||||
|
|||||||
Reference in New Issue
Block a user