From 5b2a1feaf0c2a0f42740fcb0a91143e291df5456 Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Thu, 16 Feb 2023 22:59:45 +0100 Subject: [PATCH] [IR] Support of @OptionalExpectation in IrActualizer ^KT-56579 Fixed --- .../common/actualizer/ExpectActualCollector.kt | 4 ++-- .../backend/common/actualizer/IrActualizer.kt | 15 ++++++++++++--- .../common/actualizer/IrActualizerUtils.kt | 14 +++++++++++++- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/ExpectActualCollector.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/ExpectActualCollector.kt index c534d23984d..6f14e49b8cf 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/ExpectActualCollector.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/ExpectActualCollector.kt @@ -112,7 +112,7 @@ private class ClassifiersLinkCollector( val actualClassifier = actualClassifiers[actualTypeId] if (actualClassifier != null) { expectActualMap[expectElement.symbol] = actualClassifier - } else { + } else if (!expectElement.containsOptionalExpectation()) { reportMissingActual(expectElement) } } @@ -181,7 +181,7 @@ private class CallablesLinkCollector( declaration.getter?.symbol?.let { expectActualMap[it] = actualProperty.getter!!.symbol } declaration.setter?.symbol?.let { expectActualMap[it] = actualProperty.setter!!.symbol } } - } else { + } else if (!declaration.parent.containsOptionalExpectation()) { reportMissingActual(declaration) } } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrActualizer.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrActualizer.kt index 83324ee8b81..f8646949c80 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrActualizer.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrActualizer.kt @@ -14,20 +14,29 @@ object IrActualizer { fun actualize(mainFragment: IrModuleFragment, dependentFragments: List) { val (expectActualMap, typeAliasMap) = ExpectActualCollector(mainFragment, dependentFragments).collect() FunctionDefaultParametersActualizer(expectActualMap).actualize() - removeExpectDeclarations(dependentFragments) + removeExpectDeclarations(dependentFragments, expectActualMap) addMissingFakeOverrides(expectActualMap, dependentFragments, typeAliasMap) linkExpectToActual(expectActualMap, dependentFragments) mergeIrFragments(mainFragment, dependentFragments) } - private fun removeExpectDeclarations(dependentFragments: List) { + private fun removeExpectDeclarations(dependentFragments: List, expectActualMap: Map) { for (fragment in dependentFragments) { for (file in fragment.files) { - file.declarations.removeAll { it.isProperExpect } + file.declarations.removeIf { shouldRemoveExpectDeclaration(it, expectActualMap) } } } } + private fun shouldRemoveExpectDeclaration(irDeclaration: IrDeclaration, expectActualMap: Map): Boolean { + return when (irDeclaration) { + is IrClass -> irDeclaration.isExpect && (!irDeclaration.containsOptionalExpectation() || expectActualMap.containsKey(irDeclaration.symbol)) + is IrProperty -> irDeclaration.isExpect + is IrFunction -> irDeclaration.isExpect + else -> false + } + } + private fun addMissingFakeOverrides( expectActualMap: Map, dependentFragments: List, diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrActualizerUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrActualizerUtils.kt index f05547e3099..964ea22e7f1 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrActualizerUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrActualizerUtils.kt @@ -5,14 +5,20 @@ package org.jetbrains.kotlin.backend.common.actualizer +import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrDeclarationBase +import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName +import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classifierOrFail +import org.jetbrains.kotlin.ir.util.hasAnnotation import org.jetbrains.kotlin.ir.util.kotlinFqName import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil fun generateIrElementFullName( declaration: IrElement, @@ -73,4 +79,10 @@ fun reportMissingActual(irElement: IrElement) { fun reportManyInterfacesMembersNotImplemented(declaration: IrClass, actualMember: IrDeclarationWithName) { // TODO: setup diagnostics reporting throw AssertionError("${declaration.name} must override ${actualMember.name} because it inherits multiple interface methods of it") +} + +internal fun IrElement.containsOptionalExpectation(): Boolean { + return this is IrClass && + this.kind == ClassKind.ANNOTATION_CLASS && + this.hasAnnotation(OptionalAnnotationUtil.OPTIONAL_EXPECTATION_FQ_NAME) } \ No newline at end of file