[K2, MPP] Restore ir functions actualization by argument types instead of full signatures
Refactor IrActualizer
This commit is contained in:
committed by
Space Team
parent
d99b4c78d2
commit
ec34b9fa7b
+99
-111
@@ -6,15 +6,12 @@
|
|||||||
package org.jetbrains.kotlin.backend.common.actualizer
|
package org.jetbrains.kotlin.backend.common.actualizer
|
||||||
|
|
||||||
import org.jetbrains.kotlin.KtDiagnosticReporterWithImplicitIrBasedContext
|
import org.jetbrains.kotlin.KtDiagnosticReporterWithImplicitIrBasedContext
|
||||||
import org.jetbrains.kotlin.backend.common.ir.isExpect
|
|
||||||
import org.jetbrains.kotlin.backend.common.ir.isProperExpect
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||||
import org.jetbrains.kotlin.ir.util.kotlinFqName
|
import org.jetbrains.kotlin.ir.util.kotlinFqName
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -26,110 +23,119 @@ internal class ExpectActualCollector(
|
|||||||
) {
|
) {
|
||||||
fun collect(): Pair<Map<IrSymbol, IrSymbol>, Map<FqName, FqName>> {
|
fun collect(): Pair<Map<IrSymbol, IrSymbol>, Map<FqName, FqName>> {
|
||||||
val result = mutableMapOf<IrSymbol, IrSymbol>()
|
val result = mutableMapOf<IrSymbol, IrSymbol>()
|
||||||
// Collect and link classifiers at first to make it possible to expand type aliases on the callables linking
|
// Collect and link classes at first to make it possible to expand type aliases on the members linking
|
||||||
val (allActualDeclarations, typeAliasMap) = result.appendExpectActualClassifiersMap()
|
val (actualMembers, expectActualTypeAliasMap) = result.appendExpectActualClassMap()
|
||||||
result.appendExpectActualCallablesMap(allActualDeclarations, typeAliasMap)
|
result.appendExpectActualMemberMap(actualMembers, expectActualTypeAliasMap)
|
||||||
return result to typeAliasMap
|
return result to expectActualTypeAliasMap
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MutableMap<IrSymbol, IrSymbol>.appendExpectActualClassifiersMap(): Pair<Set<IrDeclaration>, Map<FqName, FqName>> {
|
private fun MutableMap<IrSymbol, IrSymbol>.appendExpectActualClassMap(): Pair<List<IrDeclarationBase>, Map<FqName, FqName>> {
|
||||||
val actualClassifiers = mutableMapOf<String, IrSymbol>()
|
val actualClasses = mutableMapOf<String, IrClassSymbol>()
|
||||||
// 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 actualMembers = mutableListOf<IrDeclarationBase>()
|
||||||
val typeAliasMap = mutableMapOf<FqName, FqName>() // It's used to link members from expect class that have typealias actual
|
val expectActualTypeAliasMap = mutableMapOf<FqName, FqName>() // It's used to link members from expect class that have typealias actual
|
||||||
|
|
||||||
val fragmentsWithActuals = (dependentFragments.drop(1) + mainFragment)
|
val fragmentsWithActuals = dependentFragments.drop(1) + mainFragment
|
||||||
for (fragment in fragmentsWithActuals) {
|
val actualClassesAndMembersCollector = ActualClassesAndMembersCollector(actualClasses, actualMembers, expectActualTypeAliasMap)
|
||||||
ActualClassifiersCollector(actualClassifiers, allActualDeclarations, typeAliasMap).visitModuleFragment(fragment, false)
|
fragmentsWithActuals.forEach { actualClassesAndMembersCollector.collect(it) }
|
||||||
}
|
|
||||||
|
|
||||||
val linkCollector = ClassifiersLinkCollector(this, actualClassifiers, typeAliasMap, diagnosticsReporter)
|
val linkCollector = ClassLinksCollector(this, actualClasses, expectActualTypeAliasMap, diagnosticsReporter)
|
||||||
dependentFragments.forEach { linkCollector.visitModuleFragment(it) }
|
dependentFragments.forEach { linkCollector.visitModuleFragment(it) }
|
||||||
|
|
||||||
return allActualDeclarations to typeAliasMap
|
return actualMembers to expectActualTypeAliasMap
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MutableMap<IrSymbol, IrSymbol>.appendExpectActualCallablesMap(
|
private fun MutableMap<IrSymbol, IrSymbol>.appendExpectActualMemberMap(
|
||||||
allActualDeclarations: Set<IrDeclaration>,
|
actualMembers: List<IrDeclarationBase>,
|
||||||
typeAliasMap: Map<FqName, FqName>
|
expectActualTypeAliasMap: Map<FqName, FqName>
|
||||||
) {
|
) {
|
||||||
val actualMembers = mutableMapOf<String, IrDeclarationBase>()
|
val actualMembersMap = mutableMapOf<String, MutableList<IrDeclarationBase>>()
|
||||||
|
for (actualMember in actualMembers) {
|
||||||
collectActualCallables(this, actualMembers, typeAliasMap, allActualDeclarations)
|
actualMembersMap.getOrPut(generateIrElementFullNameFromExpect(actualMember, expectActualTypeAliasMap)) { mutableListOf() }
|
||||||
val collector = CallablesLinkCollector(this, actualMembers, typeAliasMap, diagnosticsReporter)
|
.add(actualMember)
|
||||||
|
}
|
||||||
|
val collector = MemberLinksCollector(this, actualMembersMap, expectActualTypeAliasMap, diagnosticsReporter)
|
||||||
dependentFragments.forEach { collector.visitModuleFragment(it) }
|
dependentFragments.forEach { collector.visitModuleFragment(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ActualClassifiersCollector(
|
private class ActualClassesAndMembersCollector(
|
||||||
private val actualClassifiers: MutableMap<String, IrSymbol>,
|
private val actualClasses: MutableMap<String, IrClassSymbol>,
|
||||||
private val allActualClassifiers: MutableSet<IrDeclaration>,
|
private val actualMembers: MutableList<IrDeclarationBase>,
|
||||||
private val typeAliasMap: MutableMap<FqName, FqName>
|
private val expectActualTypeAliasMap: MutableMap<FqName, FqName>
|
||||||
) : IrElementVisitor<Unit, Boolean> {
|
) {
|
||||||
override fun visitTypeAlias(declaration: IrTypeAlias, data: Boolean) {
|
private val visitedActualClasses = mutableSetOf<IrClass>()
|
||||||
if (declaration.isActual) {
|
|
||||||
val expandedTypeSymbol = declaration.expandedType.classifierOrFail
|
fun collect(element: IrElement) {
|
||||||
actualClassifiers[generateIrElementFullName(declaration)] = expandedTypeSymbol
|
when (element) {
|
||||||
if (expandedTypeSymbol is IrClassSymbol) {
|
is IrModuleFragment -> {
|
||||||
allActualClassifiers.add(expandedTypeSymbol.owner)
|
for (file in element.files) {
|
||||||
typeAliasMap[declaration.kotlinFqName] = expandedTypeSymbol.owner.kotlinFqName
|
collect(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is IrTypeAlias -> {
|
||||||
|
if (!element.isActual) return
|
||||||
|
|
||||||
|
val expandedTypeSymbol = element.expandedType.classifierOrFail as IrClassSymbol
|
||||||
|
addActualClass(element, expandedTypeSymbol)
|
||||||
|
collect(expandedTypeSymbol.owner)
|
||||||
|
|
||||||
|
expectActualTypeAliasMap[element.kotlinFqName] = expandedTypeSymbol.owner.kotlinFqName
|
||||||
|
}
|
||||||
|
is IrClass -> {
|
||||||
|
if (element.isExpect || !visitedActualClasses.add(element)) return
|
||||||
|
|
||||||
|
addActualClass(element, element.symbol)
|
||||||
|
for (declaration in element.declarations) {
|
||||||
|
collect(declaration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is IrDeclarationContainer -> {
|
||||||
|
for (declaration in element.declarations) {
|
||||||
|
collect(declaration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is IrEnumEntry -> {
|
||||||
|
actualMembers.add(element) // If enum entry is located inside expect enum, then this code is not executed
|
||||||
|
}
|
||||||
|
is IrProperty -> {
|
||||||
|
if (element.isExpect) return
|
||||||
|
actualMembers.add(element)
|
||||||
|
}
|
||||||
|
is IrFunction -> {
|
||||||
|
if (element.isExpect) return
|
||||||
|
actualMembers.add(element)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
visitElement(declaration, data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitClass(declaration: IrClass, data: Boolean) {
|
private fun addActualClass(classOrTypeAlias: IrElement, classSymbol: IrClassSymbol) {
|
||||||
if (!data && !declaration.isExpect) {
|
actualClasses[generateActualIrClassOrTypeAliasFullName(classOrTypeAlias)] = classSymbol
|
||||||
actualClassifiers[generateIrElementFullName(declaration)] = declaration.symbol
|
|
||||||
}
|
|
||||||
visitDeclaration(declaration, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitEnumEntry(declaration: IrEnumEntry, data: Boolean) {
|
|
||||||
if (!data && !declaration.isExpect) {
|
|
||||||
actualClassifiers[generateIrElementFullName(declaration)] = 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 class ClassLinksCollector(
|
||||||
private val expectActualMap: MutableMap<IrSymbol, IrSymbol>,
|
private val expectActualMap: MutableMap<IrSymbol, IrSymbol>,
|
||||||
private val actualClassifiers: Map<String, IrSymbol>,
|
private val actualClasses: Map<String, IrClassSymbol>,
|
||||||
private val typeAliasMap: Map<FqName, FqName>,
|
private val expectActualTypeAliasMap: Map<FqName, FqName>,
|
||||||
private val diagnosticsReporter: KtDiagnosticReporterWithImplicitIrBasedContext
|
private val diagnosticsReporter: KtDiagnosticReporterWithImplicitIrBasedContext
|
||||||
) : IrElementVisitorVoid {
|
) : IrElementVisitorVoid {
|
||||||
private fun addLinkOrReportMissing(expectElement: IrDeclaration) {
|
|
||||||
val actualClassifier = actualClassifiers[generateIrElementFullName(expectElement, expectActualMap, typeAliasMap)]
|
|
||||||
if (actualClassifier != null) {
|
|
||||||
expectActualMap[expectElement.symbol] = actualClassifier
|
|
||||||
} else if (!expectElement.containsOptionalExpectation()) {
|
|
||||||
diagnosticsReporter.reportMissingActual(expectElement)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitClass(declaration: IrClass) {
|
override fun visitClass(declaration: IrClass) {
|
||||||
if (declaration.isExpect) {
|
if (!declaration.isExpect) return
|
||||||
addLinkOrReportMissing(declaration)
|
|
||||||
}
|
|
||||||
visitElement(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitEnumEntry(declaration: IrEnumEntry) {
|
val actualClassSymbol = actualClasses[generateIrElementFullNameFromExpect(declaration, expectActualTypeAliasMap)]
|
||||||
if (declaration.isProperExpect) {
|
if (actualClassSymbol != null) {
|
||||||
addLinkOrReportMissing(declaration)
|
expectActualMap[declaration.symbol] = actualClassSymbol
|
||||||
|
val actualClass = actualClassSymbol.owner
|
||||||
|
for (expectTypeParameter in declaration.typeParameters) {
|
||||||
|
actualClass.typeParameters.firstOrNull { it.name == expectTypeParameter.name }?.let { actualTypeParameter ->
|
||||||
|
expectActualMap[expectTypeParameter.symbol] = actualTypeParameter.symbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!declaration.containsOptionalExpectation()) {
|
||||||
|
diagnosticsReporter.reportMissingActual(declaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
visitElement(declaration)
|
visitElement(declaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,44 +144,26 @@ private class ClassifiersLinkCollector(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun collectActualCallables(
|
private class MemberLinksCollector(
|
||||||
expectActualMap: MutableMap<IrSymbol, IrSymbol>,
|
|
||||||
actualMembers: MutableMap<String, IrDeclarationBase>,
|
|
||||||
typeAliasMap: Map<FqName, FqName>,
|
|
||||||
allActualDeclarations: Set<IrDeclaration>,
|
|
||||||
) {
|
|
||||||
fun collectActualsCallables(declaration: IrDeclaration) {
|
|
||||||
when (declaration) {
|
|
||||||
is IrFunction,
|
|
||||||
is IrProperty -> {
|
|
||||||
actualMembers[generateIrElementFullName(declaration, expectActualMap, typeAliasMap)] = 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<IrSymbol, IrSymbol>,
|
private val expectActualMap: MutableMap<IrSymbol, IrSymbol>,
|
||||||
private val actualMembers: Map<String, IrDeclarationBase>,
|
private val actualMembers: Map<String, List<IrDeclarationBase>>,
|
||||||
private val typeAliasMap: Map<FqName, FqName>,
|
private val typeAliasMap: Map<FqName, FqName>,
|
||||||
private val diagnosticsReporter: KtDiagnosticReporterWithImplicitIrBasedContext
|
private val diagnosticsReporter: KtDiagnosticReporterWithImplicitIrBasedContext
|
||||||
) : IrElementVisitorVoid {
|
) : IrElementVisitorVoid {
|
||||||
override fun visitFunction(declaration: IrFunction) = addLink(declaration)
|
override fun visitFunction(declaration: IrFunction) {
|
||||||
|
if (declaration.isExpect) addLink(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitProperty(declaration: IrProperty) = addLink(declaration)
|
override fun visitProperty(declaration: IrProperty) {
|
||||||
|
if (declaration.isExpect) addLink(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitEnumEntry(declaration: IrEnumEntry) {
|
||||||
|
if ((declaration.parent as IrClass).isExpect) addLink(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
private fun addLink(declaration: IrDeclarationBase) {
|
private fun addLink(declaration: IrDeclarationBase) {
|
||||||
if (!declaration.isExpect) return
|
val actualMember = actualMembers.getMatch(declaration, expectActualMap, typeAliasMap)
|
||||||
val actualMember = actualMembers[generateIrElementFullName(declaration, expectActualMap, typeAliasMap)]
|
|
||||||
if (actualMember != null) {
|
if (actualMember != null) {
|
||||||
expectActualMap[declaration.symbol] = actualMember.symbol
|
expectActualMap[declaration.symbol] = actualMember.symbol
|
||||||
if (declaration is IrProperty) {
|
if (declaration is IrProperty) {
|
||||||
|
|||||||
+8
-4
@@ -20,10 +20,10 @@ object IrActualizer {
|
|||||||
languageVersionSettings: LanguageVersionSettings
|
languageVersionSettings: LanguageVersionSettings
|
||||||
) {
|
) {
|
||||||
val ktDiagnosticReporter = KtDiagnosticReporterWithImplicitIrBasedContext(diagnosticReporter, languageVersionSettings)
|
val ktDiagnosticReporter = KtDiagnosticReporterWithImplicitIrBasedContext(diagnosticReporter, languageVersionSettings)
|
||||||
val (expectActualMap, typeAliasMap) = ExpectActualCollector(mainFragment, dependentFragments, ktDiagnosticReporter).collect()
|
val (expectActualMap, expectActualTypeAliasMap) = ExpectActualCollector(mainFragment, dependentFragments, ktDiagnosticReporter).collect()
|
||||||
FunctionDefaultParametersActualizer(expectActualMap).actualize()
|
FunctionDefaultParametersActualizer(expectActualMap).actualize()
|
||||||
removeExpectDeclarations(dependentFragments, expectActualMap)
|
removeExpectDeclarations(dependentFragments, expectActualMap)
|
||||||
addMissingFakeOverrides(expectActualMap, dependentFragments, typeAliasMap, ktDiagnosticReporter)
|
addMissingFakeOverrides(expectActualMap, dependentFragments, expectActualTypeAliasMap, ktDiagnosticReporter)
|
||||||
linkExpectToActual(expectActualMap, dependentFragments)
|
linkExpectToActual(expectActualMap, dependentFragments)
|
||||||
mergeIrFragments(mainFragment, dependentFragments)
|
mergeIrFragments(mainFragment, dependentFragments)
|
||||||
}
|
}
|
||||||
@@ -48,10 +48,14 @@ object IrActualizer {
|
|||||||
private fun addMissingFakeOverrides(
|
private fun addMissingFakeOverrides(
|
||||||
expectActualMap: Map<IrSymbol, IrSymbol>,
|
expectActualMap: Map<IrSymbol, IrSymbol>,
|
||||||
dependentFragments: List<IrModuleFragment>,
|
dependentFragments: List<IrModuleFragment>,
|
||||||
typeAliasMap: Map<FqName, FqName>,
|
expectActualTypeAliasMap: Map<FqName, FqName>,
|
||||||
diagnosticsReporter: KtDiagnosticReporterWithImplicitIrBasedContext
|
diagnosticsReporter: KtDiagnosticReporterWithImplicitIrBasedContext
|
||||||
) {
|
) {
|
||||||
MissingFakeOverridesAdder(expectActualMap, typeAliasMap, diagnosticsReporter).apply { dependentFragments.forEach { visitModuleFragment(it) } }
|
MissingFakeOverridesAdder(
|
||||||
|
expectActualMap,
|
||||||
|
expectActualTypeAliasMap,
|
||||||
|
diagnosticsReporter
|
||||||
|
).apply { dependentFragments.forEach { visitModuleFragment(it) } }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun linkExpectToActual(expectActualMap: Map<IrSymbol, IrSymbol>, dependentFragments: List<IrModuleFragment>) {
|
private fun linkExpectToActual(expectActualMap: Map<IrSymbol, IrSymbol>, dependentFragments: List<IrModuleFragment>) {
|
||||||
|
|||||||
+77
-29
@@ -12,27 +12,95 @@ import org.jetbrains.kotlin.ir.IrElement
|
|||||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||||
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
||||||
import org.jetbrains.kotlin.ir.util.kotlinFqName
|
import org.jetbrains.kotlin.ir.util.kotlinFqName
|
||||||
import org.jetbrains.kotlin.ir.util.module
|
import org.jetbrains.kotlin.ir.util.module
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
|
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
|
|
||||||
fun generateIrElementFullName(
|
fun Map<String, List<IrDeclaration>>.getMatch(
|
||||||
|
expectDeclaration: IrDeclaration,
|
||||||
|
expectActualTypesMap: Map<IrSymbol, IrSymbol>,
|
||||||
|
expectActualTypeAliasMap: Map<FqName, FqName>
|
||||||
|
): IrDeclaration? {
|
||||||
|
val members = this[generateIrElementFullNameFromExpect(expectDeclaration, expectActualTypeAliasMap)] ?: return null
|
||||||
|
return if (expectDeclaration is IrFunction) {
|
||||||
|
members.firstNotNullOfOrNull { runIf(expectDeclaration.match(it as IrFunction, expectActualTypesMap)) { it } }
|
||||||
|
} else {
|
||||||
|
members.singleOrNull()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrFunction.match(actualFunction: IrFunction, expectActualTypesMap: Map<IrSymbol, IrSymbol>): Boolean {
|
||||||
|
fun checkParameter(
|
||||||
|
expectParameter: IrValueParameter?,
|
||||||
|
actualParameter: IrValueParameter?,
|
||||||
|
typeParametersMap: Map<IrTypeParameterSymbol, IrTypeParameterSymbol>
|
||||||
|
): Boolean {
|
||||||
|
if (expectParameter == null) {
|
||||||
|
return actualParameter == null
|
||||||
|
}
|
||||||
|
if (actualParameter == null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val actualizedParameterTypeSymbol = expectParameter.type.classifierOrFail.let {
|
||||||
|
var mappedSymbol: IrSymbol? = null
|
||||||
|
if (it is IrTypeParameterSymbol) {
|
||||||
|
mappedSymbol = typeParametersMap[it]
|
||||||
|
}
|
||||||
|
if (mappedSymbol == null) {
|
||||||
|
mappedSymbol = expectActualTypesMap[it] ?: it
|
||||||
|
}
|
||||||
|
mappedSymbol
|
||||||
|
}
|
||||||
|
if (actualizedParameterTypeSymbol != actualParameter.type.classifierOrFail) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueParameters.size != actualFunction.valueParameters.size || typeParameters.size != actualFunction.typeParameters.size) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val typeParametersMap = mutableMapOf<IrTypeParameterSymbol, IrTypeParameterSymbol>()
|
||||||
|
for ((expectTypeParameter, actualTypeParameter) in typeParameters.zip(actualFunction.typeParameters)) {
|
||||||
|
if (expectTypeParameter.name != actualTypeParameter.name) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
typeParametersMap[expectTypeParameter.symbol] = actualTypeParameter.symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!checkParameter(extensionReceiverParameter, actualFunction.extensionReceiverParameter, typeParametersMap)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for ((expectParameter, actualParameter) in valueParameters.zip(actualFunction.valueParameters)) {
|
||||||
|
if (!checkParameter(expectParameter, actualParameter, typeParametersMap)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generateActualIrClassOrTypeAliasFullName(declaration: IrElement) = generateIrElementFullNameFromExpect(declaration, emptyMap())
|
||||||
|
|
||||||
|
fun generateIrElementFullNameFromExpect(
|
||||||
declaration: IrElement,
|
declaration: IrElement,
|
||||||
expectActualTypesMap: Map<IrSymbol, IrSymbol>? = null,
|
expectActualTypeAliasMap: Map<FqName, FqName>
|
||||||
typeAliasMap: Map<FqName, FqName>? = null
|
|
||||||
): String {
|
): String {
|
||||||
return StringBuilder().apply { appendElementFullName(declaration, this, expectActualTypesMap, typeAliasMap) }.toString()
|
return StringBuilder().apply { appendElementFullName(declaration, this, expectActualTypeAliasMap) }.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun appendElementFullName(
|
private fun appendElementFullName(
|
||||||
declaration: IrElement,
|
declaration: IrElement,
|
||||||
result: StringBuilder,
|
result: StringBuilder,
|
||||||
expectActualTypesMap: Map<IrSymbol, IrSymbol>? = null,
|
expectActualTypeAliasMap: Map<FqName, FqName>
|
||||||
expectActualTypeAliasMap: Map<FqName, FqName>? = null
|
|
||||||
) {
|
) {
|
||||||
if (declaration !is IrDeclarationBase) return
|
if (declaration !is IrDeclarationBase) return
|
||||||
|
|
||||||
@@ -47,7 +115,7 @@ private fun appendElementFullName(
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val parentString = parent.kotlinFqName.let { (expectActualTypeAliasMap?.get(it) ?: it).asString() }
|
val parentString = parent.kotlinFqName.let { (expectActualTypeAliasMap[it] ?: it).asString() }
|
||||||
if (parentString.isNotEmpty()) {
|
if (parentString.isNotEmpty()) {
|
||||||
parents.add(parentString)
|
parents.add(parentString)
|
||||||
}
|
}
|
||||||
@@ -64,27 +132,7 @@ private fun appendElementFullName(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (declaration is IrFunction) {
|
if (declaration is IrFunction) {
|
||||||
fun appendType(type: IrType) {
|
result.append("()")
|
||||||
val typeClassifier = type.classifierOrFail
|
|
||||||
val actualizedTypeSymbol = expectActualTypesMap?.get(typeClassifier) ?: typeClassifier
|
|
||||||
appendElementFullName(actualizedTypeSymbol.owner, result, expectActualTypesMap)
|
|
||||||
}
|
|
||||||
|
|
||||||
val extensionReceiverType = declaration.extensionReceiverParameter?.type
|
|
||||||
if (extensionReceiverType != null) {
|
|
||||||
result.append('[')
|
|
||||||
appendType(extensionReceiverType)
|
|
||||||
result.append(']')
|
|
||||||
}
|
|
||||||
|
|
||||||
result.append('(')
|
|
||||||
for ((index, parameter) in declaration.valueParameters.withIndex()) {
|
|
||||||
appendType(parameter.type)
|
|
||||||
if (index < declaration.valueParameters.size - 1) {
|
|
||||||
result.append(',')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.append(')')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-8
@@ -39,9 +39,12 @@ class MissingFakeOverridesAdder(
|
|||||||
|
|
||||||
private fun processSupertypes(declaration: IrClass) {
|
private fun processSupertypes(declaration: IrClass) {
|
||||||
val members by lazy(LazyThreadSafetyMode.NONE) {
|
val members by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
declaration.declarations.filter { !it.isBuiltinMember() }.associateBy {
|
val notBuiltinMembers = declaration.declarations.filter { !it.isBuiltinMember() }
|
||||||
generateIrElementFullName(it, expectActualMap, typeAliasMap)
|
val result = mutableMapOf<String, MutableList<IrDeclaration>>()
|
||||||
|
for (member in notBuiltinMembers) {
|
||||||
|
result.getOrPut(generateIrElementFullNameFromExpect(member, typeAliasMap)) { mutableListOf() }.add(member)
|
||||||
}
|
}
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
for (superType in declaration.superTypes) {
|
for (superType in declaration.superTypes) {
|
||||||
@@ -68,15 +71,11 @@ class MissingFakeOverridesAdder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addFakeOverride(
|
private fun addFakeOverride(actualMember: IrDeclaration, members: Map<String, List<IrDeclaration>>, declaration: IrClass) {
|
||||||
actualMember: IrDeclaration,
|
|
||||||
members: Map<String, IrDeclaration>,
|
|
||||||
declaration: IrClass
|
|
||||||
) {
|
|
||||||
when (actualMember) {
|
when (actualMember) {
|
||||||
is IrFunctionImpl,
|
is IrFunctionImpl,
|
||||||
is IrPropertyImpl -> {
|
is IrPropertyImpl -> {
|
||||||
if (members[generateIrElementFullName(actualMember, expectActualMap, typeAliasMap)] != null) {
|
if (members.getMatch(actualMember, expectActualMap, typeAliasMap) != null) {
|
||||||
diagnosticsReporter.reportManyInterfacesMembersNotImplemented(declaration, actualMember as IrDeclarationWithName)
|
diagnosticsReporter.reportManyInterfacesMembersNotImplemented(declaration, actualMember as IrDeclarationWithName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// FILE: common.kt
|
// FILE: common.kt
|
||||||
|
|
||||||
<!NO_ACTUAL_FOR_EXPECT{JVM}!>expect enum class Foo {
|
<!NO_ACTUAL_FOR_EXPECT{JVM}!>expect enum class Foo {
|
||||||
<!NO_ACTUAL_FOR_EXPECT{JVM}!>ENTRY<!>
|
ENTRY
|
||||||
}<!>
|
}<!>
|
||||||
|
|
||||||
expect enum class _TimeUnit
|
expect enum class _TimeUnit
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ expect class Foo {
|
|||||||
|
|
||||||
<!NO_ACTUAL_FOR_EXPECT{JVM}!>fun f2(s: List<String>?): MutableMap<Boolean?, Foo><!>
|
<!NO_ACTUAL_FOR_EXPECT{JVM}!>fun f2(s: List<String>?): MutableMap<Boolean?, Foo><!>
|
||||||
|
|
||||||
<!NO_ACTUAL_FOR_EXPECT{JVM}!>fun <T : Set<Number>> f3(t: T): T?<!>
|
fun <T : Set<Number>> f3(t: T): T?
|
||||||
}
|
}
|
||||||
|
|
||||||
// MODULE: m2-jvm()()(m1-common)
|
// MODULE: m2-jvm()()(m1-common)
|
||||||
|
|||||||
Reference in New Issue
Block a user