Actualize `expect` declarations with in-module `actual` counterparts
It is crucial for the @OptionalAnnotation metadata serialization
correctness.
^KT-67340: Fixed
diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/convertToIr.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/convertToIr.kt
index bfc3aa7..605ca14 100644
--- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/convertToIr.kt
+++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/convertToIr.kt
@@ -147,7 +147,7 @@
}
}
- val irActualizer = if (dependentIrFragments.isEmpty()) null else IrActualizer(
+ val irActualizer = IrActualizer(
KtDiagnosticReporterWithImplicitIrBasedContext(
fir2IrConfiguration.diagnosticReporter,
fir2IrConfiguration.languageVersionSettings
@@ -164,11 +164,11 @@
// So to avoid even more changes, when this mode is disabled, we don't run classifiers
// actualization separately. This should go away, after useIrFakeOverrideBuilder becomes
// always enabled
- irActualizer?.actualizeClassifiers()
+ irActualizer.actualizeClassifiers()
val temporaryResolver = SpecialFakeOverrideSymbolsResolver(emptyMap())
platformComponentsStorage.fakeOverrideBuilder.buildForAll(dependentIrFragments + mainIrFragment, temporaryResolver)
}
- val expectActualMap = irActualizer?.actualizeCallablesAndMergeModules() ?: emptyMap()
+ val expectActualMap = irActualizer.actualizeCallablesAndMergeModules()
val fakeOverrideResolver = runIf(!platformComponentsStorage.configuration.useFirBasedFakeOverrideGenerator) {
val fakeOverrideResolver = SpecialFakeOverrideSymbolsResolver(expectActualMap)
mainIrFragment.acceptVoid(SpecialFakeOverrideSymbolsResolverVisitor(fakeOverrideResolver))
@@ -177,7 +177,7 @@
fakeOverrideResolver
}
Fir2IrConverter.evaluateConstants(mainIrFragment, platformComponentsStorage)
- val actualizationResult = irActualizer?.runChecksAndFinalize(expectActualMap)
+ val actualizationResult = irActualizer.runChecksAndFinalize(expectActualMap)
fakeOverrideResolver?.cacheFakeOverridesOfAllClasses(mainIrFragment)
diff --git a/compiler/ir/ir.actualization/src/main/kotlin/org/jetbrains/kotlin/backend/common/actualizer/IrActualizer.kt b/compiler/ir/ir.actualization/src/main/kotlin/org/jetbrains/kotlin/backend/common/actualizer/IrActualizer.kt
index 3ad61d0..d7a72a1 100644
--- a/compiler/ir/ir.actualization/src/main/kotlin/org/jetbrains/kotlin/backend/common/actualizer/IrActualizer.kt
+++ b/compiler/ir/ir.actualization/src/main/kotlin/org/jetbrains/kotlin/backend/common/actualizer/IrActualizer.kt
@@ -108,15 +108,15 @@
fun runChecksAndFinalize(expectActualMap: Map<IrSymbol, IrSymbol>) : IrActualizedResult {
// Remove top-only expect declarations since they are not needed anymore and should not be presented in the final IrFragment
// Also, it doesn't remove unactualized expect declarations marked with @OptionalExpectation
- val removedExpectDeclarations = removeExpectDeclarations(dependentFragments, expectActualMap)
+ val removedExpectDeclarations = removeExpectDeclarations(dependentFragments + mainFragment, expectActualMap)
IrExpectActualCheckers(expectActualMap, classActualizationInfo, typeSystemContext, ktDiagnosticReporter).check()
return IrActualizedResult(removedExpectDeclarations, expectActualMap)
}
- private fun removeExpectDeclarations(dependentFragments: List<IrModuleFragment>, expectActualMap: Map<IrSymbol, IrSymbol>): List<IrDeclaration> {
+ private fun removeExpectDeclarations(fragments: List<IrModuleFragment>, expectActualMap: Map<IrSymbol, IrSymbol>): List<IrDeclaration> {
val removedExpectDeclarations = mutableListOf<IrDeclaration>()
- for (fragment in dependentFragments) {
+ for (fragment in fragments) {
for (file in fragment.files) {
file.declarations.removeIf {
if (shouldRemoveExpectDeclaration(it, expectActualMap)) {
diff --git a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt
index 1dcbb54..eb91265 100644
--- a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt
+++ b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt
@@ -29,6 +29,7 @@
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.fir.FirAnalyzerFacade
import org.jetbrains.kotlin.fir.FirTestSessionFactoryHelper
+import org.jetbrains.kotlin.fir.backend.extractFirDeclarations
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
import org.jetbrains.kotlin.fir.backend.jvm.JvmFir2IrExtensions
@@ -121,12 +122,13 @@
val fir2IrExtensions = JvmFir2IrExtensions(configuration, JvmIrDeserializerImpl(), JvmIrMangler)
val diagnosticReporter = DiagnosticReporterFactory.createReporter()
firAnalyzerFacade.runResolution()
- val (moduleFragment, components, pluginContext) = firAnalyzerFacade.result.convertToIrAndActualizeForJvm(
- fir2IrExtensions,
- configuration,
- diagnosticReporter,
- irGeneratorExtensions = emptyList()
- )
+ val (moduleFragment, components, pluginContext, actualizedExpectDeclarations) =
+ firAnalyzerFacade.result.convertToIrAndActualizeForJvm(
+ fir2IrExtensions,
+ configuration,
+ diagnosticReporter,
+ irGeneratorExtensions = emptyList()
+ )
val dummyBindingContext = NoScopeRecordCliBindingTrace(project).bindingContext
@@ -148,8 +150,13 @@
generationState.beforeCompile()
generationState.oldBEInitTrace(files)
codegenFactory.generateModuleInFrontendIRMode(
- generationState, moduleFragment, components.symbolTable, components.irProviders,
- fir2IrExtensions, FirJvmBackendExtension(components, actualizedExpectDeclarations = null), pluginContext,
+ generationState,
+ moduleFragment,
+ components.symbolTable,
+ components.irProviders,
+ fir2IrExtensions,
+ FirJvmBackendExtension(components, actualizedExpectDeclarations?.actualizedExpectDeclarations?.extractFirDeclarations()),
+ pluginContext,
) {}
generationState.factory.done()
diff --git a/libraries/tools/kotlinp/jvm/testData/OptionalAnnotation.kt b/libraries/tools/kotlinp/jvm/testData/OptionalAnnotation.kt
index 367e5db..85fc91e 100644
--- a/libraries/tools/kotlinp/jvm/testData/OptionalAnnotation.kt
+++ b/libraries/tools/kotlinp/jvm/testData/OptionalAnnotation.kt
@@ -1,6 +1,3 @@
-// IGNORE K2
-// ^ KT-62931 K2: extra class files for @OptionalExpectation marked annotations
-
// !LANGUAGE: +MultiPlatformProjects
// !OPT_IN: kotlin.ExperimentalMultiplatform
// NO_READ_WRITE_COMPARE