diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirBlackBoxCodegenBasedTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirBlackBoxCodegenBasedTestGenerated.java index 7e5cda805e0..5bc41bbaa53 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirBlackBoxCodegenBasedTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirBlackBoxCodegenBasedTestGenerated.java @@ -19190,6 +19190,12 @@ public class LLFirBlackBoxCodegenBasedTestGenerated extends AbstractLLFirBlackBo KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fakeOverride"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @Test + @TestMetadata("complexOverriddensInLazyFunctions.kt") + public void testComplexOverriddensInLazyFunctions() throws Exception { + runTest("compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.kt"); + } + @Test @TestMetadata("diamondFunction.kt") public void testDiamondFunction() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirReversedBlackBoxCodegenBasedTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirReversedBlackBoxCodegenBasedTestGenerated.java index 4f96a0737b4..299e80dc2b1 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirReversedBlackBoxCodegenBasedTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirReversedBlackBoxCodegenBasedTestGenerated.java @@ -19190,6 +19190,12 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fakeOverride"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @Test + @TestMetadata("complexOverriddensInLazyFunctions.kt") + public void testComplexOverriddensInLazyFunctions() throws Exception { + runTest("compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.kt"); + } + @Test @TestMetadata("diamondFunction.kt") public void testDiamondFunction() throws Exception { diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt index 8993cadab40..0689873c80e 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt @@ -8,10 +8,7 @@ package org.jetbrains.kotlin.fir.backend.generators import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.declarations.utils.allowsToHaveFakeOverride -import org.jetbrains.kotlin.fir.declarations.utils.isExpect -import org.jetbrains.kotlin.fir.declarations.utils.isLocal -import org.jetbrains.kotlin.fir.declarations.utils.isStatic +import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.resolve.isRealOwnerOf import org.jetbrains.kotlin.fir.resolve.toFirRegularClass @@ -25,6 +22,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirFieldSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.types.coneType +import org.jetbrains.kotlin.fir.types.typeContext import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.* @@ -219,6 +217,46 @@ class FakeOverrideGenerator( baseFunctionSymbols[fakeOverride.symbol] = baseFirSymbolsForFakeOverride } + internal fun computeBaseSymbolsWithContainingClass( + klass: FirClass, + originalFunction: FirNamedFunctionSymbol, + ): List> { + return computeBaseSymbolsWithContainingClass(klass, originalFunction, FirTypeScope::getDirectOverriddenFunctions) + } + + internal fun computeBaseSymbolsWithContainingClass( + klass: FirClass, + originalFunction: FirPropertySymbol, + ): List> { + return computeBaseSymbolsWithContainingClass(klass, originalFunction, FirTypeScope::getDirectOverriddenProperties) + } + + private inline fun > computeBaseSymbolsWithContainingClass( + klass: FirClass, + originalSymbol: S, + directOverridden: FirTypeScope.(S) -> List, + ): List> { + val scope = klass.unsubstitutedScope() + val classLookupTag = klass.symbol.toLookupTag() + val overriddenFirSymbols = computeBaseSymbols(originalSymbol, directOverridden, scope, classLookupTag) + val superTypes = klass.superConeTypes + val typeContext = session.typeContext + return overriddenFirSymbols.flatMap { symbol -> + with(typeContext) { + val symbolDispatchReceiver = symbol.containingClassLookupTag() ?: return@flatMap emptyList() + superTypes.mapNotNull { superType -> + val compatibleType = superType.anySuperTypeConstructor { + it.typeConstructor() == symbolDispatchReceiver + } + if (!compatibleType) { + return@mapNotNull null + } + symbol to superType.lookupTag + } + } + } + } + internal fun calcBaseSymbolsForFakeOverrideProperty( klass: FirClass, fakeOverride: IrProperty, diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt index 99138f06c32..d157ea380cc 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt @@ -169,7 +169,7 @@ class Fir2IrLazyProperty( override var getter: IrSimpleFunction? = Fir2IrLazyPropertyAccessor( components, startOffset, endOffset, - origin =when { + origin = when { origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB -> origin fir.delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR origin == IrDeclarationOrigin.FAKE_OVERRIDE -> origin @@ -214,17 +214,34 @@ class Fir2IrLazyProperty( } override var overriddenSymbols: List by lazyVar(lock) { - if (containingClass == null) return@lazyVar emptyList() + when (configuration.useIrFakeOverrideBuilder) { + true -> computeOverriddenSymbolsForIrFakeOverrideGenerator() + false -> computeOverriddenUsingFir2IrFakeOverrideGenerator() + } + } + + // TODO: drop this function after migration to IR f/o generator will be complete (KT-64202) + private fun computeOverriddenUsingFir2IrFakeOverrideGenerator(): List { + if (containingClass == null) return emptyList() if (isFakeOverride && parent is Fir2IrLazyClass) { fakeOverrideGenerator.calcBaseSymbolsForFakeOverrideProperty( containingClass, this, fir.symbol ) fakeOverrideGenerator.getOverriddenSymbolsForFakeOverride(this)?.let { assert(!it.contains(symbol)) { "Cannot add function $symbol to its own overriddenSymbols" } - return@lazyVar it + return it } } - fir.generateOverriddenPropertySymbols(containingClass) + return fir.generateOverriddenPropertySymbols(containingClass) + } + + private fun computeOverriddenSymbolsForIrFakeOverrideGenerator(): List { + if (containingClass == null || parent !is Fir2IrLazyClass) return emptyList() + val baseFunctionWithDispatchReceiverTag = + fakeOverrideGenerator.computeBaseSymbolsWithContainingClass(containingClass, fir.symbol) + return baseFunctionWithDispatchReceiverTag.map { (symbol, dispatchReceiverLookupTag) -> + declarationStorage.getIrPropertySymbol(symbol, dispatchReceiverLookupTag) as IrPropertySymbol + } } override var metadata: MetadataSource? diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyPropertyAccessor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyPropertyAccessor.kt index 5a0de8dd864..b04684f64ef 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyPropertyAccessor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyPropertyAccessor.kt @@ -113,10 +113,27 @@ class Fir2IrLazyPropertyAccessor( if (firParentClass == null) return@lazyVar emptyList() // If property accessor is created then corresponding property is definitely created too @OptIn(UnsafeDuringIrConstructionAPI::class) - correspondingPropertySymbol!!.owner.overriddenSymbols.mapNotNull { - when (isSetter) { - false -> declarationStorage.findGetterOfProperty(it) - true -> declarationStorage.findSetterOfProperty(it) + val correspondingProperty = correspondingPropertySymbol!!.owner + correspondingProperty.overriddenSymbols.mapNotNull { + /* + * Calculation of overridden symbols for lazy accessor may be called + * 1. during fir2ir transformation + * 2. somewhere in the backend, after fake-overrides were built + * + * In the first case declarationStorage knows about all symbols, so we always can search for accessor symbol in it + * But in the second case property symbols for fake-overrides are replaced with real one (in f/o generator) and + * declarationStorage has no information about it. But at this point all symbols are already bound. So we can + * just access the corresponding accessor using owner of the symbol + */ + when { + it.isBound -> @OptIn(UnsafeDuringIrConstructionAPI::class) when (isSetter) { + false -> it.owner.getter?.symbol + true -> it.owner.setter?.symbol + } + else -> when (isSetter) { + false -> declarationStorage.findGetterOfProperty(it) + true -> declarationStorage.findSetterOfProperty(it) + } } } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt index 9a9542b30a0..c2d22a30d52 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt @@ -30,7 +30,7 @@ class Fir2IrLazySimpleFunction( endOffset: Int, origin: IrDeclarationOrigin, override val fir: FirSimpleFunction, - firParent: FirRegularClass?, + private val firParent: FirRegularClass?, symbol: IrSimpleFunctionSymbol, parent: IrDeclarationParent, isFakeOverride: Boolean @@ -93,17 +93,34 @@ class Fir2IrLazySimpleFunction( } override var overriddenSymbols: List by lazyVar(lock) { - if (firParent == null) return@lazyVar emptyList() + when (configuration.useIrFakeOverrideBuilder) { + true -> computeOverriddenSymbolsForIrFakeOverrideGenerator() + false -> computeOverriddenUsingFir2IrFakeOverrideGenerator() + } + } + + // TODO: drop this function after migration to IR f/o generator will be complete (KT-64202) + private fun computeOverriddenUsingFir2IrFakeOverrideGenerator(): List { + if (firParent == null) return emptyList() if (isFakeOverride && parent is Fir2IrLazyClass) { fakeOverrideGenerator.calcBaseSymbolsForFakeOverrideFunction( firParent, this, fir.symbol ) fakeOverrideGenerator.getOverriddenSymbolsForFakeOverride(this)?.let { assert(!it.contains(symbol)) { "Cannot add function $symbol to its own overriddenSymbols" } - return@lazyVar it + return it } } - fir.generateOverriddenFunctionSymbols(firParent) + return fir.generateOverriddenFunctionSymbols(firParent) + } + + private fun computeOverriddenSymbolsForIrFakeOverrideGenerator(): List { + if (firParent == null || parent !is Fir2IrLazyClass) return emptyList() + val baseFunctionWithDispatchReceiverTag = + fakeOverrideGenerator.computeBaseSymbolsWithContainingClass(firParent, fir.symbol) + return baseFunctionWithDispatchReceiverTag.map { (symbol, dispatchReceiverLookupTag) -> + declarationStorage.getIrFunctionSymbol(symbol, dispatchReceiverLookupTag) as IrSimpleFunctionSymbol + } } override val initialSignatureFunction: IrFunction? by lazy { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java index f9381e98f2b..325fcaa1ac7 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java @@ -19119,6 +19119,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fakeOverride"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("complexOverriddensInLazyFunctions.kt") + public void testComplexOverriddensInLazyFunctions() throws Exception { + runTest("compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.kt"); + } + @Test @TestMetadata("diamondFunction.kt") public void testDiamondFunction() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java index 1a444e1d7d5..766a26d35ba 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java @@ -19119,6 +19119,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fakeOverride"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("complexOverriddensInLazyFunctions.kt") + public void testComplexOverriddensInLazyFunctions() throws Exception { + runTest("compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.kt"); + } + @Test @TestMetadata("diamondFunction.kt") public void testDiamondFunction() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java index a394308effa..91e22e9748b 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java @@ -19119,6 +19119,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fakeOverride"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("complexOverriddensInLazyFunctions.kt") + public void testComplexOverriddensInLazyFunctions() throws Exception { + runTest("compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.kt"); + } + @Test @TestMetadata("diamondFunction.kt") public void testDiamondFunction() throws Exception { diff --git a/compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.__JavaInterface.fir.ir.txt b/compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.__JavaInterface.fir.ir.txt new file mode 100644 index 00000000000..bdf481c432f --- /dev/null +++ b/compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.__JavaInterface.fir.ir.txt @@ -0,0 +1,32 @@ +CLASS IR_EXTERNAL_JAVA_DECLARATION_STUB INTERFACE name:JavaInterface modality:ABSTRACT visibility:public [fun] superTypes:[.B; .C; .D] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.JavaInterface + FUN IR_EXTERNAL_JAVA_DECLARATION_STUB name:foo visibility:public modality:ABSTRACT <> ($this:.JavaInterface) returnType:kotlin.Unit + overridden: + public abstract fun foo (): kotlin.Unit [fake_override] declared in .B + public abstract fun foo (): kotlin.Unit [fake_override] declared in .C + $this: VALUE_PARAMETER IR_EXTERNAL_JAVA_DECLARATION_STUB name: type:.JavaInterface + FUN IR_EXTERNAL_JAVA_DECLARATION_STUB name:bar visibility:public modality:ABSTRACT <> ($this:.JavaInterface) returnType:kotlin.Unit + overridden: + public abstract fun bar (): kotlin.Unit [fake_override] declared in .B + public abstract fun bar (): kotlin.Unit [fake_override] declared in .C + public abstract fun bar (): kotlin.Unit declared in .D + $this: VALUE_PARAMETER IR_EXTERNAL_JAVA_DECLARATION_STUB name: type:.JavaInterface + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in .B + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in .C + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in .D + $this: VALUE_PARAMETER FAKE_OVERRIDE name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in .B + public open fun hashCode (): kotlin.Int [fake_override] declared in .C + public open fun hashCode (): kotlin.Int [fake_override] declared in .D + $this: VALUE_PARAMETER FAKE_OVERRIDE name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in .B + public open fun toString (): kotlin.String [fake_override] declared in .C + public open fun toString (): kotlin.String [fake_override] declared in .D + $this: VALUE_PARAMETER FAKE_OVERRIDE name: type:kotlin.Any diff --git a/compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.__JavaInterface.ir.txt b/compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.__JavaInterface.ir.txt new file mode 100644 index 00000000000..1a12e207cce --- /dev/null +++ b/compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.__JavaInterface.ir.txt @@ -0,0 +1,32 @@ +CLASS IR_EXTERNAL_JAVA_DECLARATION_STUB INTERFACE name:JavaInterface modality:ABSTRACT visibility:public superTypes:[.B; .C; .D] + $this: VALUE_PARAMETER IR_EXTERNAL_JAVA_DECLARATION_STUB name: type:.JavaInterface + FUN IR_EXTERNAL_JAVA_DECLARATION_STUB name:bar visibility:public modality:ABSTRACT <> ($this:.JavaInterface) returnType:kotlin.Unit + overridden: + public abstract fun bar (): kotlin.Unit [fake_override] declared in .B + public abstract fun bar (): kotlin.Unit [fake_override] declared in .C + public abstract fun bar (): kotlin.Unit declared in .D + $this: VALUE_PARAMETER IR_EXTERNAL_JAVA_DECLARATION_STUB name: type:.JavaInterface + FUN IR_EXTERNAL_JAVA_DECLARATION_STUB name:foo visibility:public modality:ABSTRACT <> ($this:.JavaInterface) returnType:kotlin.Unit + overridden: + public abstract fun foo (): kotlin.Unit [fake_override] declared in .B + public abstract fun foo (): kotlin.Unit [fake_override] declared in .C + $this: VALUE_PARAMETER IR_EXTERNAL_JAVA_DECLARATION_STUB name: type:.JavaInterface + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in .B + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in .C + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in .D + $this: VALUE_PARAMETER FAKE_OVERRIDE name: type:kotlin.Any + VALUE_PARAMETER IR_EXTERNAL_DECLARATION_STUB name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in .B + public open fun hashCode (): kotlin.Int [fake_override] declared in .C + public open fun hashCode (): kotlin.Int [fake_override] declared in .D + $this: VALUE_PARAMETER FAKE_OVERRIDE name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in .B + public open fun toString (): kotlin.String [fake_override] declared in .C + public open fun toString (): kotlin.String [fake_override] declared in .D + $this: VALUE_PARAMETER FAKE_OVERRIDE name: type:kotlin.Any diff --git a/compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.fir.ir.txt b/compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.fir.ir.txt new file mode 100644 index 00000000000..84535764b1f --- /dev/null +++ b/compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.fir.ir.txt @@ -0,0 +1,95 @@ +FILE fqName: fileName:/base.kt + CLASS INTERFACE name:A modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.A + FUN name:foo visibility:public modality:ABSTRACT <> ($this:.A) returnType:kotlin.Unit + $this: VALUE_PARAMETER name: type:.A + FUN name:bar visibility:public modality:ABSTRACT <> ($this:.A) returnType:kotlin.Unit + $this: VALUE_PARAMETER name: type:.A + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS INTERFACE name:B modality:ABSTRACT visibility:public superTypes:[.A] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.B + FUN FAKE_OVERRIDE name:foo visibility:public modality:ABSTRACT <> ($this:.A) returnType:kotlin.Unit [fake_override] + overridden: + public abstract fun foo (): kotlin.Unit declared in .A + $this: VALUE_PARAMETER name: type:.A + FUN FAKE_OVERRIDE name:bar visibility:public modality:ABSTRACT <> ($this:.A) returnType:kotlin.Unit [fake_override] + overridden: + public abstract fun bar (): kotlin.Unit declared in .A + $this: VALUE_PARAMETER name: type:.A + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in .A + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in .A + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in .A + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS INTERFACE name:C modality:ABSTRACT visibility:public superTypes:[.A] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.C + FUN FAKE_OVERRIDE name:foo visibility:public modality:ABSTRACT <> ($this:.A) returnType:kotlin.Unit [fake_override] + overridden: + public abstract fun foo (): kotlin.Unit declared in .A + $this: VALUE_PARAMETER name: type:.A + FUN FAKE_OVERRIDE name:bar visibility:public modality:ABSTRACT <> ($this:.A) returnType:kotlin.Unit [fake_override] + overridden: + public abstract fun bar (): kotlin.Unit declared in .A + $this: VALUE_PARAMETER name: type:.A + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in .A + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in .A + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in .A + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS INTERFACE name:D modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.D + FUN name:bar visibility:public modality:ABSTRACT <> ($this:.D) returnType:kotlin.Unit + $this: VALUE_PARAMETER name: type:.D + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any +FILE fqName: fileName:/main.kt + FUN name:test visibility:public modality:FINAL <> (x:.JavaInterface) returnType:kotlin.Unit + VALUE_PARAMETER name:x index:0 type:.JavaInterface + BLOCK_BODY + CALL 'public abstract fun foo (): kotlin.Unit declared in .JavaInterface' type=kotlin.Unit origin=null + $this: GET_VAR 'x: .JavaInterface declared in .test' type=.JavaInterface origin=null + CALL 'public abstract fun bar (): kotlin.Unit declared in .JavaInterface' type=kotlin.Unit origin=null + $this: GET_VAR 'x: .JavaInterface declared in .test' type=.JavaInterface origin=null + FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CONST String type=kotlin.String value="OK" diff --git a/compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.ir.txt b/compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.ir.txt new file mode 100644 index 00000000000..84535764b1f --- /dev/null +++ b/compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.ir.txt @@ -0,0 +1,95 @@ +FILE fqName: fileName:/base.kt + CLASS INTERFACE name:A modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.A + FUN name:foo visibility:public modality:ABSTRACT <> ($this:.A) returnType:kotlin.Unit + $this: VALUE_PARAMETER name: type:.A + FUN name:bar visibility:public modality:ABSTRACT <> ($this:.A) returnType:kotlin.Unit + $this: VALUE_PARAMETER name: type:.A + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS INTERFACE name:B modality:ABSTRACT visibility:public superTypes:[.A] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.B + FUN FAKE_OVERRIDE name:foo visibility:public modality:ABSTRACT <> ($this:.A) returnType:kotlin.Unit [fake_override] + overridden: + public abstract fun foo (): kotlin.Unit declared in .A + $this: VALUE_PARAMETER name: type:.A + FUN FAKE_OVERRIDE name:bar visibility:public modality:ABSTRACT <> ($this:.A) returnType:kotlin.Unit [fake_override] + overridden: + public abstract fun bar (): kotlin.Unit declared in .A + $this: VALUE_PARAMETER name: type:.A + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in .A + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in .A + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in .A + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS INTERFACE name:C modality:ABSTRACT visibility:public superTypes:[.A] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.C + FUN FAKE_OVERRIDE name:foo visibility:public modality:ABSTRACT <> ($this:.A) returnType:kotlin.Unit [fake_override] + overridden: + public abstract fun foo (): kotlin.Unit declared in .A + $this: VALUE_PARAMETER name: type:.A + FUN FAKE_OVERRIDE name:bar visibility:public modality:ABSTRACT <> ($this:.A) returnType:kotlin.Unit [fake_override] + overridden: + public abstract fun bar (): kotlin.Unit declared in .A + $this: VALUE_PARAMETER name: type:.A + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in .A + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in .A + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in .A + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS INTERFACE name:D modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.D + FUN name:bar visibility:public modality:ABSTRACT <> ($this:.D) returnType:kotlin.Unit + $this: VALUE_PARAMETER name: type:.D + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any +FILE fqName: fileName:/main.kt + FUN name:test visibility:public modality:FINAL <> (x:.JavaInterface) returnType:kotlin.Unit + VALUE_PARAMETER name:x index:0 type:.JavaInterface + BLOCK_BODY + CALL 'public abstract fun foo (): kotlin.Unit declared in .JavaInterface' type=kotlin.Unit origin=null + $this: GET_VAR 'x: .JavaInterface declared in .test' type=.JavaInterface origin=null + CALL 'public abstract fun bar (): kotlin.Unit declared in .JavaInterface' type=kotlin.Unit origin=null + $this: GET_VAR 'x: .JavaInterface declared in .test' type=.JavaInterface origin=null + FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CONST String type=kotlin.String value="OK" diff --git a/compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.kt b/compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.kt new file mode 100644 index 00000000000..2dcd975f0c9 --- /dev/null +++ b/compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.kt @@ -0,0 +1,33 @@ +// TARGET_BACKEND: JVM_IR +// DUMP_IR +// DUMP_EXTERNAL_CLASS: JavaInterface + +// FILE: base.kt +interface A { + fun foo() + fun bar() +} + +interface B : A + +interface C : A + +interface D { + fun bar() +} + +// FILE: JavaInterface.java + +public interface JavaInterface extends B, C, D { + public void foo(); + public void bar(); +} + +// FILE: main.kt + +fun test(x: JavaInterface) { + x.foo() + x.bar() +} + +fun box(): String = "OK" diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index cbed6067e6e..b193ee98391 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -19119,6 +19119,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fakeOverride"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("complexOverriddensInLazyFunctions.kt") + public void testComplexOverriddensInLazyFunctions() throws Exception { + runTest("compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.kt"); + } + @Test @TestMetadata("diamondFunction.kt") public void testDiamondFunction() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java index 52433c303b8..e3192e1b352 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java @@ -19119,6 +19119,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fakeOverride"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("complexOverriddensInLazyFunctions.kt") + public void testComplexOverriddensInLazyFunctions() throws Exception { + runTest("compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.kt"); + } + @Test @TestMetadata("diamondFunction.kt") public void testDiamondFunction() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 7ddc87fc164..dab7db64486 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -15901,6 +15901,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fakeOverride"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @TestMetadata("complexOverriddensInLazyFunctions.kt") + public void testComplexOverriddensInLazyFunctions() throws Exception { + runTest("compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.kt"); + } + @TestMetadata("diamondFunction.kt") public void testDiamondFunction() throws Exception { runTest("compiler/testData/codegen/box/fakeOverride/diamondFunction.kt");