[FE] Implement FE logic of expect actual annotations matching
This implementation only checks annotations set on expect/actual declarations and requires further refinement (e.g. checking of other annotation targets, class scopes within typealiases). ^KT-58551
This commit is contained in:
committed by
Space Team
parent
b1bdb619d8
commit
1a4ab9bb4b
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.calls.mpp
|
||||
|
||||
import org.jetbrains.kotlin.mpp.DeclarationSymbolMarker
|
||||
import org.jetbrains.kotlin.mpp.TypeAliasSymbolMarker
|
||||
|
||||
object AbstractExpectActualAnnotationMatchChecker {
|
||||
class Incompatibility(val expectSymbol: DeclarationSymbolMarker, val actualSymbol: DeclarationSymbolMarker)
|
||||
|
||||
fun areAnnotationsCompatible(
|
||||
expectSymbol: DeclarationSymbolMarker,
|
||||
actualSymbol: DeclarationSymbolMarker,
|
||||
context: ExpectActualMatchingContext<*>,
|
||||
): Incompatibility? = with(context) { areAnnotationsCompatible(expectSymbol, actualSymbol) }
|
||||
|
||||
context (ExpectActualMatchingContext<*>)
|
||||
private fun areAnnotationsCompatible(
|
||||
expectSymbol: DeclarationSymbolMarker,
|
||||
actualSymbol: DeclarationSymbolMarker,
|
||||
): Incompatibility? {
|
||||
if (actualSymbol is TypeAliasSymbolMarker) {
|
||||
val expanded = actualSymbol.expandToRegularClass() ?: return null
|
||||
return areAnnotationsCompatible(expectSymbol, expanded)
|
||||
}
|
||||
|
||||
val actualAnnotationsByName = actualSymbol.annotations.groupBy { it.classId }
|
||||
|
||||
for (expectAnnotation in expectSymbol.annotations) {
|
||||
val actualAnnotationsWithSameClassId = actualAnnotationsByName[expectAnnotation.classId] ?: emptyList()
|
||||
if (actualAnnotationsWithSameClassId.none { areAnnotationArgumentsEqual(expectAnnotation, it) }) {
|
||||
return Incompatibility(expectSymbol, actualSymbol)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
+9
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.mpp.*
|
||||
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.resolve.multiplatform.ExpectActualCompatibility
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -157,4 +158,12 @@ interface ExpectActualMatchingContext<T : DeclarationSymbolMarker> : TypeSystemC
|
||||
expectSymbol: DeclarationSymbolMarker,
|
||||
actualSymbolsByIncompatibility: Map<ExpectActualCompatibility.Incompatible<*>, List<DeclarationSymbolMarker>>
|
||||
) {}
|
||||
|
||||
val DeclarationSymbolMarker.annotations: List<AnnotationCallInfo>
|
||||
|
||||
fun areAnnotationArgumentsEqual(annotation1: AnnotationCallInfo, annotation2: AnnotationCallInfo): Boolean
|
||||
|
||||
interface AnnotationCallInfo {
|
||||
val classId: ClassId?
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user