[IR] Support of @OptionalExpectation in IrActualizer

^KT-56579 Fixed
This commit is contained in:
Ivan Kochurkin
2023-02-16 22:59:45 +01:00
committed by Space Team
parent c10bd1e3f0
commit 5b2a1feaf0
3 changed files with 27 additions and 6 deletions
@@ -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)
}
}
@@ -14,20 +14,29 @@ object IrActualizer {
fun actualize(mainFragment: IrModuleFragment, dependentFragments: List<IrModuleFragment>) {
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<IrModuleFragment>) {
private fun removeExpectDeclarations(dependentFragments: List<IrModuleFragment>, expectActualMap: Map<IrSymbol, IrSymbol>) {
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<IrSymbol, IrSymbol>): 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<IrSymbol, IrSymbol>,
dependentFragments: List<IrModuleFragment>,
@@ -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)
}