JVM IR: Generate interface delegations for specialized interface defaults
This commit is contained in:
committed by
Georgy Bronnikov
parent
8746d08dd5
commit
a49ed1eca2
+6
-5
@@ -50,10 +50,10 @@ private class InheritedDefaultMethodsOnClassesLowering(val context: JvmBackendCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun lower(declaration: IrClass) {
|
override fun lower(declaration: IrClass) {
|
||||||
super.visitClass(declaration)
|
if (!declaration.isJvmInterface)
|
||||||
if (declaration.isJvmInterface) return
|
generateInterfaceMethods(declaration)
|
||||||
|
|
||||||
generateInterfaceMethods(declaration)
|
super.visitClass(declaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateInterfaceMethods(irClass: IrClass) {
|
private fun generateInterfaceMethods(irClass: IrClass) {
|
||||||
@@ -80,13 +80,14 @@ private class InheritedDefaultMethodsOnClassesLowering(val context: JvmBackendCo
|
|||||||
if (origin != IrDeclarationOrigin.FAKE_OVERRIDE) return null
|
if (origin != IrDeclarationOrigin.FAKE_OVERRIDE) return null
|
||||||
parent.let { if (it is IrClass && it.isJvmInterface) return null }
|
parent.let { if (it is IrClass && it.isJvmInterface) return null }
|
||||||
|
|
||||||
|
val implementation = resolveFakeOverride() ?: return null
|
||||||
|
|
||||||
// Only generate interface delegation for functions immediately inherited from an interface.
|
// Only generate interface delegation for functions immediately inherited from an interface.
|
||||||
// (Otherwise, delegation will be present in the parent class)
|
// (Otherwise, delegation will be present in the parent class)
|
||||||
if (overriddenSymbols.any { !it.owner.parentAsClass.isInterface && it.owner.modality != Modality.ABSTRACT }) {
|
if (overriddenSymbols.any { !it.owner.parentAsClass.isInterface && it.owner.modality != Modality.ABSTRACT && it.owner.resolveFakeOverride() == implementation }) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
val implementation = resolveFakeOverride() ?: return null
|
|
||||||
if (!implementation.hasInterfaceParent()
|
if (!implementation.hasInterfaceParent()
|
||||||
|| Visibilities.isPrivate(implementation.visibility)
|
|| Visibilities.isPrivate(implementation.visibility)
|
||||||
|| implementation.isDefinitelyNotDefaultImplsMethod()
|
|| implementation.isDefinitelyNotDefaultImplsMethod()
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
|
||||||
|
interface A {
|
||||||
|
val result: Any get() = "Fail"
|
||||||
|
}
|
||||||
|
|
||||||
|
interface B : A {
|
||||||
|
override val result: String get() = "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class AImpl : A
|
||||||
|
|
||||||
|
class BImpl : AImpl(), B
|
||||||
|
|
||||||
|
fun box(): String =
|
||||||
|
(BImpl() as A).result.toString()
|
||||||
+5
@@ -1537,6 +1537,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/bridges/propertyDiamond.kt");
|
runTest("compiler/testData/codegen/box/bridges/propertyDiamond.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("propertyDiamondFakeOverride.kt")
|
||||||
|
public void testPropertyDiamondFakeOverride() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/bridges/propertyDiamondFakeOverride.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("propertyInConstructor.kt")
|
@TestMetadata("propertyInConstructor.kt")
|
||||||
public void testPropertyInConstructor() throws Exception {
|
public void testPropertyInConstructor() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/bridges/propertyInConstructor.kt");
|
runTest("compiler/testData/codegen/box/bridges/propertyInConstructor.kt");
|
||||||
|
|||||||
+5
@@ -1537,6 +1537,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/bridges/propertyDiamond.kt");
|
runTest("compiler/testData/codegen/box/bridges/propertyDiamond.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("propertyDiamondFakeOverride.kt")
|
||||||
|
public void testPropertyDiamondFakeOverride() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/bridges/propertyDiamondFakeOverride.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("propertyInConstructor.kt")
|
@TestMetadata("propertyInConstructor.kt")
|
||||||
public void testPropertyInConstructor() throws Exception {
|
public void testPropertyInConstructor() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/bridges/propertyInConstructor.kt");
|
runTest("compiler/testData/codegen/box/bridges/propertyInConstructor.kt");
|
||||||
|
|||||||
+5
@@ -1517,6 +1517,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/bridges/propertyDiamond.kt");
|
runTest("compiler/testData/codegen/box/bridges/propertyDiamond.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("propertyDiamondFakeOverride.kt")
|
||||||
|
public void testPropertyDiamondFakeOverride() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/bridges/propertyDiamondFakeOverride.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("propertyInConstructor.kt")
|
@TestMetadata("propertyInConstructor.kt")
|
||||||
public void testPropertyInConstructor() throws Exception {
|
public void testPropertyInConstructor() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/bridges/propertyInConstructor.kt");
|
runTest("compiler/testData/codegen/box/bridges/propertyInConstructor.kt");
|
||||||
|
|||||||
+5
@@ -1517,6 +1517,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/bridges/propertyDiamond.kt");
|
runTest("compiler/testData/codegen/box/bridges/propertyDiamond.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("propertyDiamondFakeOverride.kt")
|
||||||
|
public void testPropertyDiamondFakeOverride() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/bridges/propertyDiamondFakeOverride.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("propertyInConstructor.kt")
|
@TestMetadata("propertyInConstructor.kt")
|
||||||
public void testPropertyInConstructor() throws Exception {
|
public void testPropertyInConstructor() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/bridges/propertyInConstructor.kt");
|
runTest("compiler/testData/codegen/box/bridges/propertyInConstructor.kt");
|
||||||
|
|||||||
Generated
+5
@@ -1152,6 +1152,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/bridges/propertyDiamond.kt");
|
runTest("compiler/testData/codegen/box/bridges/propertyDiamond.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("propertyDiamondFakeOverride.kt")
|
||||||
|
public void testPropertyDiamondFakeOverride() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/bridges/propertyDiamondFakeOverride.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("propertyInConstructor.kt")
|
@TestMetadata("propertyInConstructor.kt")
|
||||||
public void testPropertyInConstructor() throws Exception {
|
public void testPropertyInConstructor() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/bridges/propertyInConstructor.kt");
|
runTest("compiler/testData/codegen/box/bridges/propertyInConstructor.kt");
|
||||||
|
|||||||
+5
@@ -1152,6 +1152,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/bridges/propertyDiamond.kt");
|
runTest("compiler/testData/codegen/box/bridges/propertyDiamond.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("propertyDiamondFakeOverride.kt")
|
||||||
|
public void testPropertyDiamondFakeOverride() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/bridges/propertyDiamondFakeOverride.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("propertyInConstructor.kt")
|
@TestMetadata("propertyInConstructor.kt")
|
||||||
public void testPropertyInConstructor() throws Exception {
|
public void testPropertyInConstructor() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/bridges/propertyInConstructor.kt");
|
runTest("compiler/testData/codegen/box/bridges/propertyInConstructor.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user