From 31424e38acf0af9612332270deff4beaae10cdf1 Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Fri, 21 Apr 2023 15:50:09 +0200 Subject: [PATCH] [FIR] Consider the isExpect value of the receiver class for intersection overrides It's critical for signature calculation in FIR2IR because `isExpect` is a part of signature --- .../FirLightTreeJvmIrTextTestGenerated.java | 6 + .../ir/FirPsiJvmIrTextTestGenerated.java | 6 + .../impl/FirTypeIntersectionScopeContext.kt | 7 +- .../expectIntersectionOverride.ir.txt | 127 ++++++++++++++++++ .../expectIntersectionOverride.kt | 29 ++++ .../expectIntersectionOverride.kt.txt | 44 ++++++ .../ir/ClassicJvmIrTextTestGenerated.java | 6 + .../klib/KlibIrTextTestCaseGenerated.java | 5 + .../FirLightTreeJsIrTextTestGenerated.java | 6 + .../test/fir/FirPsiJsIrTextTestGenerated.java | 6 + .../test/ir/ClassicJsIrTextTestGenerated.java | 6 + 11 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.ir.txt create mode 100644 compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt create mode 100644 compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt.txt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/FirLightTreeJvmIrTextTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/FirLightTreeJvmIrTextTestGenerated.java index ac7e9777fab..95067f1369a 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/FirLightTreeJvmIrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/FirLightTreeJvmIrTextTestGenerated.java @@ -1003,6 +1003,12 @@ public class FirLightTreeJvmIrTextTestGenerated extends AbstractFirLightTreeJvmI runTest("compiler/testData/ir/irText/declarations/multiplatform/expectClassInherited.kt"); } + @Test + @TestMetadata("expectIntersectionOverride.kt") + public void testExpectIntersectionOverride() throws Exception { + runTest("compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt"); + } + @Test @TestMetadata("expectedEnumClass.kt") public void testExpectedEnumClass() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/FirPsiJvmIrTextTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/FirPsiJvmIrTextTestGenerated.java index 6409a3b31b8..7f293bce704 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/FirPsiJvmIrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/FirPsiJvmIrTextTestGenerated.java @@ -1003,6 +1003,12 @@ public class FirPsiJvmIrTextTestGenerated extends AbstractFirPsiJvmIrTextTest { runTest("compiler/testData/ir/irText/declarations/multiplatform/expectClassInherited.kt"); } + @Test + @TestMetadata("expectIntersectionOverride.kt") + public void testExpectIntersectionOverride() throws Exception { + runTest("compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt"); + } + @Test @TestMetadata("expectedEnumClass.kt") public void testExpectedEnumClass() throws Exception { diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScopeContext.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScopeContext.kt index 3e3f02c02b5..c257da18c56 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScopeContext.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScopeContext.kt @@ -39,6 +39,8 @@ class FirTypeIntersectionScopeContext( ) { private val overrideService = session.overrideService + private val isReceiverClassExpect = dispatchReceiverType.toRegularClassSymbol(session)?.isExpect == true + val intersectionOverrides: FirCache, MemberWithBaseScope>, ResultOfIntersection.NonTrivial<*>> = session.intersectionOverrideStorage.cacheByScope.getValue(dispatchReceiverType) @@ -357,7 +359,8 @@ class FirTypeIntersectionScopeContext( val newSymbol = FirIntersectionOverrideFunctionSymbol(callableId, overrides) FirFakeOverrideGenerator.createCopyForFirFunction( newSymbol, keyFir, derivedClassLookupTag = null, session, - FirDeclarationOrigin.IntersectionOverride, keyFir.isExpect, + FirDeclarationOrigin.IntersectionOverride, + isExpect = isReceiverClassExpect || keyFir.isExpect, newModality = newModality, newVisibility = newVisibility, newDispatchReceiverType = dispatchReceiverType, @@ -382,6 +385,7 @@ class FirTypeIntersectionScopeContext( FirFakeOverrideGenerator.createCopyForFirProperty( symbol, fir, derivedClassLookupTag = null, session, FirDeclarationOrigin.IntersectionOverride, + isExpect = isReceiverClassExpect || fir.isExpect, newModality = newModality, newVisibility = newVisibility, newDispatchReceiverType = dispatchReceiverType, @@ -406,6 +410,7 @@ class FirTypeIntersectionScopeContext( FirFakeOverrideGenerator.createCopyForFirField( symbol, fir, derivedClassLookupTag = null, session, FirDeclarationOrigin.IntersectionOverride, + isExpect = isReceiverClassExpect || fir.isExpect, newModality = newModality, newVisibility = newVisibility, newDispatchReceiverType = dispatchReceiverType, diff --git a/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.ir.txt b/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.ir.txt new file mode 100644 index 00000000000..00bebbfca38 --- /dev/null +++ b/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.ir.txt @@ -0,0 +1,127 @@ +Module: +FILE fqName: fileName:/common.kt + CLASS INTERFACE name:I1 modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.I1 + FUN name:f visibility:public modality:ABSTRACT <> ($this:.I1) returnType:kotlin.String + $this: VALUE_PARAMETER name: type:.I1 + PROPERTY name:p visibility:public modality:ABSTRACT [val] + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:ABSTRACT <> ($this:.I1) returnType:kotlin.Int + correspondingProperty: PROPERTY name:p visibility:public modality:ABSTRACT [val] + $this: VALUE_PARAMETER name: type:.I1 + 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 [operator] 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:I2 modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.I2 + FUN name:f visibility:public modality:ABSTRACT <> ($this:.I2) returnType:kotlin.String + $this: VALUE_PARAMETER name: type:.I2 + PROPERTY name:p visibility:public modality:ABSTRACT [val] + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:ABSTRACT <> ($this:.I2) returnType:kotlin.Int + correspondingProperty: PROPERTY name:p visibility:public modality:ABSTRACT [val] + $this: VALUE_PARAMETER name: type:.I2 + 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 [operator] 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 CLASS name:C modality:FINAL visibility:public [expect] superTypes:[.I1; .I2] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.C + CONSTRUCTOR visibility:public <> () returnType:.C [primary,expect] + FUN FAKE_OVERRIDE name:f visibility:public modality:ABSTRACT <> ($this:.I1) returnType:kotlin.String [expect,fake_override] + overridden: + public abstract fun f (): kotlin.String declared in .I1 + public abstract fun f (): kotlin.String declared in .I2 + $this: VALUE_PARAMETER name: type:.I1 + PROPERTY FAKE_OVERRIDE name:p visibility:public modality:ABSTRACT [expect,fake_override,val] + overridden: + public abstract p: kotlin.Int [val] + public abstract p: kotlin.Int [val] + FUN FAKE_OVERRIDE name: visibility:public modality:ABSTRACT <> ($this:.I1) returnType:kotlin.Int [fake_override] + correspondingProperty: PROPERTY FAKE_OVERRIDE name:p visibility:public modality:ABSTRACT [expect,fake_override,val] + overridden: + public abstract fun (): kotlin.Int declared in .I1 + public abstract fun (): kotlin.Int declared in .I2 + $this: VALUE_PARAMETER name: type:.I1 + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [expect,fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in .I1 + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in .I2 + $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 [expect,fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in .I1 + public open fun hashCode (): kotlin.Int [fake_override] declared in .I2 + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [expect,fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in .I1 + public open fun toString (): kotlin.String [fake_override] declared in .I2 + $this: VALUE_PARAMETER name: type:kotlin.Any +Module: platform +FILE fqName: fileName:/platform.kt + CLASS CLASS name:C modality:FINAL visibility:public superTypes:[.I1; .I2] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.C + CONSTRUCTOR visibility:public <> () returnType:.C [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C modality:FINAL visibility:public superTypes:[.I1; .I2]' + FUN name:f visibility:public modality:OPEN <> ($this:.C) returnType:kotlin.String + overridden: + public abstract fun f (): kotlin.String declared in .I1 + public abstract fun f (): kotlin.String declared in .I2 + $this: VALUE_PARAMETER name: type:.C + BLOCK_BODY + RETURN type=kotlin.Nothing from='public open fun f (): kotlin.String declared in .C' + CONST String type=kotlin.String value="OK" + PROPERTY name:p visibility:public modality:OPEN [val] + overridden: + public abstract p: kotlin.Int [val] + public abstract p: kotlin.Int [val] + FIELD PROPERTY_BACKING_FIELD name:p type:kotlin.Int visibility:private [final] + EXPRESSION_BODY + CONST Int type=kotlin.Int value=42 + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:OPEN <> ($this:.C) returnType:kotlin.Int + correspondingProperty: PROPERTY name:p visibility:public modality:OPEN [val] + overridden: + public abstract fun (): kotlin.Int declared in .I1 + public abstract fun (): kotlin.Int declared in .I2 + $this: VALUE_PARAMETER name: type:.C + BLOCK_BODY + RETURN type=kotlin.Nothing from='public open fun (): kotlin.Int declared in .C' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:p type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .C declared in .C.' type=.C origin=null + 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 .I1 + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in .I2 + $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 [fake_override] declared in .I1 + public open fun hashCode (): kotlin.Int [fake_override] declared in .I2 + $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 [fake_override] declared in .I1 + public open fun toString (): kotlin.String [fake_override] declared in .I2 + $this: VALUE_PARAMETER name: type:kotlin.Any diff --git a/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt b/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt new file mode 100644 index 00000000000..8f0734a6660 --- /dev/null +++ b/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt @@ -0,0 +1,29 @@ +// FIR_IDENTICAL +// IGNORE_BACKEND_K1: JVM_IR, JS_IR +// !LANGUAGE: +MultiPlatformProjects + +// MODULE: common +// FILE: common.kt + +interface I1 { + fun f(): String + + val p: Int +} + +interface I2 { + fun f(): String + + val p: Int +} + +expect class C() : I1, I2 + +// MODULE: platform()()(common) +// FILE: platform.kt + +actual class C : I1, I2 { + override fun f() = "OK" + + override val p = 42 +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt.txt b/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt.txt new file mode 100644 index 00000000000..39ce841460a --- /dev/null +++ b/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt.txt @@ -0,0 +1,44 @@ +// MODULE: +// FILE: common.kt + +interface I1 { + abstract fun f(): String + + abstract val p: Int + abstract get + +} + +interface I2 { + abstract fun f(): String + + abstract val p: Int + abstract get + +} + +expect class C : I1, I2 { + expect constructor() /* primary */ + +} + +// MODULE: platform +// FILE: platform.kt + +class C : I1, I2 { + constructor() /* primary */ { + super/*Any*/() + /* () */ + + } + + override fun f(): String { + return "OK" + } + + override val p: Int + field = 42 + override get + +} + diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/ClassicJvmIrTextTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/ClassicJvmIrTextTestGenerated.java index d9e7f1f1f80..9e206e66473 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/ClassicJvmIrTextTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/ClassicJvmIrTextTestGenerated.java @@ -1003,6 +1003,12 @@ public class ClassicJvmIrTextTestGenerated extends AbstractClassicJvmIrTextTest runTest("compiler/testData/ir/irText/declarations/multiplatform/expectClassInherited.kt"); } + @Test + @TestMetadata("expectIntersectionOverride.kt") + public void testExpectIntersectionOverride() throws Exception { + runTest("compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt"); + } + @Test @TestMetadata("expectedEnumClass.kt") public void testExpectedEnumClass() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/klib/KlibIrTextTestCaseGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/klib/KlibIrTextTestCaseGenerated.java index 092dee975e0..32d2c27fbf5 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/klib/KlibIrTextTestCaseGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/klib/KlibIrTextTestCaseGenerated.java @@ -732,6 +732,11 @@ public class KlibIrTextTestCaseGenerated extends AbstractKlibIrTextTestCase { runTest("compiler/testData/ir/irText/declarations/multiplatform/expectClassInherited.kt"); } + @TestMetadata("expectIntersectionOverride.kt") + public void testExpectIntersectionOverride() throws Exception { + runTest("compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt"); + } + @TestMetadata("expectedEnumClass.kt") public void testExpectedEnumClass() throws Exception { runTest("compiler/testData/ir/irText/declarations/multiplatform/expectedEnumClass.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirLightTreeJsIrTextTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirLightTreeJsIrTextTestGenerated.java index 80e2bfc2c5f..c3c781afe50 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirLightTreeJsIrTextTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirLightTreeJsIrTextTestGenerated.java @@ -823,6 +823,12 @@ public class FirLightTreeJsIrTextTestGenerated extends AbstractFirLightTreeJsIrT runTest("compiler/testData/ir/irText/declarations/multiplatform/expectClassInherited.kt"); } + @Test + @TestMetadata("expectIntersectionOverride.kt") + public void testExpectIntersectionOverride() throws Exception { + runTest("compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt"); + } + @Test @TestMetadata("expectedEnumClass.kt") public void testExpectedEnumClass() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirPsiJsIrTextTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirPsiJsIrTextTestGenerated.java index 565d7651b81..df5f80a4075 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirPsiJsIrTextTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirPsiJsIrTextTestGenerated.java @@ -823,6 +823,12 @@ public class FirPsiJsIrTextTestGenerated extends AbstractFirPsiJsIrTextTest { runTest("compiler/testData/ir/irText/declarations/multiplatform/expectClassInherited.kt"); } + @Test + @TestMetadata("expectIntersectionOverride.kt") + public void testExpectIntersectionOverride() throws Exception { + runTest("compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt"); + } + @Test @TestMetadata("expectedEnumClass.kt") public void testExpectedEnumClass() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/ClassicJsIrTextTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/ClassicJsIrTextTestGenerated.java index 3a744f59c81..03bb5572491 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/ClassicJsIrTextTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/ClassicJsIrTextTestGenerated.java @@ -823,6 +823,12 @@ public class ClassicJsIrTextTestGenerated extends AbstractClassicJsIrTextTest { runTest("compiler/testData/ir/irText/declarations/multiplatform/expectClassInherited.kt"); } + @Test + @TestMetadata("expectIntersectionOverride.kt") + public void testExpectIntersectionOverride() throws Exception { + runTest("compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt"); + } + @Test @TestMetadata("expectedEnumClass.kt") public void testExpectedEnumClass() throws Exception {