[IR] Refactor: create new class for all IR expect-actual checkers

...to not write call of each checker inside IrActualizer.actualize.
This is needed because new IR checker will be addded in subsequent
commits.

^KT-59940
This commit is contained in:
Roman Efremov
2023-09-13 14:37:42 +02:00
committed by Space Team
parent 88c308dfd3
commit d4b8f73e04
6 changed files with 86 additions and 26 deletions
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.backend.common.actualizer
import org.jetbrains.kotlin.KtDiagnosticReporterWithImplicitIrBasedContext
import org.jetbrains.kotlin.backend.common.actualizer.checker.IrExpectActualCheckers
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
@@ -42,9 +43,8 @@ object IrActualizer {
ktDiagnosticReporter,
expectActualTracker
).collect()
if (languageVersionSettings.supportsFeature(LanguageFeature.MultiplatformRestrictions)) {
IrExpectActualAnnotationMatchingChecker(expectActualMap, actualDeclarations, typeSystemContext, ktDiagnosticReporter).check()
}
IrExpectActualCheckers(expectActualMap, actualDeclarations, typeSystemContext, ktDiagnosticReporter).check()
// 2. Remove top-only expect declarations since they are not needed anymore and should not be presented in the final IrFragment
// Expect fake-overrides from non-expect classes remain untouched since they will be actualized in the next phase.
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.backend.common.actualizer
import org.jetbrains.kotlin.backend.common.actualizer.checker.areIrExpressionConstValuesEqual
import org.jetbrains.kotlin.backend.common.sourceElement
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
@@ -3,39 +3,29 @@
* 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.backend.common.actualizer
package org.jetbrains.kotlin.backend.common.actualizer.checker
import org.jetbrains.kotlin.KtDiagnosticReporterWithImplicitIrBasedContext
import org.jetbrains.kotlin.backend.common.actualizer.ClassActualizationInfo
import org.jetbrains.kotlin.backend.common.actualizer.reportActualAnnotationsNotMatchExpect
import org.jetbrains.kotlin.backend.common.lower.parents
import org.jetbrains.kotlin.config.LanguageFeature
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
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
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualAnnotationMatchChecker
internal class IrExpectActualAnnotationMatchingChecker(
private val matchedExpectToActual: Map<IrSymbol, IrSymbol>,
private val classActualizationInfo: ClassActualizationInfo,
typeSystemContext: IrTypeSystemContext,
private val diagnosticsReporter: KtDiagnosticReporterWithImplicitIrBasedContext,
) {
private val context = object : IrExpectActualMatchingContext(typeSystemContext, classActualizationInfo.actualClasses) {
override fun onMatchedClasses(expectClassSymbol: IrClassSymbol, actualClassSymbol: IrClassSymbol) {
error("Must not be called")
internal object IrExpectActualAnnotationMatchingChecker : IrExpectActualChecker {
override fun check(context: IrExpectActualChecker.Context) = with(context) {
if (!diagnosticsReporter.languageVersionSettings.supportsFeature(LanguageFeature.MultiplatformRestrictions)) {
return
}
override fun onMatchedCallables(expectSymbol: IrSymbol, actualSymbol: IrSymbol) {
error("Must not be called")
}
}
fun check() {
for ((expectSymbol, actualSymbol) in matchedExpectToActual.entries) {
if (expectSymbol is IrTypeParameterSymbol) {
continue
@@ -44,9 +34,9 @@ internal class IrExpectActualAnnotationMatchingChecker(
continue
}
val incompatibility =
AbstractExpectActualAnnotationMatchChecker.areAnnotationsCompatible(expectSymbol, actualSymbol, context) ?: continue
AbstractExpectActualAnnotationMatchChecker.areAnnotationsCompatible(expectSymbol, actualSymbol, matchingContext) ?: continue
val reportOn = getTypealiasSymbolIfActualizedViaTypealias(expectSymbol)
val reportOn = getTypealiasSymbolIfActualizedViaTypealias(expectSymbol, classActualizationInfo)
?: getContainingActualClassIfFakeOverride(actualSymbol)
?: actualSymbol
diagnosticsReporter.reportActualAnnotationsNotMatchExpect(
@@ -61,7 +51,10 @@ internal class IrExpectActualAnnotationMatchingChecker(
private val IrSymbol.isFakeOverride: Boolean
get() = (owner as IrDeclaration).isFakeOverride
private fun getTypealiasSymbolIfActualizedViaTypealias(expectSymbol: IrSymbol): IrTypeAliasSymbol? {
private fun getTypealiasSymbolIfActualizedViaTypealias(
expectSymbol: IrSymbol,
classActualizationInfo: ClassActualizationInfo,
): IrTypeAliasSymbol? {
val topLevelExpectClass = getContainingTopLevelClass(expectSymbol) ?: return null
val classId = topLevelExpectClass.classIdOrFail
return classActualizationInfo.actualTypeAliases[classId]
@@ -0,0 +1,24 @@
/*
* 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.backend.common.actualizer.checker
import org.jetbrains.kotlin.KtDiagnosticReporterWithImplicitIrBasedContext
import org.jetbrains.kotlin.backend.common.actualizer.ClassActualizationInfo
import org.jetbrains.kotlin.backend.common.actualizer.IrExpectActualMatchingContext
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
internal interface IrExpectActualChecker {
interface Context {
val matchedExpectToActual: Map<IrSymbol, IrSymbol>
val classActualizationInfo: ClassActualizationInfo
val typeSystemContext: IrTypeSystemContext
val diagnosticsReporter: KtDiagnosticReporterWithImplicitIrBasedContext
val matchingContext: IrExpectActualMatchingContext
}
fun check(context: Context)
}
@@ -0,0 +1,41 @@
/*
* 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.backend.common.actualizer.checker
import org.jetbrains.kotlin.KtDiagnosticReporterWithImplicitIrBasedContext
import org.jetbrains.kotlin.backend.common.actualizer.ClassActualizationInfo
import org.jetbrains.kotlin.backend.common.actualizer.IrExpectActualMatchingContext
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
internal class IrExpectActualCheckers(
override val matchedExpectToActual: Map<IrSymbol, IrSymbol>,
override val classActualizationInfo: ClassActualizationInfo,
override val typeSystemContext: IrTypeSystemContext,
override val diagnosticsReporter: KtDiagnosticReporterWithImplicitIrBasedContext,
) : IrExpectActualChecker.Context {
private val checkers: Set<IrExpectActualChecker> = setOf(
IrExpectActualAnnotationMatchingChecker
)
override val matchingContext = object : IrExpectActualMatchingContext(typeSystemContext, classActualizationInfo.actualClasses) {
override fun onMatchedClasses(expectClassSymbol: IrClassSymbol, actualClassSymbol: IrClassSymbol) {
error("Must not be called")
}
override fun onMatchedCallables(expectSymbol: IrSymbol, actualSymbol: IrSymbol) {
error("Must not be called")
}
}
fun check() {
for (checker in checkers) {
checker.check(context = this)
}
}
}
@@ -3,8 +3,9 @@
* 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.backend.common.actualizer
package org.jetbrains.kotlin.backend.common.actualizer.checker
import org.jetbrains.kotlin.backend.common.actualizer.IrExpectActualMatchingContext
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.types.classOrFail