[K2, MPP] Correct actualization of nested objects
^KT-57182 Fixed
This commit is contained in:
committed by
Space Team
parent
8a3e2543f7
commit
d99b4c78d2
+15
-20
@@ -33,7 +33,7 @@ internal class ExpectActualCollector(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun MutableMap<IrSymbol, IrSymbol>.appendExpectActualClassifiersMap(): Pair<Set<IrDeclaration>, Map<FqName, FqName>> {
|
private fun MutableMap<IrSymbol, IrSymbol>.appendExpectActualClassifiersMap(): Pair<Set<IrDeclaration>, Map<FqName, FqName>> {
|
||||||
val actualClassifiers = mutableMapOf<FqName, IrSymbol>()
|
val actualClassifiers = mutableMapOf<String, IrSymbol>()
|
||||||
// There is no list for builtins declarations; that's why they are being collected from typealiases
|
// There is no list for builtins declarations; that's why they are being collected from typealiases
|
||||||
val allActualDeclarations = mutableSetOf<IrDeclaration>()
|
val allActualDeclarations = mutableSetOf<IrDeclaration>()
|
||||||
val typeAliasMap = mutableMapOf<FqName, FqName>() // It's used to link members from expect class that have typealias actual
|
val typeAliasMap = mutableMapOf<FqName, FqName>() // It's used to link members from expect class that have typealias actual
|
||||||
@@ -43,7 +43,7 @@ internal class ExpectActualCollector(
|
|||||||
ActualClassifiersCollector(actualClassifiers, allActualDeclarations, typeAliasMap).visitModuleFragment(fragment, false)
|
ActualClassifiersCollector(actualClassifiers, allActualDeclarations, typeAliasMap).visitModuleFragment(fragment, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
val linkCollector = ClassifiersLinkCollector(this, actualClassifiers, diagnosticsReporter)
|
val linkCollector = ClassifiersLinkCollector(this, actualClassifiers, typeAliasMap, diagnosticsReporter)
|
||||||
dependentFragments.forEach { linkCollector.visitModuleFragment(it) }
|
dependentFragments.forEach { linkCollector.visitModuleFragment(it) }
|
||||||
|
|
||||||
return allActualDeclarations to typeAliasMap
|
return allActualDeclarations to typeAliasMap
|
||||||
@@ -55,21 +55,21 @@ internal class ExpectActualCollector(
|
|||||||
) {
|
) {
|
||||||
val actualMembers = mutableMapOf<String, IrDeclarationBase>()
|
val actualMembers = mutableMapOf<String, IrDeclarationBase>()
|
||||||
|
|
||||||
collectActualCallables(this, actualMembers, allActualDeclarations)
|
collectActualCallables(this, actualMembers, typeAliasMap, allActualDeclarations)
|
||||||
val collector = CallablesLinkCollector(this, actualMembers, typeAliasMap, diagnosticsReporter)
|
val collector = CallablesLinkCollector(this, actualMembers, typeAliasMap, diagnosticsReporter)
|
||||||
dependentFragments.forEach { collector.visitModuleFragment(it) }
|
dependentFragments.forEach { collector.visitModuleFragment(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ActualClassifiersCollector(
|
private class ActualClassifiersCollector(
|
||||||
private val actualClassifiers: MutableMap<FqName, IrSymbol>,
|
private val actualClassifiers: MutableMap<String, IrSymbol>,
|
||||||
private val allActualClassifiers: MutableSet<IrDeclaration>,
|
private val allActualClassifiers: MutableSet<IrDeclaration>,
|
||||||
private val typeAliasMap: MutableMap<FqName, FqName>
|
private val typeAliasMap: MutableMap<FqName, FqName>
|
||||||
) : IrElementVisitor<Unit, Boolean> {
|
) : IrElementVisitor<Unit, Boolean> {
|
||||||
override fun visitTypeAlias(declaration: IrTypeAlias, data: Boolean) {
|
override fun visitTypeAlias(declaration: IrTypeAlias, data: Boolean) {
|
||||||
if (declaration.isActual) {
|
if (declaration.isActual) {
|
||||||
val expandedTypeSymbol = declaration.expandedType.classifierOrFail
|
val expandedTypeSymbol = declaration.expandedType.classifierOrFail
|
||||||
actualClassifiers[declaration.kotlinFqName] = expandedTypeSymbol
|
actualClassifiers[generateIrElementFullName(declaration)] = expandedTypeSymbol
|
||||||
if (expandedTypeSymbol is IrClassSymbol) {
|
if (expandedTypeSymbol is IrClassSymbol) {
|
||||||
allActualClassifiers.add(expandedTypeSymbol.owner)
|
allActualClassifiers.add(expandedTypeSymbol.owner)
|
||||||
typeAliasMap[declaration.kotlinFqName] = expandedTypeSymbol.owner.kotlinFqName
|
typeAliasMap[declaration.kotlinFqName] = expandedTypeSymbol.owner.kotlinFqName
|
||||||
@@ -80,19 +80,14 @@ private class ActualClassifiersCollector(
|
|||||||
|
|
||||||
override fun visitClass(declaration: IrClass, data: Boolean) {
|
override fun visitClass(declaration: IrClass, data: Boolean) {
|
||||||
if (!data && !declaration.isExpect) {
|
if (!data && !declaration.isExpect) {
|
||||||
actualClassifiers[declaration.kotlinFqName] = declaration.symbol
|
actualClassifiers[generateIrElementFullName(declaration)] = declaration.symbol
|
||||||
}
|
}
|
||||||
visitDeclaration(declaration, data)
|
visitDeclaration(declaration, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitEnumEntry(declaration: IrEnumEntry, data: Boolean) {
|
override fun visitEnumEntry(declaration: IrEnumEntry, data: Boolean) {
|
||||||
if (!data && !declaration.isExpect) {
|
if (!data && !declaration.isExpect) {
|
||||||
actualClassifiers[FqName.fromSegments(
|
actualClassifiers[generateIrElementFullName(declaration)] = declaration.symbol
|
||||||
listOf(
|
|
||||||
declaration.parent.kotlinFqName.asString(),
|
|
||||||
declaration.name.asString()
|
|
||||||
)
|
|
||||||
)] = declaration.symbol
|
|
||||||
}
|
}
|
||||||
visitDeclaration(declaration, data)
|
visitDeclaration(declaration, data)
|
||||||
}
|
}
|
||||||
@@ -111,11 +106,12 @@ private class ActualClassifiersCollector(
|
|||||||
|
|
||||||
private class ClassifiersLinkCollector(
|
private class ClassifiersLinkCollector(
|
||||||
private val expectActualMap: MutableMap<IrSymbol, IrSymbol>,
|
private val expectActualMap: MutableMap<IrSymbol, IrSymbol>,
|
||||||
private val actualClassifiers: Map<FqName, IrSymbol>,
|
private val actualClassifiers: Map<String, IrSymbol>,
|
||||||
|
private val typeAliasMap: Map<FqName, FqName>,
|
||||||
private val diagnosticsReporter: KtDiagnosticReporterWithImplicitIrBasedContext
|
private val diagnosticsReporter: KtDiagnosticReporterWithImplicitIrBasedContext
|
||||||
) : IrElementVisitorVoid {
|
) : IrElementVisitorVoid {
|
||||||
private fun addLinkOrReportMissing(expectElement: IrDeclaration, actualTypeId: FqName) {
|
private fun addLinkOrReportMissing(expectElement: IrDeclaration) {
|
||||||
val actualClassifier = actualClassifiers[actualTypeId]
|
val actualClassifier = actualClassifiers[generateIrElementFullName(expectElement, expectActualMap, typeAliasMap)]
|
||||||
if (actualClassifier != null) {
|
if (actualClassifier != null) {
|
||||||
expectActualMap[expectElement.symbol] = actualClassifier
|
expectActualMap[expectElement.symbol] = actualClassifier
|
||||||
} else if (!expectElement.containsOptionalExpectation()) {
|
} else if (!expectElement.containsOptionalExpectation()) {
|
||||||
@@ -125,16 +121,14 @@ private class ClassifiersLinkCollector(
|
|||||||
|
|
||||||
override fun visitClass(declaration: IrClass) {
|
override fun visitClass(declaration: IrClass) {
|
||||||
if (declaration.isExpect) {
|
if (declaration.isExpect) {
|
||||||
addLinkOrReportMissing(declaration, declaration.kotlinFqName)
|
addLinkOrReportMissing(declaration)
|
||||||
}
|
}
|
||||||
visitElement(declaration)
|
visitElement(declaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitEnumEntry(declaration: IrEnumEntry) {
|
override fun visitEnumEntry(declaration: IrEnumEntry) {
|
||||||
if (declaration.isProperExpect) {
|
if (declaration.isProperExpect) {
|
||||||
addLinkOrReportMissing(
|
addLinkOrReportMissing(declaration)
|
||||||
declaration, FqName.fromSegments(listOf(declaration.parent.kotlinFqName.asString(), declaration.name.asString()))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
visitElement(declaration)
|
visitElement(declaration)
|
||||||
}
|
}
|
||||||
@@ -147,13 +141,14 @@ private class ClassifiersLinkCollector(
|
|||||||
private fun collectActualCallables(
|
private fun collectActualCallables(
|
||||||
expectActualMap: MutableMap<IrSymbol, IrSymbol>,
|
expectActualMap: MutableMap<IrSymbol, IrSymbol>,
|
||||||
actualMembers: MutableMap<String, IrDeclarationBase>,
|
actualMembers: MutableMap<String, IrDeclarationBase>,
|
||||||
|
typeAliasMap: Map<FqName, FqName>,
|
||||||
allActualDeclarations: Set<IrDeclaration>,
|
allActualDeclarations: Set<IrDeclaration>,
|
||||||
) {
|
) {
|
||||||
fun collectActualsCallables(declaration: IrDeclaration) {
|
fun collectActualsCallables(declaration: IrDeclaration) {
|
||||||
when (declaration) {
|
when (declaration) {
|
||||||
is IrFunction,
|
is IrFunction,
|
||||||
is IrProperty -> {
|
is IrProperty -> {
|
||||||
actualMembers[generateIrElementFullName(declaration, expectActualMap)] = declaration as IrDeclarationBase
|
actualMembers[generateIrElementFullName(declaration, expectActualMap, typeAliasMap)] = declaration as IrDeclarationBase
|
||||||
}
|
}
|
||||||
is IrClass -> {
|
is IrClass -> {
|
||||||
for (member in declaration.declarations) {
|
for (member in declaration.declarations) {
|
||||||
|
|||||||
+26
-9
@@ -22,23 +22,40 @@ import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
|
|||||||
|
|
||||||
fun generateIrElementFullName(
|
fun generateIrElementFullName(
|
||||||
declaration: IrElement,
|
declaration: IrElement,
|
||||||
expectActualTypesMap: Map<IrSymbol, IrSymbol>,
|
expectActualTypesMap: Map<IrSymbol, IrSymbol>? = null,
|
||||||
typeAliasMap: Map<FqName, FqName>? = null
|
typeAliasMap: Map<FqName, FqName>? = null
|
||||||
): String {
|
): String {
|
||||||
return StringBuilder().apply { appendElementFullName(declaration, expectActualTypesMap, this, typeAliasMap) }.toString()
|
return StringBuilder().apply { appendElementFullName(declaration, this, expectActualTypesMap, typeAliasMap) }.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun appendElementFullName(
|
private fun appendElementFullName(
|
||||||
declaration: IrElement,
|
declaration: IrElement,
|
||||||
expectActualTypesMap: Map<IrSymbol, IrSymbol>,
|
|
||||||
result: StringBuilder,
|
result: StringBuilder,
|
||||||
typeAliasMap: Map<FqName, FqName>? = null
|
expectActualTypesMap: Map<IrSymbol, IrSymbol>? = null,
|
||||||
|
expectActualTypeAliasMap: Map<FqName, FqName>? = null
|
||||||
) {
|
) {
|
||||||
if (declaration !is IrDeclarationBase) return
|
if (declaration !is IrDeclarationBase) return
|
||||||
|
|
||||||
val parentName = declaration.parent.kotlinFqName
|
val parents = mutableListOf<String>()
|
||||||
if (parentName.asString().isNotEmpty()) {
|
var parent: IrDeclarationParent? = declaration.parent
|
||||||
result.append(typeAliasMap?.get(parentName) ?: parentName.asString())
|
while (parent != null) {
|
||||||
|
if (parent is IrDeclarationWithName) {
|
||||||
|
val parentParent = parent.parent
|
||||||
|
if (parentParent is IrClass) {
|
||||||
|
parents.add(parent.name.asString())
|
||||||
|
parent = parentParent
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val parentString = parent.kotlinFqName.let { (expectActualTypeAliasMap?.get(it) ?: it).asString() }
|
||||||
|
if (parentString.isNotEmpty()) {
|
||||||
|
parents.add(parentString)
|
||||||
|
}
|
||||||
|
parent = null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parents.isNotEmpty()) {
|
||||||
|
result.append(parents.asReversed().joinToString(separator = "."))
|
||||||
result.append('.')
|
result.append('.')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,8 +66,8 @@ private fun appendElementFullName(
|
|||||||
if (declaration is IrFunction) {
|
if (declaration is IrFunction) {
|
||||||
fun appendType(type: IrType) {
|
fun appendType(type: IrType) {
|
||||||
val typeClassifier = type.classifierOrFail
|
val typeClassifier = type.classifierOrFail
|
||||||
val actualizedTypeSymbol = expectActualTypesMap[typeClassifier] ?: typeClassifier
|
val actualizedTypeSymbol = expectActualTypesMap?.get(typeClassifier) ?: typeClassifier
|
||||||
appendElementFullName(actualizedTypeSymbol.owner, expectActualTypesMap, result)
|
appendElementFullName(actualizedTypeSymbol.owner, result, expectActualTypesMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
val extensionReceiverType = declaration.extensionReceiverParameter?.type
|
val extensionReceiverType = declaration.extensionReceiverParameter?.type
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
// MODULE: m1-common
|
|
||||||
// FILE: common.kt
|
|
||||||
|
|
||||||
expect sealed class Presence {
|
|
||||||
<!NO_ACTUAL_FOR_EXPECT{JVM}!>object Online: Presence<!>
|
|
||||||
<!NO_ACTUAL_FOR_EXPECT{JVM}!>object Offline: Presence<!>
|
|
||||||
}
|
|
||||||
|
|
||||||
// MODULE: m2-jvm()()(m1-common)
|
|
||||||
// FILE: jvm.kt
|
|
||||||
|
|
||||||
actual typealias Presence = P
|
|
||||||
sealed class P {
|
|
||||||
object Online : P()
|
|
||||||
object Offline : P()
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// MODULE: m1-common
|
// MODULE: m1-common
|
||||||
// FILE: common.kt
|
// FILE: common.kt
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user