[FIR] Implement DEPRECATED_SINCE_KOTLIN_WITH_UNORDERED_VERSIONS diagnostics, fix tests
This commit is contained in:
committed by
TeamCityServer
parent
5c086e2321
commit
dc99a673a5
+1
@@ -157,6 +157,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val NEWER_VERSION_IN_SINCE_KOTLIN by warning<KtExpression> {
|
||||
parameter<String>("specifiedVersion")
|
||||
}
|
||||
val DEPRECATED_SINCE_KOTLIN_WITH_UNORDERED_VERSIONS by error<PsiElement>()
|
||||
}
|
||||
|
||||
val EXPOSED_VISIBILITY by object : DiagnosticGroup("Exposed visibility") {
|
||||
|
||||
@@ -163,6 +163,7 @@ object FirErrors {
|
||||
val ANNOTATION_USED_AS_ANNOTATION_ARGUMENT by error0<KtAnnotation>()
|
||||
val ILLEGAL_KOTLIN_VERSION_STRING_VALUE by error0<KtExpression>()
|
||||
val NEWER_VERSION_IN_SINCE_KOTLIN by warning1<KtExpression, String>()
|
||||
val DEPRECATED_SINCE_KOTLIN_WITH_UNORDERED_VERSIONS by error0<PsiElement>()
|
||||
|
||||
// Exposed visibility
|
||||
val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3<KtNamedDeclaration, EffectiveVisibility, FirMemberDeclaration, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||
|
||||
+9
-1
@@ -86,6 +86,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATE_SPECIAL_
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_IN_INTERFACE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_MODIFIER_PAIR
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_SINCE_KOTLIN_WITH_UNORDERED_VERSIONS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_TYPE_PARAMETER_SYNTAX
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DESERIALIZATION_ERROR
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DYNAMIC_UPPER_BOUND
|
||||
@@ -423,8 +424,15 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
||||
map.put(VAR_ANNOTATION_PARAMETER, "An annotation parameter cannot be 'var'")
|
||||
map.put(NOT_AN_ANNOTATION_CLASS, "Illegal annotation class: {0}", NULLABLE_STRING)
|
||||
map.put(SUPERTYPES_FOR_ANNOTATION_CLASS, "Annotation class cannot have supertypes")
|
||||
map.put(ILLEGAL_KOTLIN_VERSION_STRING_VALUE, "Invalid value in version annotation (should be 'major.minor' or 'major.minor.patch')")
|
||||
map.put(
|
||||
ILLEGAL_KOTLIN_VERSION_STRING_VALUE,
|
||||
"Invalid value in version annotation (should be 'major.minor' or 'major.minor.patch')"
|
||||
)
|
||||
map.put(NEWER_VERSION_IN_SINCE_KOTLIN, "The version is greater than the specified API version {0}", NULLABLE_STRING)
|
||||
map.put(
|
||||
DEPRECATED_SINCE_KOTLIN_WITH_UNORDERED_VERSIONS,
|
||||
"Values of DeprecatedSinceKotlin annotation should be ordered so 'warningSince' <= 'errorSince' <= 'hiddenSince' if specified"
|
||||
)
|
||||
|
||||
// Exposed visibility group // #
|
||||
map.put(
|
||||
|
||||
+1
@@ -143,6 +143,7 @@ private fun mapInapplicableCandidateError(
|
||||
)
|
||||
is UnsafeCall -> mapUnsafeCallError(diagnostic.candidate, rootCause, source, qualifiedAccessSource)
|
||||
is ManyLambdaExpressionArguments -> FirErrors.MANY_LAMBDA_EXPRESSION_ARGUMENTS.on(rootCause.argument.source ?: source)
|
||||
is DeprecatedSinceKotlinWithUnorderedVersions -> FirErrors.DEPRECATED_SINCE_KOTLIN_WITH_UNORDERED_VERSIONS.on(source)
|
||||
else -> null
|
||||
}
|
||||
}.ifEmpty { listOf(FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidate.symbol)) }
|
||||
|
||||
+3
-1
@@ -101,4 +101,6 @@ class NullForNotNullType(
|
||||
|
||||
class ManyLambdaExpressionArguments(
|
||||
val argument: FirExpression
|
||||
) : ResolutionDiagnostic(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR)
|
||||
) : ResolutionDiagnostic(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR)
|
||||
|
||||
object DeprecatedSinceKotlinWithUnorderedVersions : ResolutionDiagnostic(INAPPLICABLE)
|
||||
|
||||
+64
-3
@@ -5,13 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.config.ApiVersion
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.FirSymbolOwner
|
||||
import org.jetbrains.kotlin.fir.FirVisibilityChecker
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.*
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
@@ -22,6 +21,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.visibilityChecker
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -144,6 +144,7 @@ internal object CheckArguments : CheckerStage() {
|
||||
override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) {
|
||||
val argumentMapping =
|
||||
candidate.argumentMapping ?: error("Argument should be already mapped while checking arguments!")
|
||||
|
||||
for (argument in callInfo.arguments) {
|
||||
val parameter = argumentMapping[argument]
|
||||
candidate.resolveArgument(
|
||||
@@ -155,10 +156,70 @@ internal object CheckArguments : CheckerStage() {
|
||||
context = context
|
||||
)
|
||||
}
|
||||
|
||||
checkDeprecatedSinceKotlinArgs(candidate, argumentMapping, sink)
|
||||
|
||||
if (candidate.system.hasContradiction && callInfo.arguments.isNotEmpty()) {
|
||||
sink.yieldDiagnostic(InapplicableCandidate)
|
||||
}
|
||||
}
|
||||
|
||||
private val deprecatedSinceKotlin = CallableId(
|
||||
FqName("kotlin"),
|
||||
FqName("DeprecatedSinceKotlin"),
|
||||
Name.identifier("DeprecatedSinceKotlin")
|
||||
)
|
||||
|
||||
private suspend fun checkDeprecatedSinceKotlinArgs(
|
||||
candidate: Candidate,
|
||||
argumentMapping: LinkedHashMap<FirExpression, FirValueParameter>,
|
||||
sink: CheckerSink
|
||||
) {
|
||||
val symbol = candidate.symbol
|
||||
if (symbol is FirFunctionSymbol<*>) {
|
||||
if (symbol.callableId == deprecatedSinceKotlin) {
|
||||
var warningSince: ApiVersion? = null
|
||||
var errorSince: ApiVersion? = null
|
||||
var hiddenSince: ApiVersion? = null
|
||||
for (argument in argumentMapping) {
|
||||
val identifier = argument.value.name.identifier
|
||||
if (identifier == "warningSince" || identifier == "errorSince" || identifier == "hiddenSince") {
|
||||
val argKey = argument.key
|
||||
val constExpression = (argKey as? FirConstExpression<*>)
|
||||
?: ((argKey as? FirNamedArgumentExpression)?.expression as? FirConstExpression<*>)
|
||||
val stringValue = constExpression?.value as? String
|
||||
if (stringValue != null) {
|
||||
val version = ApiVersion.parse(stringValue)
|
||||
when (identifier) {
|
||||
"warningSince" -> warningSince = version
|
||||
"errorSince" -> errorSince = version
|
||||
"hiddenSince" -> hiddenSince = version
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var isReportDeprecatedSinceKotlinWithUnorderedVersions = false
|
||||
if (warningSince != null) {
|
||||
if (errorSince != null) {
|
||||
isReportDeprecatedSinceKotlinWithUnorderedVersions = warningSince > errorSince
|
||||
}
|
||||
|
||||
if (hiddenSince != null && !isReportDeprecatedSinceKotlinWithUnorderedVersions) {
|
||||
isReportDeprecatedSinceKotlinWithUnorderedVersions = warningSince > hiddenSince
|
||||
}
|
||||
}
|
||||
|
||||
if (errorSince != null && hiddenSince != null && !isReportDeprecatedSinceKotlinWithUnorderedVersions) {
|
||||
isReportDeprecatedSinceKotlinWithUnorderedVersions = errorSince > hiddenSince
|
||||
}
|
||||
|
||||
if (isReportDeprecatedSinceKotlinWithUnorderedVersions) {
|
||||
sink.yieldDiagnostic(DeprecatedSinceKotlinWithUnorderedVersions)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal object EagerResolveOfCallableReferences : CheckerStage() {
|
||||
|
||||
+4
-4
@@ -25,19 +25,19 @@ fun fooError() {}
|
||||
fun fooHidden() {}
|
||||
|
||||
@Deprecated("")
|
||||
@DeprecatedSinceKotlin(warningSince = "1.1", errorSince = "1.0")
|
||||
<!DEPRECATED_SINCE_KOTLIN_WITH_UNORDERED_VERSIONS!>@DeprecatedSinceKotlin(warningSince = "1.1", errorSince = "1.0")<!>
|
||||
fun fooWarningIsGreater1() {}
|
||||
|
||||
@Deprecated("")
|
||||
@DeprecatedSinceKotlin(warningSince = "1.1", hiddenSince = "1.0")
|
||||
<!DEPRECATED_SINCE_KOTLIN_WITH_UNORDERED_VERSIONS!>@DeprecatedSinceKotlin(warningSince = "1.1", hiddenSince = "1.0")<!>
|
||||
fun fooWarningIsGreater2() {}
|
||||
|
||||
@Deprecated("")
|
||||
@DeprecatedSinceKotlin(warningSince = "1.1", errorSince = "1.3", hiddenSince = "1.2")
|
||||
<!DEPRECATED_SINCE_KOTLIN_WITH_UNORDERED_VERSIONS!>@DeprecatedSinceKotlin(warningSince = "1.1", errorSince = "1.3", hiddenSince = "1.2")<!>
|
||||
fun fooErrorIsGreater() {}
|
||||
|
||||
@Deprecated("")
|
||||
@DeprecatedSinceKotlin("1.2", "1.1", "1.1")
|
||||
<!DEPRECATED_SINCE_KOTLIN_WITH_UNORDERED_VERSIONS!>@DeprecatedSinceKotlin("1.2", "1.1", "1.1")<!>
|
||||
fun fooDefault() {}
|
||||
|
||||
@Deprecated("")
|
||||
|
||||
+6
@@ -527,6 +527,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.DEPRECATED_SINCE_KOTLIN_WITH_UNORDERED_VERSIONS) { firDiagnostic ->
|
||||
DeprecatedSinceKotlinWithUnorderedVersionsImpl(
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE) { firDiagnostic ->
|
||||
ExposedTypealiasExpandedTypeImpl(
|
||||
firDiagnostic.a,
|
||||
|
||||
+4
@@ -380,6 +380,10 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
abstract val specifiedVersion: String
|
||||
}
|
||||
|
||||
abstract class DeprecatedSinceKotlinWithUnorderedVersions : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = DeprecatedSinceKotlinWithUnorderedVersions::class
|
||||
}
|
||||
|
||||
abstract class ExposedTypealiasExpandedType : KtFirDiagnostic<KtNamedDeclaration>() {
|
||||
override val diagnosticClass get() = ExposedTypealiasExpandedType::class
|
||||
abstract val elementVisibility: EffectiveVisibility
|
||||
|
||||
+7
@@ -612,6 +612,13 @@ internal class NewerVersionInSinceKotlinImpl(
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class DeprecatedSinceKotlinWithUnorderedVersionsImpl(
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.DeprecatedSinceKotlinWithUnorderedVersions(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class ExposedTypealiasExpandedTypeImpl(
|
||||
override val elementVisibility: EffectiveVisibility,
|
||||
override val restrictingDeclaration: KtSymbol,
|
||||
|
||||
Reference in New Issue
Block a user