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 f8c1d95b2a8..6a918dbe2f2 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 @@ -23,7 +23,7 @@ internal class ExpectActualCollector(private val mainFragment: IrModuleFragment, val result = mutableMapOf() // Collect and link classifiers at first to make it possible to expand type aliases on the callables linking val (allActualDeclarations, typeAliasMap) = result.appendExpectActualClassifiersMap() - result.appendExpectActualCallablesMap(allActualDeclarations, typeAliasMap, dependentFragments) + result.appendExpectActualCallablesMap(allActualDeclarations, typeAliasMap) return result to typeAliasMap } @@ -44,92 +44,9 @@ internal class ExpectActualCollector(private val mainFragment: IrModuleFragment, return allActualDeclarations to typeAliasMap } - class ActualClassifiersCollector( - private val actualClassifiers: MutableMap, - private val allActualClassifiers: MutableSet, - private val typeAliasMap: MutableMap - ) : IrElementVisitor { - override fun visitTypeAlias(declaration: IrTypeAlias, data: Boolean) { - if (declaration.isActual) { - val expandedTypeSymbol = declaration.expandedType.classifierOrFail - actualClassifiers[declaration.kotlinFqName] = expandedTypeSymbol - if (expandedTypeSymbol is IrClassSymbol) { - allActualClassifiers.add(expandedTypeSymbol.owner) - typeAliasMap[declaration.kotlinFqName] = expandedTypeSymbol.owner.kotlinFqName - } - } - visitElement(declaration, data) - } - - override fun visitClass(declaration: IrClass, data: Boolean) { - if (!data && !declaration.isExpect) { - actualClassifiers[declaration.kotlinFqName] = declaration.symbol - } - visitDeclaration(declaration, data) - } - - override fun visitEnumEntry(declaration: IrEnumEntry, data: Boolean) { - if (!data && !declaration.isExpect) { - actualClassifiers[FqName.fromSegments( - listOf( - declaration.parent.kotlinFqName.asString(), - declaration.name.asString() - ) - )] = declaration.symbol - } - visitDeclaration(declaration, data) - } - - override fun visitDeclaration(declaration: IrDeclarationBase, data: Boolean) { - if (!data && !declaration.isExpect) { - allActualClassifiers.add(declaration) - } - visitElement(declaration, data || declaration.isExpect) - } - - override fun visitElement(element: IrElement, data: Boolean) { - element.acceptChildren(this, data) - } - } - - class ClassifiersLinkCollector( - private val expectActualMap: MutableMap, - private val actualClassifiers: Map - ) : IrElementVisitorVoid { - private fun addLinkOrReportMissing(expectElement: IrSymbolOwner, actualTypeId: FqName) { - val actualClassifier = actualClassifiers[actualTypeId] - if (actualClassifier != null) { - expectActualMap[expectElement.symbol] = actualClassifier - } else { - reportMissingActual(expectElement) - } - } - - override fun visitClass(declaration: IrClass) { - if (declaration.isExpect) { - addLinkOrReportMissing(declaration, declaration.kotlinFqName) - } - visitElement(declaration) - } - - override fun visitEnumEntry(declaration: IrEnumEntry) { - if (declaration.isProperExpect) { - addLinkOrReportMissing( - declaration, FqName.fromSegments(listOf(declaration.parent.kotlinFqName.asString(), declaration.name.asString())) - ) - } - visitElement(declaration) - } - - override fun visitElement(element: IrElement) { - element.acceptChildrenVoid(this) - } - } - private fun MutableMap.appendExpectActualCallablesMap( allActualDeclarations: Set, - typeAliasMap: Map, - dependentFragments: List + typeAliasMap: Map ) { val actualMembers = mutableMapOf() @@ -137,57 +54,139 @@ internal class ExpectActualCollector(private val mainFragment: IrModuleFragment, val collector = CallablesLinkCollector(this, actualMembers, typeAliasMap) dependentFragments.forEach { collector.visitModuleFragment(it) } } +} - private fun collectActualCallables( - expectActualMap: MutableMap, - actualMembers: MutableMap, - allActualDeclarations: Set, - ) { - fun collectActualsCallables(declaration: IrDeclaration) { - when (declaration) { - is IrFunction, - is IrProperty -> { - actualMembers[generateIrElementFullName(declaration, expectActualMap)] = declaration as IrDeclarationBase - } - is IrClass -> { - for (member in declaration.declarations) { - collectActualsCallables(member) - } - } +private class ActualClassifiersCollector( + private val actualClassifiers: MutableMap, + private val allActualClassifiers: MutableSet, + private val typeAliasMap: MutableMap +) : IrElementVisitor { + override fun visitTypeAlias(declaration: IrTypeAlias, data: Boolean) { + if (declaration.isActual) { + val expandedTypeSymbol = declaration.expandedType.classifierOrFail + actualClassifiers[declaration.kotlinFqName] = expandedTypeSymbol + if (expandedTypeSymbol is IrClassSymbol) { + allActualClassifiers.add(expandedTypeSymbol.owner) + typeAliasMap[declaration.kotlinFqName] = expandedTypeSymbol.owner.kotlinFqName } } - - for (actualDeclaration in allActualDeclarations) { - collectActualsCallables(actualDeclaration) - } + visitElement(declaration, data) } - class CallablesLinkCollector( - private val expectActualMap: MutableMap, - private val actualMembers: Map, - private val typeAliasMap: Map - ) : IrElementVisitorVoid { - override fun visitFunction(declaration: IrFunction) = addLink(declaration) - - override fun visitProperty(declaration: IrProperty) = addLink(declaration) - - private fun addLink(declaration: IrDeclarationBase) { - if (!declaration.isExpect) return - val member = actualMembers[generateIrElementFullName(declaration, expectActualMap, typeAliasMap)] - if (member != null) { - expectActualMap[declaration.symbol] = member.symbol - if (declaration is IrProperty) { - member as IrProperty - declaration.getter?.symbol?.let { expectActualMap[it] = member.getter!!.symbol } - declaration.setter?.symbol?.let { expectActualMap[it] = member.setter!!.symbol } - } - } else { - reportMissingActual(declaration) - } + override fun visitClass(declaration: IrClass, data: Boolean) { + if (!data && !declaration.isExpect) { + actualClassifiers[declaration.kotlinFqName] = declaration.symbol } + visitDeclaration(declaration, data) + } - override fun visitElement(element: IrElement) { - element.acceptChildrenVoid(this) + override fun visitEnumEntry(declaration: IrEnumEntry, data: Boolean) { + if (!data && !declaration.isExpect) { + actualClassifiers[FqName.fromSegments( + listOf( + declaration.parent.kotlinFqName.asString(), + declaration.name.asString() + ) + )] = declaration.symbol } + visitDeclaration(declaration, data) + } + + override fun visitDeclaration(declaration: IrDeclarationBase, data: Boolean) { + if (!data && !declaration.isExpect) { + allActualClassifiers.add(declaration) + } + visitElement(declaration, data || declaration.isExpect) + } + + override fun visitElement(element: IrElement, data: Boolean) { + element.acceptChildren(this, data) } } + +private class ClassifiersLinkCollector( + private val expectActualMap: MutableMap, + private val actualClassifiers: Map +) : IrElementVisitorVoid { + private fun addLinkOrReportMissing(expectElement: IrSymbolOwner, actualTypeId: FqName) { + val actualClassifier = actualClassifiers[actualTypeId] + if (actualClassifier != null) { + expectActualMap[expectElement.symbol] = actualClassifier + } else { + reportMissingActual(expectElement) + } + } + + override fun visitClass(declaration: IrClass) { + if (declaration.isExpect) { + addLinkOrReportMissing(declaration, declaration.kotlinFqName) + } + visitElement(declaration) + } + + override fun visitEnumEntry(declaration: IrEnumEntry) { + if (declaration.isProperExpect) { + addLinkOrReportMissing( + declaration, FqName.fromSegments(listOf(declaration.parent.kotlinFqName.asString(), declaration.name.asString())) + ) + } + visitElement(declaration) + } + + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } +} + +private fun collectActualCallables( + expectActualMap: MutableMap, + actualMembers: MutableMap, + allActualDeclarations: Set, +) { + fun collectActualsCallables(declaration: IrDeclaration) { + when (declaration) { + is IrFunction, + is IrProperty -> { + actualMembers[generateIrElementFullName(declaration, expectActualMap)] = declaration as IrDeclarationBase + } + is IrClass -> { + for (member in declaration.declarations) { + collectActualsCallables(member) + } + } + } + } + + for (actualDeclaration in allActualDeclarations) { + collectActualsCallables(actualDeclaration) + } +} + +private class CallablesLinkCollector( + private val expectActualMap: MutableMap, + private val actualMembers: Map, + private val typeAliasMap: Map +) : IrElementVisitorVoid { + override fun visitFunction(declaration: IrFunction) = addLink(declaration) + + override fun visitProperty(declaration: IrProperty) = addLink(declaration) + + private fun addLink(declaration: IrDeclarationBase) { + if (!declaration.isExpect) return + val member = actualMembers[generateIrElementFullName(declaration, expectActualMap, typeAliasMap)] + if (member != null) { + expectActualMap[declaration.symbol] = member.symbol + if (declaration is IrProperty) { + member as IrProperty + declaration.getter?.symbol?.let { expectActualMap[it] = member.getter!!.symbol } + declaration.setter?.symbol?.let { expectActualMap[it] = member.setter!!.symbol } + } + } else { + reportMissingActual(declaration) + } + } + + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } +} \ No newline at end of file