[FIR] Introduce OPTIONAL_EXPECTATION_NOT_ON_EXPECTED diagnostic

^KT-60892 Fixed
This commit is contained in:
Ivan Kochurkin
2023-08-08 16:26:34 +02:00
committed by Space Team
parent 8e8de513ee
commit d4d30dcfcf
9 changed files with 51 additions and 1 deletions
@@ -3630,6 +3630,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.OPTIONAL_EXPECTATION_NOT_ON_EXPECTED) { firDiagnostic ->
OptionalExpectationNotOnExpectedImpl(
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION) { firDiagnostic ->
InitializerRequiredForDestructuringDeclarationImpl(
firDiagnostic as KtPsiDiagnostic,
@@ -2541,6 +2541,10 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = OptionalDeclarationUsageInNonCommonSource::class
}
interface OptionalExpectationNotOnExpected : KtFirDiagnostic<PsiElement> {
override val diagnosticClass get() = OptionalExpectationNotOnExpected::class
}
interface InitializerRequiredForDestructuringDeclaration : KtFirDiagnostic<KtDestructuringDeclaration> {
override val diagnosticClass get() = InitializerRequiredForDestructuringDeclaration::class
}
@@ -3063,6 +3063,11 @@ internal class OptionalDeclarationUsageInNonCommonSourceImpl(
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.OptionalDeclarationUsageInNonCommonSource
internal class OptionalExpectationNotOnExpectedImpl(
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.OptionalExpectationNotOnExpected
internal class InitializerRequiredForDestructuringDeclarationImpl(
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
@@ -1240,6 +1240,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY by error<PsiElement>()
val OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE by error<PsiElement>()
val OPTIONAL_EXPECTATION_NOT_ON_EXPECTED by error<PsiElement>()
}
val DESTRUCTING_DECLARATION by object : DiagnosticGroup("Destructuring declaration") {
@@ -651,6 +651,7 @@ object FirErrors {
val ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT by warning3<KtElement, FirBasedSymbol<*>, FirBasedSymbol<*>, ExpectActualAnnotationsIncompatibilityType<FirAnnotation>>(SourceElementPositioningStrategies.DECLARATION_NAME_ONLY)
val OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY by error0<PsiElement>()
val OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE by error0<PsiElement>()
val OPTIONAL_EXPECTATION_NOT_ON_EXPECTED by error0<PsiElement>()
// Destructuring declaration
val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error0<KtDestructuringDeclaration>()
@@ -32,6 +32,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirPublishedApiChecker,
FirOptInMarkedDeclarationChecker,
FirExpectConsistencyChecker,
FirOptionalExpectationDeclarationChecker
)
override val callableDeclarationCheckers: Set<FirCallableDeclarationChecker>
@@ -0,0 +1,26 @@
/*
* 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.analysis.checkers.declaration
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
import org.jetbrains.kotlin.name.StandardClassIds
object FirOptionalExpectationDeclarationChecker : FirBasicDeclarationChecker() {
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration !is FirMemberDeclaration || !declaration.isExpect) {
declaration.getAnnotationByClassId(StandardClassIds.Annotations.OptionalExpectation, context.session)?.let {
reporter.reportOn(it.source, FirErrors.OPTIONAL_EXPECTATION_NOT_ON_EXPECTED, context)
}
}
}
}
@@ -437,6 +437,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OPERATOR_MODIFIER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OPERATOR_RENAMED_ON_IMPORT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OPTIONAL_EXPECTATION_NOT_ON_EXPECTED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OPT_IN_ARGUMENT_IS_NOT_MARKER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OPT_IN_CAN_ONLY_BE_USED_AS_ANNOTATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OPT_IN_IS_NOT_ENABLED
@@ -1931,6 +1932,10 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE,
"Declaration annotated with '@OptionalExpectation' can only be used in common module sources"
)
map.put(
OPTIONAL_EXPECTATION_NOT_ON_EXPECTED,
"'@OptionalExpectation' can only be used on an expected annotation class"
)
// Destructuring declaration
map.put(INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION, "Initializer required for destructuring declaration")
@@ -13,7 +13,7 @@ fun useInSignature(a: <!OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY!>A<!>)
<!NO_ACTUAL_FOR_EXPECT{JVM}!><!WRONG_ANNOTATION_TARGET!>@OptionalExpectation<!>
expect class NotAnAnnotationClass<!>
@OptionalExpectation
<!OPTIONAL_EXPECTATION_NOT_ON_EXPECTED!>@OptionalExpectation<!>
annotation class NotAnExpectedClass
annotation class InOtherAnnotation(val a: <!OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY!>A<!>)