From a64bac0b8c781278af7dd82c4b50fd5bd7095bcd Mon Sep 17 00:00:00 2001 From: Roman Efremov Date: Fri, 28 Jul 2023 13:33:26 +0200 Subject: [PATCH] [FE] Refactor: differentiate two types of problems in annotation checker This is needed for more beautiful reporting and easier implementation of quick fix in IDE. ^KT-58551 --- ...tractExpectActualAnnotationMatchChecker.kt | 22 +++++++++++++++++-- ...ectActualAnnotationsIncompatibilityType.kt | 19 ++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 core/compiler.common/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectActualAnnotationsIncompatibilityType.kt diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualAnnotationMatchChecker.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualAnnotationMatchChecker.kt index 8be8406c7f9..3f4c384c992 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualAnnotationMatchChecker.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualAnnotationMatchChecker.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.mpp.DeclarationSymbolMarker import org.jetbrains.kotlin.mpp.TypeAliasSymbolMarker import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.StandardClassIds +import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType as IncompatibilityType object AbstractExpectActualAnnotationMatchChecker { private val SKIPPED_CLASS_IDS = setOf( @@ -21,7 +22,11 @@ object AbstractExpectActualAnnotationMatchChecker { StandardClassIds.Annotations.WasExperimental, ) - class Incompatibility(val expectSymbol: DeclarationSymbolMarker, val actualSymbol: DeclarationSymbolMarker) + class Incompatibility( + val expectSymbol: DeclarationSymbolMarker, + val actualSymbol: DeclarationSymbolMarker, + val type: IncompatibilityType, + ) fun areAnnotationsCompatible( expectSymbol: DeclarationSymbolMarker, @@ -55,11 +60,24 @@ object AbstractExpectActualAnnotationMatchChecker { continue } val actualAnnotationsWithSameClassId = actualAnnotationsByName[expectClassId] ?: emptyList() + if (actualAnnotationsWithSameClassId.isEmpty()) { + return Incompatibility( + expectSymbol, + actualSymbol, + IncompatibilityType.MissingOnActual(expectAnnotation) + ) + } val collectionCompatibilityChecker = getAnnotationCollectionArgumentsCompatibilityChecker(expectClassId) if (actualAnnotationsWithSameClassId.none { areAnnotationArgumentsEqual(expectAnnotation, it, collectionCompatibilityChecker) }) { - return Incompatibility(expectSymbol, actualSymbol) + val incompatibilityType = if (actualAnnotationsWithSameClassId.size == 1) { + IncompatibilityType.DifferentOnActual(expectAnnotation, actualAnnotationsWithSameClassId.single()) + } else { + // In the case of repeatable annotations, we can't choose on which to report + IncompatibilityType.MissingOnActual(expectAnnotation) + } + return Incompatibility(expectSymbol, actualSymbol, incompatibilityType) } } return null 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 new file mode 100644 index 00000000000..62a5ca18dc8 --- /dev/null +++ b/core/compiler.common/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectActualAnnotationsIncompatibilityType.kt @@ -0,0 +1,19 @@ +/* + * 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.multiplatform + +sealed class ExpectActualAnnotationsIncompatibilityType { + abstract val expectAnnotation: A + + class MissingOnActual( + override val expectAnnotation: A, + ) : ExpectActualAnnotationsIncompatibilityType() + + class DifferentOnActual( + override val expectAnnotation: A, + val actualAnnotation: A + ) : ExpectActualAnnotationsIncompatibilityType() +}