From 97cf62e2910d4c60371897b40547026f17aa13ca Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 6 Dec 2023 12:10:48 +0200 Subject: [PATCH] [FIR2IR] Properly calculate overridden symbols for lazy declarations This change affects only mode with IR f/o generator The old way of overridden computation with fir2ir f/o generator relied on the fact that fir2ir generator creates IR for all f/o and fills its caches. But with IR f/o generator enabled, we don't call fir2ir generator, so some caches are missing. And for this mode it's enough to acquire the symbol using the original declaration symbol and the lookup tag of the corresponding supertype Relates to KT-64202 --- ...LFirBlackBoxCodegenBasedTestGenerated.java | 6 ++ ...rsedBlackBoxCodegenBasedTestGenerated.java | 6 ++ .../generators/FakeOverrideGenerator.kt | 46 ++++++++- .../kotlin/fir/lazy/Fir2IrLazyProperty.kt | 25 ++++- .../fir/lazy/Fir2IrLazyPropertyAccessor.kt | 25 ++++- .../fir/lazy/Fir2IrLazySimpleFunction.kt | 25 ++++- ...LightTreeBlackBoxCodegenTestGenerated.java | 6 ++ ...hIrFakeOverrideGeneratorTestGenerated.java | 6 ++ .../FirPsiBlackBoxCodegenTestGenerated.java | 6 ++ ...InLazyFunctions.__JavaInterface.fir.ir.txt | 32 +++++++ ...densInLazyFunctions.__JavaInterface.ir.txt | 32 +++++++ ...mplexOverriddensInLazyFunctions.fir.ir.txt | 95 +++++++++++++++++++ .../complexOverriddensInLazyFunctions.ir.txt | 95 +++++++++++++++++++ .../complexOverriddensInLazyFunctions.kt | 33 +++++++ .../IrBlackBoxCodegenTestGenerated.java | 6 ++ ...kBoxCodegenWithIrInlinerTestGenerated.java | 6 ++ .../LightAnalysisModeTestGenerated.java | 5 + 17 files changed, 439 insertions(+), 16 deletions(-) create mode 100644 compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.__JavaInterface.fir.ir.txt create mode 100644 compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.__JavaInterface.ir.txt create mode 100644 compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.fir.ir.txt create mode 100644 compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.ir.txt create mode 100644 compiler/testData/codegen/box/fakeOverride/complexOverriddensInLazyFunctions.kt 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");