[FE] Refactor: reorganize methods in AbstractExpectActualAnnotationMatchChecker

Separate callable and class checks to prepare for checking
class scopes. Extract common checks to separate methods.

Also, it is found that in IR checker annotations on type parameters also checked,
because they stored in `matchedExpectToActual`. But it is expected that
only classes and callables are checked. This started to fail because of
added input parameter type checks inside `areAnnotationsCompatible`.
That's why `expectSymbol is IrTypeParameterSymbol` early-return is added.

^KT-60668
^KT-60936
This commit is contained in:
Roman Efremov
2023-07-24 13:27:52 +02:00
committed by Space Team
parent 8cbefcc26f
commit 2f00ed3ed7
2 changed files with 53 additions and 4 deletions
@@ -13,6 +13,7 @@ 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
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
import org.jetbrains.kotlin.ir.util.classIdOrFail
import org.jetbrains.kotlin.ir.util.isFakeOverride
@@ -36,6 +37,9 @@ internal class IrExpectActualAnnotationMatchingChecker(
fun check() {
for ((expectSymbol, actualSymbol) in matchedExpectToActual.entries) {
if (expectSymbol is IrTypeParameterSymbol) {
continue
}
if (expectSymbol.isFakeOverride || actualSymbol.isFakeOverride) {
continue
}
@@ -5,8 +5,7 @@
package org.jetbrains.kotlin.resolve.calls.mpp
import org.jetbrains.kotlin.mpp.DeclarationSymbolMarker
import org.jetbrains.kotlin.mpp.TypeAliasSymbolMarker
import org.jetbrains.kotlin.mpp.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.resolve.checkers.OptInNames
@@ -40,15 +39,61 @@ object AbstractExpectActualAnnotationMatchChecker {
private fun areAnnotationsCompatible(
expectSymbol: DeclarationSymbolMarker,
actualSymbol: DeclarationSymbolMarker,
): Incompatibility? {
return when (expectSymbol) {
is CallableSymbolMarker -> {
areCallableAnnotationsCompatible(expectSymbol, actualSymbol as CallableSymbolMarker)
}
is RegularClassSymbolMarker -> {
areClassAnnotationsCompatible(expectSymbol, actualSymbol as ClassLikeSymbolMarker)
}
else -> error("Incorrect types: $expectSymbol $actualSymbol")
}
}
context (ExpectActualMatchingContext<*>)
private fun areCallableAnnotationsCompatible(
expectSymbol: CallableSymbolMarker,
actualSymbol: CallableSymbolMarker,
): Incompatibility? {
commonForClassAndCallableChecks(expectSymbol, actualSymbol)?.let { return it }
return null
}
context (ExpectActualMatchingContext<*>)
private fun areClassAnnotationsCompatible(
expectSymbol: RegularClassSymbolMarker,
actualSymbol: ClassLikeSymbolMarker,
): Incompatibility? {
if (actualSymbol is TypeAliasSymbolMarker) {
val expanded = actualSymbol.expandToRegularClass() ?: return null
return areAnnotationsCompatible(expectSymbol, expanded)
return areClassAnnotationsCompatible(expectSymbol, expanded)
}
// TODO(Roman.Efremov, KT-58551): check other annotation targets (constructors, types, value parameters, etc)
commonForClassAndCallableChecks(expectSymbol, actualSymbol)?.let { return it }
// TODO(Roman.Efremov, KT-58551): fix actual typealias class members not checked in FE checkers
// TODO(Roman.Efremov, KT-58551): check annotations on fake overrides in case of implicit actualization
return null
}
context (ExpectActualMatchingContext<*>)
private fun commonForClassAndCallableChecks(
expectSymbol: DeclarationSymbolMarker,
actualSymbol: DeclarationSymbolMarker,
): Incompatibility? {
areAnnotationsSetOnDeclarationsCompatible(expectSymbol, actualSymbol)?.let { return it }
return null
}
context (ExpectActualMatchingContext<*>)
private fun areAnnotationsSetOnDeclarationsCompatible(
expectSymbol: DeclarationSymbolMarker,
actualSymbol: DeclarationSymbolMarker,
): Incompatibility? {
// TODO(Roman.Efremov, KT-58551): check other annotation targets (constructors, types, value parameters, etc)
val skipSourceAnnotations = actualSymbol.hasSourceAnnotationsErased
val actualAnnotationsByName = actualSymbol.annotations.groupBy { it.classId }