[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
This commit is contained in:
Roman Efremov
2023-07-28 13:33:26 +02:00
committed by Space Team
parent 75bef4050e
commit a64bac0b8c
2 changed files with 39 additions and 2 deletions
@@ -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<ExpectActualMatchingContext.AnnotationCallInfo>,
)
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
@@ -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<out A> {
abstract val expectAnnotation: A
class MissingOnActual<out A>(
override val expectAnnotation: A,
) : ExpectActualAnnotationsIncompatibilityType<A>()
class DifferentOnActual<out A>(
override val expectAnnotation: A,
val actualAnnotation: A
) : ExpectActualAnnotationsIncompatibilityType<A>()
}