From 11ccad7e405e43be2f448c41172765bdfe7d84c7 Mon Sep 17 00:00:00 2001 From: Roman Efremov Date: Fri, 28 Jul 2023 16:51:22 +0200 Subject: [PATCH] [FE, IR] Add expect actual annotations incompatibility info into diagnostic This is needed for more beautiful reporting and easier implementation of quick fix in IDE. ^KT-58551 --- .../api/fir/generator/HLDiagnosticConverter.kt | 4 +++- .../api/fir/diagnostics/KtFirDataClassConverters.kt | 1 + .../analysis/api/fir/diagnostics/KtFirDiagnostics.kt | 7 +++++-- .../api/fir/diagnostics/KtFirDiagnosticsImpl.kt | 7 +++++-- .../generator/diagnostics/FirDiagnosticsList.kt | 7 +++++-- .../kotlin/fir/analysis/diagnostics/FirErrors.kt | 4 +++- .../declaration/FirExpectActualDeclarationChecker.kt | 2 ++ .../analysis/diagnostics/FirErrorsDefaultMessages.kt | 3 ++- .../mpp/FirExpectActualMatchingContextImpl.kt | 2 ++ .../src/org/jetbrains/kotlin/diagnostics/Errors.java | 7 +++++-- .../diagnostics/rendering/DefaultErrorMessages.java | 2 +- .../checkers/ExpectedActualDeclarationChecker.kt | 4 +++- .../kotlin/backend/common/CommonBackendErrors.kt | 12 +++++------- .../backend/common/actualizer/IrActualizerUtils.kt | 4 ++++ .../IrExpectActualAnnotationMatchingChecker.kt | 2 ++ .../actualizer/IrExpectActualMatchingContext.kt | 2 ++ .../resolve/calls/mpp/ExpectActualMatchingContext.kt | 1 + .../ClassicExpectActualMatchingContext.kt | 2 ++ .../ExpectActualAnnotationsIncompatibilityType.kt | 7 +++++++ 19 files changed, 60 insertions(+), 20 deletions(-) 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 7e9ada2f624..64949035a4b 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,13 +30,14 @@ 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.name.ClassId import org.jetbrains.kotlin.name.CallableId +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo +import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility import org.jetbrains.kotlin.types.Variance import kotlin.reflect.KClass @@ -363,6 +364,7 @@ internal object FirToKtConversionCreator { FirModuleData::class, ExpectActualCompatibility::class, ExpectActualCompatibility.Incompatible::class, + ExpectActualAnnotationsIncompatibilityType::class, DeprecationInfo::class, ApiVersion::class, CallableId::class, 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 03796ddf1ff..db0a18209a9 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 @@ -3540,6 +3540,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert ActualAnnotationsNotMatchExpectImpl( firSymbolBuilder.buildSymbol(firDiagnostic.a), firSymbolBuilder.buildSymbol(firDiagnostic.b), + firDiagnostic.c, firDiagnostic as KtPsiDiagnostic, token, ) 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 43907e6d52a..902e383ce0f 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 @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.descriptors.EffectiveVisibility import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.diagnostics.WhenMissingCase import org.jetbrains.kotlin.fir.FirModuleData +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 @@ -80,6 +81,7 @@ import org.jetbrains.kotlin.psi.KtWhenEntry import org.jetbrains.kotlin.psi.KtWhenExpression import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo +import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible import org.jetbrains.kotlin.types.Variance @@ -2472,8 +2474,9 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { interface ActualAnnotationsNotMatchExpect : KtFirDiagnostic { override val diagnosticClass get() = ActualAnnotationsNotMatchExpect::class - val expect: KtSymbol - val actual: KtSymbol + val expectSymbol: KtSymbol + val actualSymbol: KtSymbol + val incompatibilityType: ExpectActualAnnotationsIncompatibilityType } interface InitializerRequiredForDestructuringDeclaration : KtFirDiagnostic { 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 2142a92dd4e..25400985940 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 @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic import org.jetbrains.kotlin.diagnostics.WhenMissingCase import org.jetbrains.kotlin.fir.FirModuleData +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 @@ -81,6 +82,7 @@ import org.jetbrains.kotlin.psi.KtWhenEntry import org.jetbrains.kotlin.psi.KtWhenExpression import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo +import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible import org.jetbrains.kotlin.types.Variance @@ -2980,8 +2982,9 @@ internal class ActualTypealiasToSpecialAnnotationImpl( ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.ActualTypealiasToSpecialAnnotation internal class ActualAnnotationsNotMatchExpectImpl( - override val expect: KtSymbol, - override val actual: KtSymbol, + override val expectSymbol: KtSymbol, + override val actualSymbol: KtSymbol, + override val incompatibilityType: ExpectActualAnnotationsIncompatibilityType, firDiagnostic: KtPsiDiagnostic, token: KtLifetimeToken, ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.ActualAnnotationsNotMatchExpect 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 62d4e80951c..867b18808ce 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 @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.FirModuleData import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.* import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirTypeAlias +import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.* @@ -34,6 +35,7 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo +import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible import org.jetbrains.kotlin.types.Variance @@ -1195,8 +1197,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { } val ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT by warning(PositioningStrategy.DECLARATION_NAME_ONLY) { - parameter("expect") - parameter("actual") + parameter("expectSymbol") + parameter("actualSymbol") + parameter>("incompatibilityType") } } 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 d5a6771ba77..bc019977784 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 @@ -36,6 +36,7 @@ import org.jetbrains.kotlin.diagnostics.WhenMissingCase import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory import org.jetbrains.kotlin.fir.FirModuleData import org.jetbrains.kotlin.fir.declarations.FirFunction +import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol @@ -103,6 +104,7 @@ import org.jetbrains.kotlin.psi.KtWhenEntry import org.jetbrains.kotlin.psi.KtWhenExpression import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo +import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible import org.jetbrains.kotlin.types.Variance @@ -635,7 +637,7 @@ object FirErrors { val NOT_A_MULTIPLATFORM_COMPILATION by error0() val EXPECT_ACTUAL_OPT_IN_ANNOTATION by error0(SourceElementPositioningStrategies.EXPECT_ACTUAL_MODIFIER) val ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION by error1(SourceElementPositioningStrategies.TYPEALIAS_TYPE_REFERENCE) - val ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT by warning2, FirBasedSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME_ONLY) + val ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT by warning3, FirBasedSymbol<*>, ExpectActualAnnotationsIncompatibilityType>(SourceElementPositioningStrategies.DECLARATION_NAME_ONLY) // Destructuring declaration val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error0() diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExpectActualDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExpectActualDeclarationChecker.kt index db5b29920c3..72c9fe9d9f9 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExpectActualDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExpectActualDeclarationChecker.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.isExpect import org.jetbrains.kotlin.fir.declarations.utils.isExternal import org.jetbrains.kotlin.fir.declarations.utils.isTailRec import org.jetbrains.kotlin.fir.expectActualMatchingContextFactory +import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.scopes.collectAllFunctions import org.jetbrains.kotlin.fir.scopes.getDeclaredConstructors @@ -263,6 +264,7 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() { actualSymbol.source, FirErrors.ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, incompatibility.expectSymbol as FirBasedSymbol<*>, incompatibility.actualSymbol as FirBasedSymbol<*>, + incompatibility.type.mapAnnotationType { it.annotationSymbol as FirAnnotation }, context ) } 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 93c945f3ed2..90c93dce102 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 @@ -1889,7 +1889,8 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() { "All annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.\n" + "Expected: {0}\n" + "Actual: {1}", - FirDiagnosticRenderers.SYMBOL_WITH_ANNOTATIONS, FirDiagnosticRenderers.SYMBOL_WITH_ANNOTATIONS + FirDiagnosticRenderers.SYMBOL_WITH_ANNOTATIONS, FirDiagnosticRenderers.SYMBOL_WITH_ANNOTATIONS, + TO_STRING ) // Destructuring declaration diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContextImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContextImpl.kt index 8b0dda18578..e88ba734cbb 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContextImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContextImpl.kt @@ -357,6 +357,8 @@ class FirExpectActualMatchingContextImpl private constructor( } private inner class AnnotationCallInfoImpl(val annotation: FirAnnotation) : AnnotationCallInfo { + override val annotationSymbol: FirAnnotation = annotation + override val classId: ClassId? get() = annotation.toAnnotationClassId(actualSession) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 6453c817f56..7ba774eaedf 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -13,6 +13,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.config.LanguageFeature; import org.jetbrains.kotlin.config.LanguageVersionSettings; import org.jetbrains.kotlin.descriptors.*; +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.kotlin.diagnostics.rendering.DeclarationWithDiagnosticComponents; import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages; import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap; @@ -33,6 +34,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability; import org.jetbrains.kotlin.resolve.calls.tower.WrongResolutionToClassifier; import org.jetbrains.kotlin.resolve.calls.util.BuilderLambdaLabelingInfo; import org.jetbrains.kotlin.resolve.deprecation.DescriptorBasedDeprecationInfo; +import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType; import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible; import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData; import org.jetbrains.kotlin.types.KotlinType; @@ -844,8 +846,9 @@ public interface Errors { DiagnosticFactory0 EXPECT_ACTUAL_OPT_IN_ANNOTATION = DiagnosticFactory0.create(ERROR, EXPECT_ACTUAL_MODIFIER); DiagnosticFactory1 ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION = DiagnosticFactory1.create(ERROR, TYPEALIAS_TYPE_REFERENCE); - DiagnosticFactory2 ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT - = DiagnosticFactory2.create(WARNING, DECLARATION_NAME_ONLY); + DiagnosticFactory3> ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT = + DiagnosticFactory3.create(WARNING, DECLARATION_NAME_ONLY); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 140eecfb60b..fdcf1b052b2 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -407,7 +407,7 @@ public class DefaultErrorMessages { "All annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.\n" + " Expected: {0}\n" + " Actual: {1}", - DESCRIPTOR_WITH_ANNOTATIONS, DESCRIPTOR_WITH_ANNOTATIONS); + DESCRIPTOR_WITH_ANNOTATIONS, DESCRIPTOR_WITH_ANNOTATIONS, TO_STRING); MAP.put(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT, "Projections are not allowed on type arguments of functions and properties"); MAP.put(SUPERTYPE_NOT_INITIALIZED, "This type has a constructor, and thus must be initialized here"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt index ff3a5c2df1c..6fe90bc1846 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt @@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.config.AnalysisFlags import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.mpp.MppJavaImplicitActualizatorMarker @@ -490,7 +491,8 @@ class ExpectedActualDeclarationChecker( Errors.ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT.on( reportOn, incompatibility.expectSymbol as DeclarationDescriptor, - incompatibility.actualSymbol as DeclarationDescriptor + incompatibility.actualSymbol as DeclarationDescriptor, + incompatibility.type.mapAnnotationType { it.annotationSymbol as AnnotationDescriptor } ) ) } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CommonBackendErrors.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CommonBackendErrors.kt index 1669ffb845d..5345646e6d3 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CommonBackendErrors.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CommonBackendErrors.kt @@ -9,20 +9,17 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.backend.common.BackendDiagnosticRenderers.INCOMPATIBILITY import org.jetbrains.kotlin.backend.common.BackendDiagnosticRenderers.SYMBOL_OWNER_DECLARATION_FQ_NAME import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap -import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME -import org.jetbrains.kotlin.diagnostics.error1 -import org.jetbrains.kotlin.diagnostics.error2 -import org.jetbrains.kotlin.diagnostics.error3 +import org.jetbrains.kotlin.diagnostics.* import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.STRING import org.jetbrains.kotlin.diagnostics.rendering.Renderer import org.jetbrains.kotlin.diagnostics.rendering.Renderers.MODULE_WITH_PLATFORM import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory -import org.jetbrains.kotlin.diagnostics.warning2 import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName +import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable +import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility object CommonBackendErrors { @@ -30,7 +27,7 @@ object CommonBackendErrors { val MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED by error2() val MANY_IMPL_MEMBER_NOT_IMPLEMENTED by error2() val INCOMPATIBLE_MATCHING by error3>() - val ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT by warning2() + val ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT by warning3>() val EVALUATION_ERROR by error1() init { @@ -70,6 +67,7 @@ object KtDefaultCommonBackendErrorMessages : BaseDiagnosticRendererFactory() { "All annotations from expect declaration `{0}` must be present with the same arguments on actual declaration `{1}` otherwise they have no effect", SYMBOL_OWNER_DECLARATION_FQ_NAME, SYMBOL_OWNER_DECLARATION_FQ_NAME, + STRING, ) map.put( CommonBackendErrors.EVALUATION_ERROR, diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrActualizerUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrActualizerUtils.kt index d5c9fe7ab41..103428d0537 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrActualizerUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrActualizerUtils.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.builders.declarations.buildFun import org.jetbrains.kotlin.ir.builders.declarations.buildProperty import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol @@ -20,6 +21,7 @@ import org.jetbrains.kotlin.ir.types.IrTypeSystemContext import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualCompatibilityChecker +import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil import org.jetbrains.kotlin.utils.addToStdlib.runIf @@ -125,12 +127,14 @@ internal fun KtDiagnosticReporterWithImplicitIrBasedContext.reportIncompatibleEx internal fun KtDiagnosticReporterWithImplicitIrBasedContext.reportActualAnnotationsNotMatchExpect( expectSymbol: IrSymbol, actualSymbol: IrSymbol, + incompatibilityType: ExpectActualAnnotationsIncompatibilityType, reportOn: IrSymbol, ) { at(reportOn.owner as IrDeclaration).report( CommonBackendErrors.ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, expectSymbol, actualSymbol, + incompatibilityType, ) } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualAnnotationMatchingChecker.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualAnnotationMatchingChecker.kt index 9d86e821ad9..0b485d53b34 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualAnnotationMatchingChecker.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualAnnotationMatchingChecker.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.KtDiagnosticReporterWithImplicitIrBasedContext import org.jetbrains.kotlin.backend.common.lower.parentsWithSelf import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclaration +import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeAliasSymbol @@ -45,6 +46,7 @@ internal class IrExpectActualAnnotationMatchingChecker( diagnosticsReporter.reportActualAnnotationsNotMatchExpect( incompatibility.expectSymbol as IrSymbol, incompatibility.actualSymbol as IrSymbol, + incompatibility.type.mapAnnotationType { it.annotationSymbol as IrConstructorCall }, reportOn, ) } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualMatchingContext.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualMatchingContext.kt index 04b4391f217..a198297766e 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualMatchingContext.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualMatchingContext.kt @@ -472,6 +472,8 @@ internal abstract class IrExpectActualMatchingContext( } private inner class AnnotationCallInfoImpl(val irElement: IrConstructorCall) : AnnotationCallInfo { + override val annotationSymbol: IrConstructorCall = irElement + override val classId: ClassId? get() = getAnnotationClass()?.classId diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualMatchingContext.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualMatchingContext.kt index 7c0053e1ff7..6511221d01c 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualMatchingContext.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualMatchingContext.kt @@ -169,6 +169,7 @@ interface ExpectActualMatchingContext : TypeSystemC val DeclarationSymbolMarker.hasSourceAnnotationsErased: Boolean interface AnnotationCallInfo { + val annotationSymbol: Any val classId: ClassId? val isRetentionSource: Boolean val isOptIn: Boolean diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ClassicExpectActualMatchingContext.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ClassicExpectActualMatchingContext.kt index 8c2361ef21c..db4ddded00a 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ClassicExpectActualMatchingContext.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ClassicExpectActualMatchingContext.kt @@ -355,6 +355,8 @@ class ClassicExpectActualMatchingContext(val platformModule: ModuleDescriptor) : private class AnnotationCallInfoImpl( val annotationDescriptor: AnnotationDescriptor, ) : AnnotationCallInfo { + override val annotationSymbol: AnnotationDescriptor = annotationDescriptor + override val classId: ClassId? get() = annotationDescriptor.annotationClass?.classId diff --git a/core/compiler.common/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectActualAnnotationsIncompatibilityType.kt b/core/compiler.common/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectActualAnnotationsIncompatibilityType.kt index 62a5ca18dc8..8fa0938b7f1 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectActualAnnotationsIncompatibilityType.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectActualAnnotationsIncompatibilityType.kt @@ -16,4 +16,11 @@ sealed class ExpectActualAnnotationsIncompatibilityType { override val expectAnnotation: A, val actualAnnotation: A ) : ExpectActualAnnotationsIncompatibilityType() + + fun mapAnnotationType(mapper: (A) -> A2): ExpectActualAnnotationsIncompatibilityType { + return when (this) { + is MissingOnActual -> MissingOnActual(mapper(expectAnnotation)) + is DifferentOnActual -> DifferentOnActual(mapper(expectAnnotation), mapper(actualAnnotation)) + } + } }