Fix translation of interface with non-abstract methods in JS BE
Fix additional case of generic interfaces in KT-18187
This commit is contained in:
+1
-1
@@ -20,7 +20,7 @@ fun box(): String {
|
||||
if (bar1 != "bar:default") return "fail2: $bar1"
|
||||
|
||||
val bar2 = A().bar("q")
|
||||
if (bar2 != "bar:q") return "fail3: $bar1"
|
||||
if (bar2 != "bar:q") return "fail3: $bar2"
|
||||
|
||||
val foo2 = B().foo()
|
||||
if (foo2 != "foo") return "fail4: $foo2"
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
interface I<T> {
|
||||
fun foo(x: T): String = "foo($x)"
|
||||
|
||||
fun bar(x: T, y: String = "default") = "bar($x,$y)"
|
||||
}
|
||||
|
||||
interface J : I<String>
|
||||
|
||||
class A : I<String>, J
|
||||
|
||||
class B : J, I<String>
|
||||
|
||||
fun box(): String {
|
||||
val foo = A().foo("q")
|
||||
if (foo != "foo(q)") return "fail1: $foo"
|
||||
|
||||
val bar1 = A().bar("w")
|
||||
if (bar1 != "bar(w,default)") return "fail2: $bar1"
|
||||
|
||||
val bar2 = A().bar("e", "r")
|
||||
if (bar2 != "bar(e,r)") return "fail3: $bar2"
|
||||
|
||||
val foo2 = B().foo("t")
|
||||
if (foo2 != "foo(t)") return "fail4: $foo2"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+6
@@ -18056,6 +18056,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("interfaceWithNonAbstractFunIndirectGeneric.kt")
|
||||
public void testInterfaceWithNonAbstractFunIndirectGeneric() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/traits/interfaceWithNonAbstractFunIndirectGeneric.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt1936.kt")
|
||||
public void testKt1936() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/traits/kt1936.kt");
|
||||
|
||||
@@ -18056,6 +18056,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("interfaceWithNonAbstractFunIndirectGeneric.kt")
|
||||
public void testInterfaceWithNonAbstractFunIndirectGeneric() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/traits/interfaceWithNonAbstractFunIndirectGeneric.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt1936.kt")
|
||||
public void testKt1936() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/traits/kt1936.kt");
|
||||
|
||||
@@ -18056,6 +18056,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("interfaceWithNonAbstractFunIndirectGeneric.kt")
|
||||
public void testInterfaceWithNonAbstractFunIndirectGeneric() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/traits/interfaceWithNonAbstractFunIndirectGeneric.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt1936.kt")
|
||||
public void testKt1936() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/traits/kt1936.kt");
|
||||
|
||||
@@ -22160,6 +22160,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("interfaceWithNonAbstractFunIndirectGeneric.kt")
|
||||
public void testInterfaceWithNonAbstractFunIndirectGeneric() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/traits/interfaceWithNonAbstractFunIndirectGeneric.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt1936.kt")
|
||||
public void testKt1936() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/traits/kt1936.kt");
|
||||
|
||||
+8
-6
@@ -156,7 +156,7 @@ class ClassModelGenerator(val context: StaticContext) {
|
||||
// If one of overridden members is non-abstract, copy it.
|
||||
// When none found, we have nothing to copy, ignore.
|
||||
// When multiple found, our current class should provide implementation, ignore.
|
||||
val memberToCopy = member.findNonRepeatingOverriddenDescriptors { overriddenDescriptors }
|
||||
val memberToCopy = member.findNonRepeatingOverriddenDescriptors({ overriddenDescriptors }, { original })
|
||||
.filter { it.modality != Modality.ABSTRACT }
|
||||
.singleOrNull() ?: return null
|
||||
|
||||
@@ -171,7 +171,7 @@ class ClassModelGenerator(val context: StaticContext) {
|
||||
// If one of overridden members has parameters with default value, copy it.
|
||||
// When non found, we have nothing to copy, ignore.
|
||||
// When multiple found, our current class should provide implementation, ignore.
|
||||
val memberToCopy = member.findNonRepeatingOverriddenDescriptors { overriddenDescriptors }
|
||||
val memberToCopy = member.findNonRepeatingOverriddenDescriptors({ overriddenDescriptors }, { original })
|
||||
.filter { it.hasOrInheritsParametersWithDefaultValue() }
|
||||
.singleOrNull() ?: return null
|
||||
|
||||
@@ -183,20 +183,22 @@ class ClassModelGenerator(val context: StaticContext) {
|
||||
}
|
||||
|
||||
private fun <T : CallableMemberDescriptor> T.findNonRepeatingOverriddenDescriptors(
|
||||
getTypedOverriddenDescriptors: T.() -> Collection<T>
|
||||
getTypedOverriddenDescriptors: T.() -> Collection<T>,
|
||||
getOriginalDescriptor: T.() -> T
|
||||
): List<T> {
|
||||
val allDescriptors = mutableSetOf<T>()
|
||||
val repeatedDescriptors = mutableSetOf<T>()
|
||||
fun walk(descriptor: T) {
|
||||
if (!allDescriptors.add(descriptor)) return
|
||||
val overridden = descriptor.getTypedOverriddenDescriptors()
|
||||
val original = descriptor.getOriginalDescriptor()
|
||||
if (!allDescriptors.add(original)) return
|
||||
val overridden = original.getTypedOverriddenDescriptors().map { it.getOriginalDescriptor() }
|
||||
repeatedDescriptors += overridden
|
||||
overridden.forEach { walk(it) }
|
||||
}
|
||||
|
||||
val directOverriddenDescriptors = getTypedOverriddenDescriptors()
|
||||
directOverriddenDescriptors.forEach { walk(it) }
|
||||
return directOverriddenDescriptors.filter { it !in repeatedDescriptors }
|
||||
return directOverriddenDescriptors.filter { it.getOriginalDescriptor() !in repeatedDescriptors }
|
||||
}
|
||||
|
||||
private fun generateBridgeMethods(descriptor: ClassDescriptor, model: JsClassModel) {
|
||||
|
||||
Reference in New Issue
Block a user