[IR] Support of @OptionalExpectation in IrActualizer
^KT-56579 Fixed
This commit is contained in:
committed by
Space Team
parent
c10bd1e3f0
commit
5b2a1feaf0
+2
-2
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+12
-3
@@ -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>,
|
||||
|
||||
+13
-1
@@ -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)
|
||||
}
|
||||
Reference in New Issue
Block a user