[K2, MPP] Handle overloaded properties

^KT-57532 Fixed
This commit is contained in:
Ivan Kochurkin
2023-03-23 19:46:40 +01:00
committed by Space Team
parent 43dd8571d3
commit 9a09565cf6
4 changed files with 56 additions and 19 deletions
@@ -163,16 +163,23 @@ private class MemberLinksCollector(
}
private fun addLink(declaration: IrDeclarationBase) {
val actualMember = actualMembers.getMatch(declaration, expectActualMap, typeAliasMap)
if (actualMember != null) {
expectActualMap[declaration.symbol] = actualMember.symbol
if (declaration is IrProperty) {
val actualProperty = actualMember as IrProperty
declaration.getter?.symbol?.let { expectActualMap[it] = actualProperty.getter!!.symbol }
declaration.setter?.symbol?.let { expectActualMap[it] = actualProperty.setter!!.symbol }
val actualMemberMatches = actualMembers.getMatches(declaration, expectActualMap, typeAliasMap)
when {
actualMemberMatches.size == 1 -> {
val actualMember = actualMemberMatches.single()
expectActualMap[declaration.symbol] = actualMember.symbol
if (declaration is IrProperty) {
val actualProperty = actualMember as IrProperty
declaration.getter!!.symbol.let { expectActualMap[it] = actualProperty.getter!!.symbol }
declaration.setter?.symbol?.let { expectActualMap[it] = actualProperty.setter!!.symbol }
}
}
actualMemberMatches.size > 1 -> {
// TODO: report AMBIGUOUS_ACTUALS here, see KT-57932
}
!declaration.parent.containsOptionalExpectation() && !(declaration is IrConstructor && declaration.isPrimary) -> {
diagnosticsReporter.reportMissingActual(declaration)
}
} else if (!declaration.parent.containsOptionalExpectation() && !(declaration is IrConstructor && declaration.isPrimary)) {
diagnosticsReporter.reportMissingActual(declaration)
}
}
@@ -20,21 +20,29 @@ import org.jetbrains.kotlin.ir.util.kotlinFqName
import org.jetbrains.kotlin.ir.util.module
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
import org.jetbrains.kotlin.utils.addToStdlib.runIf
fun Map<String, List<IrDeclaration>>.getMatch(
internal fun Map<String, List<IrDeclaration>>.getMatches(
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()
): List<IrDeclaration> {
val members = this[generateIrElementFullNameFromExpect(expectDeclaration, expectActualTypeAliasMap)] ?: return emptyList()
return when (expectDeclaration) {
is IrFunction -> members.getMatches(expectDeclaration, expectActualTypesMap) { it as IrFunction }
is IrProperty -> members.getMatches(expectDeclaration, expectActualTypesMap) { (it as IrProperty).getter!! }
else -> members
}
}
private inline fun List<IrDeclaration>.getMatches(
expect: IrDeclaration,
expectActualTypesMap: Map<IrSymbol, IrSymbol>,
functionExtractor: (IrDeclaration) -> IrFunction
): List<IrDeclaration> {
val expectFunction = functionExtractor(expect)
return filter { expectFunction.match(functionExtractor(it), expectActualTypesMap) }
}
private fun IrFunction.match(actualFunction: IrFunction, expectActualTypesMap: Map<IrSymbol, IrSymbol>): Boolean {
fun getActualizedValueParameterSymbol(
expectParameter: IrValueParameter,
@@ -83,7 +83,7 @@ class MissingFakeOverridesAdder(
else -> return
}
if (members.getMatch(newMember, expectActualMap, typeAliasMap) == null) {
if (members.getMatches(newMember, expectActualMap, typeAliasMap).isEmpty()) {
declaration.declarations.add(newMember)
members.getOrPut(generateIrElementFullNameFromExpect(newMember, typeAliasMap)) { mutableListOf() }.add(newMember)
} else {
@@ -11,8 +11,18 @@ expect fun foo(s: S): S
expect fun foo(i: Int): Int
expect val Int.k: Int
expect val String.k: String
expect var Int.l: Int
expect var String.l: String
fun test(s: S) = foo(s)
fun k() = "K".k + "".l
// MODULE: platform()()(common)
// FILE: platform.kt
@@ -20,6 +30,18 @@ actual fun foo(i: Int) = i
actual fun foo(s: String) = s
actual val Int.k: Int get() = 42
actual val String.k: String get() = this
actual var Int.l: Int
get() = 48
set(value) {}
actual var String.l: String
get() = this
set(value) {}
actual typealias S = String
fun box() = test("OK")
fun box() = test("O") + k()