From d4d30dcfcf1afb083f09279c6f1ba05031efeabb Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Tue, 8 Aug 2023 16:26:34 +0200 Subject: [PATCH] [FIR] Introduce OPTIONAL_EXPECTATION_NOT_ON_EXPECTED diagnostic ^KT-60892 Fixed --- .../diagnostics/KtFirDataClassConverters.kt | 6 +++++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 4 +++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 5 ++++ .../diagnostics/FirDiagnosticsList.kt | 2 ++ .../fir/analysis/diagnostics/FirErrors.kt | 1 + .../checkers/CommonDeclarationCheckers.kt | 1 + ...irOptionalExpectationDeclarationChecker.kt | 26 +++++++++++++++++++ .../diagnostics/FirErrorsDefaultMessages.kt | 5 ++++ .../optionalExpectationDiagnostics.fir.kt | 2 +- 9 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOptionalExpectationDeclarationChecker.kt 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 d072d285dc1..7d999eb4c24 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 @@ -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, 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 fd9e54eefde..77430c1d901 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 @@ -2541,6 +2541,10 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = OptionalDeclarationUsageInNonCommonSource::class } + interface OptionalExpectationNotOnExpected : KtFirDiagnostic { + override val diagnosticClass get() = OptionalExpectationNotOnExpected::class + } + interface InitializerRequiredForDestructuringDeclaration : KtFirDiagnostic { override val diagnosticClass get() = InitializerRequiredForDestructuringDeclaration::class } 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 87cc6c6d49b..b378a3b6aeb 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 @@ -3063,6 +3063,11 @@ internal class OptionalDeclarationUsageInNonCommonSourceImpl( token: KtLifetimeToken, ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.OptionalDeclarationUsageInNonCommonSource +internal class OptionalExpectationNotOnExpectedImpl( + firDiagnostic: KtPsiDiagnostic, + token: KtLifetimeToken, +) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.OptionalExpectationNotOnExpected + internal class InitializerRequiredForDestructuringDeclarationImpl( firDiagnostic: KtPsiDiagnostic, token: KtLifetimeToken, 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 a713bed9a59..8d74dd99077 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 @@ -1240,6 +1240,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { val OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY by error() val OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE by error() + + val OPTIONAL_EXPECTATION_NOT_ON_EXPECTED by error() } val DESTRUCTING_DECLARATION by object : DiagnosticGroup("Destructuring declaration") { 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 1ccd0738e61..c1a7b39b5e4 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 @@ -651,6 +651,7 @@ object FirErrors { val ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT by warning3, FirBasedSymbol<*>, ExpectActualAnnotationsIncompatibilityType>(SourceElementPositioningStrategies.DECLARATION_NAME_ONLY) val OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY by error0() val OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE by error0() + val OPTIONAL_EXPECTATION_NOT_ON_EXPECTED by error0() // Destructuring declaration val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error0() diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt index e99f66b04cc..3e6b29c343e 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt @@ -32,6 +32,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirPublishedApiChecker, FirOptInMarkedDeclarationChecker, FirExpectConsistencyChecker, + FirOptionalExpectationDeclarationChecker ) override val callableDeclarationCheckers: Set diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOptionalExpectationDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOptionalExpectationDeclarationChecker.kt new file mode 100644 index 00000000000..21ba23b9cba --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOptionalExpectationDeclarationChecker.kt @@ -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) + } + } + } +} \ No newline at end of file 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 ff2b3bc6a1a..275a1a157ff 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 @@ -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") diff --git a/compiler/testData/diagnostics/tests/multiplatform/optionalExpectationDiagnostics.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/optionalExpectationDiagnostics.fir.kt index 093e7ae1713..51f19600c50 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/optionalExpectationDiagnostics.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/optionalExpectationDiagnostics.fir.kt @@ -13,7 +13,7 @@ fun useInSignature(a: A) @OptionalExpectation expect class NotAnAnnotationClass -@OptionalExpectation +@OptionalExpectation annotation class NotAnExpectedClass annotation class InOtherAnnotation(val a: A)