From c80cfb0fdb00323ba9b5e1dd98c5cbd0bfab6b8b Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Thu, 13 Jan 2022 18:22:42 +0300 Subject: [PATCH] [FIR] Replace single supertype scope with list of scopes of supertypes in use site scopes This big refactoring is needed to cleanup building of overrides mappings and prevent creating redundant intersection overrides in cases when there is no need in them: ```kotlin interface A { fun foo() } interface B { fun foo() } interface C : A, B { override fun foo() } ``` Before this refactoring there was next override tree: C.foo intersection override (A.foo, B.foo) A.foo B.foo Also this commit fixes special mapping of overrides in jvm scopes for declarations which have kotlin builtins in supertypes with special java mapping rules (collections, for example) --- ...nosisCompilerFirTestdataTestGenerated.java | 94 +++ ...TouchedTilContractsPhaseTestGenerated.java | 83 +++ .../explicitOverrideOfTwoMembers.fir.txt | 22 + .../scopes/explicitOverrideOfTwoMembers.kt | 16 + ...explicitOverrideOfTwoMembers.overrides.txt | 8 + .../explicitOverrideOfTwoMembers_java.fir.txt | 26 + .../explicitOverrideOfTwoMembers_java.kt | 42 ++ ...citOverrideOfTwoMembers_java.overrides.txt | 21 + .../getterOverrideAndKotlinProperty.fir.txt | 24 + .../scopes/getterOverrideAndKotlinProperty.kt | 22 + ...terOverrideAndKotlinProperty.overrides.txt | 15 + .../intersectionOverrideOfTwoMembers.fir.txt | 24 + .../intersectionOverrideOfTwoMembers.kt | 18 + ...rsectionOverrideOfTwoMembers.overrides.txt | 18 + ...ersectionOverrideOfTwoMembers_java.fir.txt | 24 + .../intersectionOverrideOfTwoMembers_java.kt | 18 + ...ionOverrideOfTwoMembers_java.overrides.txt | 17 + ...linPropertyFromDifferentSupertypes.fir.txt | 13 + ...ndKotlinPropertyFromDifferentSupertypes.kt | 18 + ...pertyFromDifferentSupertypes.overrides.txt | 4 + ...cessorsLikeFunctionsThrowJavaClass.fir.txt | 24 + ...linAccessorsLikeFunctionsThrowJavaClass.kt | 23 + ...noIntersectionOverrideOfTwoMembers.fir.txt | 33 + .../noIntersectionOverrideOfTwoMembers.kt | 25 + ...rsectionOverrideOfTwoMembers.overrides.txt | 26 + ...ersectionOverrideOfTwoMembers_java.fir.txt | 33 + ...noIntersectionOverrideOfTwoMembers_java.kt | 25 + ...ionOverrideOfTwoMembers_java.overrides.txt | 25 + .../publicJavaAndPrivateKotlinVar.fir.txt | 23 + .../scopes/publicJavaAndPrivateKotlinVar.kt | 25 + ...ublicJavaAndPrivateKotlinVar.overrides.txt | 14 + .../scopes/specialFunctionInJava_1.fir.txt | 0 .../resolve/scopes/specialFunctionInJava_1.kt | 41 ++ .../specialFunctionInJava_1.overrides.txt | 18 + .../scopes/specialFunctionInJava_2.fir.txt | 11 + .../resolve/scopes/specialFunctionInJava_2.kt | 42 ++ .../specialFunctionInJava_2.overrides.txt | 39 + .../scopes/specialFunctionInJava_3.fir.txt | 23 + .../resolve/scopes/specialFunctionInJava_3.kt | 28 + .../specialFunctionInJava_3.overrides.txt | 8 + .../scopes/specialFunctionInJava_4.fir.txt | 1 + .../resolve/scopes/specialFunctionInJava_4.kt | 28 + .../specialFunctionInJava_4.overrides.txt | 10 + .../runners/FirDiagnosticTestGenerated.java | 94 +++ ...DiagnosticsWithLightTreeTestGenerated.java | 94 +++ .../FirNotImplementedOverrideChecker.kt | 26 +- .../declaration/FirOverrideChecker.kt | 9 +- .../kotlin/fir/java/JavaScopeProvider.kt | 16 +- .../JavaClassMembersEnhancementScope.kt | 81 +-- .../scopes/JavaClassStaticUseSiteScope.kt | 2 +- .../scopes/JavaClassUseSiteMemberScope.kt | 670 +++++++++++------- .../fir/java/scopes/JavaOverrideChecker.kt | 4 +- .../kotlin/fir/java/scopes/JavaScopeUtils.kt | 187 +++++ .../fir/scopes/FirKotlinScopeProvider.kt | 7 +- .../kotlin/fir/scopes/FirOverrideChecker.kt | 6 + .../scopes/impl/AbstractFirOverrideScope.kt | 7 + .../impl/AbstractFirUseSiteMemberScope.kt | 186 +++-- .../scopes/impl/FirClassUseSiteMemberScope.kt | 95 ++- .../fir/scopes/impl/FirOverrideUtils.kt | 63 ++ .../scopes/impl/FirTypeIntersectionScope.kt | 12 +- .../impl/FirTypeIntersectionScopeContext.kt | 161 +++-- .../kotlin/fir/resolve/ResolveUtils.kt | 1 + .../fir/declarations/FirDeclarationOrigin.kt | 1 + .../jetbrains/kotlin/fir/scopes/FirScope.kt | 12 +- .../kotlin/fir/scopes/FirTypeScope.kt | 113 ++- .../collections/irrelevantImplCharSequence.kt | 2 - .../irrelevantImplMutableListSubstitution.kt | 2 +- .../collectionStringImpl.fir.kt | 85 --- .../collectionStringImpl.kt | 1 + .../containsAndOverload.fir.kt | 8 +- .../irrelevantImplCharSequence.fir.kt | 25 - .../irrelevantImplCharSequence.kt | 1 + .../override/FakeOverrideModality3.fir.kt | 16 + .../tests/override/FakeOverrideModality3.kt | 1 - .../diagnostics/tests/scopes/kt1822.fir.kt | 2 +- .../jvmDefault/javaOverride.fir.kt | 72 ++ .../annotations/jvmDefault/javaOverride.kt | 1 - .../ir/irText/classes/kt45853.fir.ir.txt | 61 ++ .../testData/ir/irText/classes/kt45853.kt | 3 - ...elegationAndInheritanceFromJava.fir.ir.txt | 12 + .../ImplicitReceiverStack.fir.ir.txt | 1 + .../irText/firProblems/MultiList.fir.ir.txt | 8 +- 82 files changed, 2564 insertions(+), 636 deletions(-) create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.overrides.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers_java.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers_java.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers_java.overrides.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/getterOverrideAndKotlinProperty.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/getterOverrideAndKotlinProperty.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/getterOverrideAndKotlinProperty.overrides.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers.overrides.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers_java.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers_java.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers_java.overrides.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/javaFunctionAndKotlinPropertyFromDifferentSupertypes.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/javaFunctionAndKotlinPropertyFromDifferentSupertypes.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/javaFunctionAndKotlinPropertyFromDifferentSupertypes.overrides.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/kotlinAccessorsLikeFunctionsThrowJavaClass.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/kotlinAccessorsLikeFunctionsThrowJavaClass.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers.overrides.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers_java.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers_java.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers_java.overrides.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.overrides.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_1.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_1.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_1.overrides.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_2.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_2.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_2.overrides.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_3.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_3.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_3.overrides.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_4.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_4.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_4.overrides.txt create mode 100644 compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaScopeUtils.kt create mode 100644 compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirOverrideUtils.kt delete mode 100644 compiler/testData/diagnostics/tests/j+k/collectionOverrides/collectionStringImpl.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequence.fir.kt create mode 100644 compiler/testData/diagnostics/tests/override/FakeOverrideModality3.fir.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/javaOverride.fir.kt create mode 100644 compiler/testData/ir/irText/classes/kt45853.fir.ir.txt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java index a584654657a..74503b4c921 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java @@ -3482,6 +3482,100 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis } } + @Nested + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/scopes") + @TestDataPath("$PROJECT_ROOT") + public class Scopes { + @Test + public void testAllFilesPresentInScopes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("explicitOverrideOfTwoMembers.kt") + public void testExplicitOverrideOfTwoMembers() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.kt"); + } + + @Test + @TestMetadata("explicitOverrideOfTwoMembers_java.kt") + public void testExplicitOverrideOfTwoMembers_java() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers_java.kt"); + } + + @Test + @TestMetadata("getterOverrideAndKotlinProperty.kt") + public void testGetterOverrideAndKotlinProperty() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/getterOverrideAndKotlinProperty.kt"); + } + + @Test + @TestMetadata("intersectionOverrideOfTwoMembers.kt") + public void testIntersectionOverrideOfTwoMembers() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers.kt"); + } + + @Test + @TestMetadata("intersectionOverrideOfTwoMembers_java.kt") + public void testIntersectionOverrideOfTwoMembers_java() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers_java.kt"); + } + + @Test + @TestMetadata("javaFunctionAndKotlinPropertyFromDifferentSupertypes.kt") + public void testJavaFunctionAndKotlinPropertyFromDifferentSupertypes() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/javaFunctionAndKotlinPropertyFromDifferentSupertypes.kt"); + } + + @Test + @TestMetadata("kotlinAccessorsLikeFunctionsThrowJavaClass.kt") + public void testKotlinAccessorsLikeFunctionsThrowJavaClass() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/kotlinAccessorsLikeFunctionsThrowJavaClass.kt"); + } + + @Test + @TestMetadata("noIntersectionOverrideOfTwoMembers.kt") + public void testNoIntersectionOverrideOfTwoMembers() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers.kt"); + } + + @Test + @TestMetadata("noIntersectionOverrideOfTwoMembers_java.kt") + public void testNoIntersectionOverrideOfTwoMembers_java() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers_java.kt"); + } + + @Test + @TestMetadata("publicJavaAndPrivateKotlinVar.kt") + public void testPublicJavaAndPrivateKotlinVar() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.kt"); + } + + @Test + @TestMetadata("specialFunctionInJava_1.kt") + public void testSpecialFunctionInJava_1() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_1.kt"); + } + + @Test + @TestMetadata("specialFunctionInJava_2.kt") + public void testSpecialFunctionInJava_2() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_2.kt"); + } + + @Test + @TestMetadata("specialFunctionInJava_3.kt") + public void testSpecialFunctionInJava_3() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_3.kt"); + } + + @Test + @TestMetadata("specialFunctionInJava_4.kt") + public void testSpecialFunctionInJava_4() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_4.kt"); + } + } + @Nested @TestMetadata("compiler/fir/analysis-tests/testData/resolve/smartcasts") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java index 5dfe3a3c695..6b51bb914fa 100644 --- a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java +++ b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java @@ -3077,6 +3077,89 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract } } + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/scopes") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Scopes extends AbstractLazyBodyIsNotTouchedTilContractsPhaseTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInScopes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @TestMetadata("explicitOverrideOfTwoMembers.kt") + public void testExplicitOverrideOfTwoMembers() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.kt"); + } + + @TestMetadata("explicitOverrideOfTwoMembers_java.kt") + public void testExplicitOverrideOfTwoMembers_java() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers_java.kt"); + } + + @TestMetadata("getterOverrideAndKotlinProperty.kt") + public void testGetterOverrideAndKotlinProperty() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/getterOverrideAndKotlinProperty.kt"); + } + + @TestMetadata("intersectionOverrideOfTwoMembers.kt") + public void testIntersectionOverrideOfTwoMembers() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers.kt"); + } + + @TestMetadata("intersectionOverrideOfTwoMembers_java.kt") + public void testIntersectionOverrideOfTwoMembers_java() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers_java.kt"); + } + + @TestMetadata("javaFunctionAndKotlinPropertyFromDifferentSupertypes.kt") + public void testJavaFunctionAndKotlinPropertyFromDifferentSupertypes() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/javaFunctionAndKotlinPropertyFromDifferentSupertypes.kt"); + } + + @TestMetadata("kotlinAccessorsLikeFunctionsThrowJavaClass.kt") + public void testKotlinAccessorsLikeFunctionsThrowJavaClass() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/kotlinAccessorsLikeFunctionsThrowJavaClass.kt"); + } + + @TestMetadata("noIntersectionOverrideOfTwoMembers.kt") + public void testNoIntersectionOverrideOfTwoMembers() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers.kt"); + } + + @TestMetadata("noIntersectionOverrideOfTwoMembers_java.kt") + public void testNoIntersectionOverrideOfTwoMembers_java() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers_java.kt"); + } + + @TestMetadata("publicJavaAndPrivateKotlinVar.kt") + public void testPublicJavaAndPrivateKotlinVar() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.kt"); + } + + @TestMetadata("specialFunctionInJava_1.kt") + public void testSpecialFunctionInJava_1() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_1.kt"); + } + + @TestMetadata("specialFunctionInJava_2.kt") + public void testSpecialFunctionInJava_2() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_2.kt"); + } + + @TestMetadata("specialFunctionInJava_3.kt") + public void testSpecialFunctionInJava_3() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_3.kt"); + } + + @TestMetadata("specialFunctionInJava_4.kt") + public void testSpecialFunctionInJava_4() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_4.kt"); + } + } + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/smartcasts") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.fir.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.fir.txt new file mode 100644 index 00000000000..e6f95c21148 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.fir.txt @@ -0,0 +1,22 @@ +FILE: explicitOverrideOfTwoMembers.kt + public abstract interface A : R|kotlin/Any| { + public abstract fun foo(): R|kotlin/Any| + + public abstract val x: R|kotlin/Any| + public get(): R|kotlin/Any| + + } + public abstract interface B : R|kotlin/Any| { + public abstract fun foo(): R|kotlin/Any| + + public abstract val x: R|kotlin/Any| + public get(): R|kotlin/Any| + + } + public abstract interface C : R|A|, R|B| { + public abstract override fun foo(): R|kotlin/Any| + + public abstract override val x: R|kotlin/Any| + public get(): R|kotlin/Any| + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.kt b/compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.kt new file mode 100644 index 00000000000..a9dac33f15d --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.kt @@ -0,0 +1,16 @@ +// SCOPE_DUMP: C:foo;x + +interface A { + fun foo(): Any + val x: Any +} + +interface B { + fun foo(): Any + val x: Any +} + +interface C : A, B { + override fun foo(): Any + override val x: Any +} diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.overrides.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.overrides.txt new file mode 100644 index 00000000000..b6f9141e4f5 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.overrides.txt @@ -0,0 +1,8 @@ +C: + [Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /C [id: 0] + [Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 1] + [Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /B [id: 2] + [Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /C [id: 0] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 1] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /B [id: 2] + diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers_java.fir.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers_java.fir.txt new file mode 100644 index 00000000000..90f085fa513 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers_java.fir.txt @@ -0,0 +1,26 @@ +FILE: lib.kt + public abstract interface A : R|kotlin/Any| { + public abstract fun foo(): R|kotlin/Any| + + public abstract val x: R|kotlin/Int| + public get(): R|kotlin/Int| + + public abstract val y: R|kotlin/Int| + public get(): R|kotlin/Int| + + } + public abstract interface B : R|kotlin/Any| { + public abstract fun foo(): R|kotlin/Any| + + public abstract val x: R|kotlin/String| + public get(): R|kotlin/String| + + public abstract val y: R|kotlin/Int| + public get(): R|kotlin/Int| + + } +FILE: main.kt + public final fun test(d: R|D|): R|kotlin/Unit| { + lval a: R|kotlin/Int| = R|/d|.R|/C.x| + lval b: R|kotlin/Int| = R|/d|.R|/D.y| + } diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers_java.kt b/compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers_java.kt new file mode 100644 index 00000000000..a5013c7974d --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers_java.kt @@ -0,0 +1,42 @@ +// SCOPE_DUMP: C:foo;x;y;getX, D:x;y;getX, E:x;getX + +// FILE: lib.kt +interface A { + fun foo(): Any + val x: Int + val y: Int +} + +interface B { + fun foo(): Any + val x: String + val y: Int +} + +// FILE: C.java +public abstract class C { + public int x; + private int y; +} + +// FILE: D.java +public abstract class D extends C implements A, B { + public abstract Object foo(); + + public abstract Object getX(); + public abstract int getY(); +} + +// FILE: E.java +public abstract class E implements A, B { + public abstract Object foo(); + + public abstract Object getX(); +} + +// FILE: main.kt + +fun test(d: D) { + val a = d.x + val b = d.y +} diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers_java.overrides.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers_java.overrides.txt new file mode 100644 index 00000000000..8301b4ac7dc --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers_java.overrides.txt @@ -0,0 +1,21 @@ +C: + [Java]: public open field x: R|kotlin/Int| from Java enhancement scope for /C [id: 0] + [Java]: private open field y: R|kotlin/Int| from Java enhancement scope for /C [id: 0] + +D: + [Java]: public open field x: R|kotlin/Int| from Java enhancement scope for /D [id: 0] + [IntersectionOverride]: public abstract val x: R|kotlin/Int| from Java enhancement scope for /D [id: 0] + [Source]: public abstract val x: R|kotlin/Int| from Use site scope of /A [id: 1] + [Source]: public abstract val x: R|kotlin/String| from Use site scope of /B [id: 2] + [Java]: private open field y: R|kotlin/Int| from Java enhancement scope for /D [id: 0] + [Synthetic]: public abstract val y: R|kotlin/Int| from Java enhancement scope for /D [id: 0] + [Source]: public abstract val y: R|kotlin/Int| from Use site scope of /A [id: 1] + [Source]: public abstract val y: R|kotlin/Int| from Use site scope of /B [id: 2] + [Enhancement]: public abstract fun getX(): R|ft| from Java enhancement scope for /D [id: 0] + +E: + [IntersectionOverride]: public abstract val x: R|kotlin/Int| from Java enhancement scope for /E [id: 0] + [Source]: public abstract val x: R|kotlin/Int| from Use site scope of /A [id: 1] + [Source]: public abstract val x: R|kotlin/String| from Use site scope of /B [id: 2] + [Enhancement]: public abstract fun getX(): R|ft| from Java enhancement scope for /E [id: 0] + diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/getterOverrideAndKotlinProperty.fir.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/getterOverrideAndKotlinProperty.fir.txt new file mode 100644 index 00000000000..a0ae777b207 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/getterOverrideAndKotlinProperty.fir.txt @@ -0,0 +1,24 @@ +FILE: B.kt + public abstract class B : R|A| { + public constructor(): R|B| { + super() + } + + private final val foo: R|kotlin/Int| = Int(1) + private get(): R|kotlin/Int| + + public open override fun getFoo(): R|kotlin/String| { + ^getFoo String(foo) + } + + } +FILE: main.kt + public final class D : R|C| { + public constructor(): R|D| { + super() + } + + } + public final fun test(d: R|D|): R|kotlin/Unit| { + R|/d|.R|/B.foo|.R|kotlin/String.length| + } diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/getterOverrideAndKotlinProperty.kt b/compiler/fir/analysis-tests/testData/resolve/scopes/getterOverrideAndKotlinProperty.kt new file mode 100644 index 00000000000..84acec933f1 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/getterOverrideAndKotlinProperty.kt @@ -0,0 +1,22 @@ +// SCOPE_DUMP: A:getFoo, B:getFoo, C:getFoo, D:getFoo +// FILE: A.java +public interface A { + String getFoo(); +} + +// FILE: B.kt +abstract class B : A { + private val foo: Int = 1 + + override fun getFoo(): String = "foo" +} + +// FILE: C.java +public abstract class C extends B implements A {} + +// FILE: main.kt +class D : C() + +fun test(d: D) { + d.foo.length +} diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/getterOverrideAndKotlinProperty.overrides.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/getterOverrideAndKotlinProperty.overrides.txt new file mode 100644 index 00000000000..43927830d4a --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/getterOverrideAndKotlinProperty.overrides.txt @@ -0,0 +1,15 @@ +A: + [Enhancement]: public abstract fun getFoo(): R|ft| from Java enhancement scope for /A [id: 0] + +B: + [Source]: public open override fun getFoo(): R|kotlin/String| from Use site scope of /B [id: 0] + [Enhancement]: public abstract fun getFoo(): R|ft| from Java enhancement scope for /A [id: 1] + +C: + [Source]: public open override fun getFoo(): R|kotlin/String| from Java enhancement scope for /C [id: 0] + [Enhancement]: public abstract fun getFoo(): R|ft| from Java enhancement scope for /A [id: 1] + +D: + [Source]: public open override fun getFoo(): R|kotlin/String| from Use site scope of /D [id: 0] + [Enhancement]: public abstract fun getFoo(): R|ft| from Java enhancement scope for /A [id: 1] + diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers.fir.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers.fir.txt new file mode 100644 index 00000000000..ca93cfd59d3 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers.fir.txt @@ -0,0 +1,24 @@ +FILE: intersectionOverrideOfTwoMembers.kt + public abstract interface A : R|kotlin/Any| { + public abstract fun foo(): R|kotlin/Any| + + public abstract val x: R|kotlin/Any| + public get(): R|kotlin/Any| + + } + public abstract interface B : R|kotlin/Any| { + public abstract fun foo(): R|kotlin/Any| + + public abstract val x: R|kotlin/Any| + public get(): R|kotlin/Any| + + } + public abstract interface C : R|A|, R|B| { + } + public abstract interface D : R|C| { + public abstract override fun foo(): R|kotlin/Any| + + public abstract override val x: R|kotlin/Any| + public get(): R|kotlin/Any| + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers.kt b/compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers.kt new file mode 100644 index 00000000000..17d42c81ca1 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers.kt @@ -0,0 +1,18 @@ +// SCOPE_DUMP: C:foo;x, D:foo;x + +interface A { + fun foo(): Any + val x: Any +} + +interface B { + fun foo(): Any + val x: Any +} + +interface C : A, B + +interface D : C { + override fun foo(): Any + override val x: Any +} diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers.overrides.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers.overrides.txt new file mode 100644 index 00000000000..1dee26bb4d6 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers.overrides.txt @@ -0,0 +1,18 @@ +C: + [IntersectionOverride]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /C [id: 0] + [Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 1] + [Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /B [id: 2] + [IntersectionOverride]: public abstract val x: R|kotlin/Any| from Use site scope of /C [id: 0] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 1] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /B [id: 2] + +D: + [Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /D [id: 0] + [IntersectionOverride]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /C [id: 1] + [Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 2] + [Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /B [id: 3] + [Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /D [id: 0] + [IntersectionOverride]: public abstract val x: R|kotlin/Any| from Use site scope of /C [id: 1] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 2] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /B [id: 3] + diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers_java.fir.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers_java.fir.txt new file mode 100644 index 00000000000..a2084a58d5e --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers_java.fir.txt @@ -0,0 +1,24 @@ +FILE: intersectionOverrideOfTwoMembers_java.kt + public abstract interface A : R|kotlin/Any| { + public abstract fun foo(): R|kotlin/Any| + + public abstract val x: R|kotlin/Any| + public get(): R|kotlin/Any| + + } + public abstract interface B : R|kotlin/Any| { + public abstract fun foo(): R|kotlin/Any| + + public abstract val x: R|kotlin/Any| + public get(): R|kotlin/Any| + + } + public abstract interface C : R|A|, R|B| { + } + public abstract interface D : R|C| { + public abstract override fun foo(): R|kotlin/Any| + + public abstract override val x: R|kotlin/Any| + public get(): R|kotlin/Any| + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers_java.kt b/compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers_java.kt new file mode 100644 index 00000000000..17d42c81ca1 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers_java.kt @@ -0,0 +1,18 @@ +// SCOPE_DUMP: C:foo;x, D:foo;x + +interface A { + fun foo(): Any + val x: Any +} + +interface B { + fun foo(): Any + val x: Any +} + +interface C : A, B + +interface D : C { + override fun foo(): Any + override val x: Any +} diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers_java.overrides.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers_java.overrides.txt new file mode 100644 index 00000000000..26b74036639 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers_java.overrides.txt @@ -0,0 +1,17 @@ +C: + [IntersectionOverride]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /C [id: 0] + [Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 1] + [Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /B [id: 2] + [IntersectionOverride]: public abstract val x: R|kotlin/Any| from Use site scope of /C [id: 0] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 1] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /B [id: 2] + +D: + [Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /D [id: 0] + [IntersectionOverride]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /C [id: 1] + [Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 2] + [Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /B [id: 3] + [Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /D [id: 0] + [IntersectionOverride]: public abstract val x: R|kotlin/Any| from Use site scope of /C [id: 1] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 2] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /B [id: 3] diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/javaFunctionAndKotlinPropertyFromDifferentSupertypes.fir.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/javaFunctionAndKotlinPropertyFromDifferentSupertypes.fir.txt new file mode 100644 index 00000000000..70d317e3ba2 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/javaFunctionAndKotlinPropertyFromDifferentSupertypes.fir.txt @@ -0,0 +1,13 @@ +FILE: B.kt + public abstract interface B : R|kotlin/Any| { + public abstract val foo: R|kotlin/Int| + public get(): R|kotlin/Int| + + } +FILE: main.kt + public final class D : R|C| { + public constructor(): R|D| { + super() + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/javaFunctionAndKotlinPropertyFromDifferentSupertypes.kt b/compiler/fir/analysis-tests/testData/resolve/scopes/javaFunctionAndKotlinPropertyFromDifferentSupertypes.kt new file mode 100644 index 00000000000..38b4102410a --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/javaFunctionAndKotlinPropertyFromDifferentSupertypes.kt @@ -0,0 +1,18 @@ +// SCOPE_DUMP: C:foo;getFoo +// FILE: A.java +public abstract class A { + public int getFoo() { + return 42; + } +} + +// FILE: B.kt +interface B { + val foo: Int +} + +// FILE: C.java +public class C extends A implements B {} + +// FILE: main.kt +class D : C() diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/javaFunctionAndKotlinPropertyFromDifferentSupertypes.overrides.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/javaFunctionAndKotlinPropertyFromDifferentSupertypes.overrides.txt new file mode 100644 index 00000000000..dd19af21155 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/javaFunctionAndKotlinPropertyFromDifferentSupertypes.overrides.txt @@ -0,0 +1,4 @@ +C: + [Synthetic]: public open val foo: R|kotlin/Int| from Java enhancement scope for /C [id: 0] + [Source]: public abstract val foo: R|kotlin/Int| from Use site scope of /B [id: 1] + diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/kotlinAccessorsLikeFunctionsThrowJavaClass.fir.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/kotlinAccessorsLikeFunctionsThrowJavaClass.fir.txt new file mode 100644 index 00000000000..71486cff298 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/kotlinAccessorsLikeFunctionsThrowJavaClass.fir.txt @@ -0,0 +1,24 @@ +FILE: A.kt + public open class A : R|kotlin/Any| { + public constructor(): R|A| { + super() + } + + public open fun getScope(): R|kotlin/String?| { + ^getScope Null(null) + } + + public final fun setScope(scope: R|kotlin/String?|): R|A| { + ^setScope this@R|/A| + } + + protected final var scope: R|kotlin/String?| = Null(null) + protected get(): R|kotlin/String?| + protected set(value: R|kotlin/String?|): R|kotlin/Unit| + + } +FILE: main.kt + public final fun test(b: R|B|): R|kotlin/Unit| { + lval s: R|kotlin/String?| = R|/b|.R|/B.getScope|() + R|/b|.R|/A.setScope|(R|/s|) + } diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/kotlinAccessorsLikeFunctionsThrowJavaClass.kt b/compiler/fir/analysis-tests/testData/resolve/scopes/kotlinAccessorsLikeFunctionsThrowJavaClass.kt new file mode 100644 index 00000000000..92be1b74eac --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/kotlinAccessorsLikeFunctionsThrowJavaClass.kt @@ -0,0 +1,23 @@ +// FILE: A.kt +open class A { + open fun getScope(): String? = null + fun setScope(scope: String?): A { + return this + } + + protected var scope: String? = null +} + +// FILE: B.java +public class B extends A { + @java.lang.Override + public String getScope() { + return null; + } +} + +// FILE: main.kt +fun test(b: B) { + val s = b.getScope() + b.setScope(s) +} diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers.fir.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers.fir.txt new file mode 100644 index 00000000000..8d331ea2bc4 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers.fir.txt @@ -0,0 +1,33 @@ +FILE: noIntersectionOverrideOfTwoMembers.kt + public abstract interface A : R|kotlin/Any| { + public abstract fun foo(): R|kotlin/Any| + + public abstract val x: R|kotlin/Any| + public get(): R|kotlin/Any| + + } + public abstract interface B : R|A| { + public abstract override fun foo(): R|kotlin/Any| + + public abstract override val x: R|kotlin/Any| + public get(): R|kotlin/Any| + + } + public abstract interface C : R|A|, R|B| { + } + public abstract interface D : R|kotlin/Any| { + public abstract fun foo(): R|kotlin/Int| + + public abstract val x: R|kotlin/Any| + public get(): R|kotlin/Any| + + } + public abstract interface Explicit : R|C|, R|D| { + public abstract override fun foo(): R|kotlin/Int| + + public abstract override val x: R|kotlin/Any| + public get(): R|kotlin/Any| + + } + public abstract interface Implicit : R|C|, R|D| { + } diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers.kt b/compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers.kt new file mode 100644 index 00000000000..a9e179c07c1 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers.kt @@ -0,0 +1,25 @@ +// SCOPE_DUMP: C:foo;x, Explicit:foo;x, Implicit:foo;x + +interface A { + fun foo(): Any + val x: Any +} + +interface B : A { + override fun foo(): Any + override val x: Any +} + +interface C : A, B + +interface D { + fun foo(): Int + val x: Any +} + +interface Explicit : C, D { + override fun foo(): Int + override val x: Any +} + +interface Implicit : C, D diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers.overrides.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers.overrides.txt new file mode 100644 index 00000000000..be866ea1148 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers.overrides.txt @@ -0,0 +1,26 @@ +C: + [Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /C [id: 0] + [Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 1] + [Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /C [id: 0] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 1] + +Explicit: + [Source]: public abstract override fun foo(): R|kotlin/Int| from Use site scope of /Explicit [id: 0] + [Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /C [id: 1] + [Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 2] + [Source]: public abstract fun foo(): R|kotlin/Int| from Use site scope of /D [id: 3] + [Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /Explicit [id: 0] + [Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /C [id: 1] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 2] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /D [id: 3] + +Implicit: + [IntersectionOverride]: public abstract fun foo(): R|kotlin/Int| from Use site scope of /Implicit [id: 0] + [Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /C [id: 1] + [Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 2] + [Source]: public abstract fun foo(): R|kotlin/Int| from Use site scope of /D [id: 3] + [IntersectionOverride]: public abstract override val x: R|kotlin/Any| from Use site scope of /Implicit [id: 0] + [Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /C [id: 1] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 2] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /D [id: 3] + diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers_java.fir.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers_java.fir.txt new file mode 100644 index 00000000000..d4507cff261 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers_java.fir.txt @@ -0,0 +1,33 @@ +FILE: noIntersectionOverrideOfTwoMembers_java.kt + public abstract interface A : R|kotlin/Any| { + public abstract fun foo(): R|kotlin/Any| + + public abstract val x: R|kotlin/Any| + public get(): R|kotlin/Any| + + } + public abstract interface B : R|A| { + public abstract override fun foo(): R|kotlin/Any| + + public abstract override val x: R|kotlin/Any| + public get(): R|kotlin/Any| + + } + public abstract interface C : R|A|, R|B| { + } + public abstract interface D : R|kotlin/Any| { + public abstract fun foo(): R|kotlin/Int| + + public abstract val x: R|kotlin/Any| + public get(): R|kotlin/Any| + + } + public abstract interface Explicit : R|C|, R|D| { + public abstract override fun foo(): R|kotlin/Int| + + public abstract override val x: R|kotlin/Any| + public get(): R|kotlin/Any| + + } + public abstract interface Implicit : R|C|, R|D| { + } diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers_java.kt b/compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers_java.kt new file mode 100644 index 00000000000..a9e179c07c1 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers_java.kt @@ -0,0 +1,25 @@ +// SCOPE_DUMP: C:foo;x, Explicit:foo;x, Implicit:foo;x + +interface A { + fun foo(): Any + val x: Any +} + +interface B : A { + override fun foo(): Any + override val x: Any +} + +interface C : A, B + +interface D { + fun foo(): Int + val x: Any +} + +interface Explicit : C, D { + override fun foo(): Int + override val x: Any +} + +interface Implicit : C, D diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers_java.overrides.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers_java.overrides.txt new file mode 100644 index 00000000000..5bbcbed223f --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers_java.overrides.txt @@ -0,0 +1,25 @@ +C: + [Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /C [id: 0] + [Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 1] + [Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /C [id: 0] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 1] + +Explicit: + [Source]: public abstract override fun foo(): R|kotlin/Int| from Use site scope of /Explicit [id: 0] + [Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /C [id: 1] + [Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 2] + [Source]: public abstract fun foo(): R|kotlin/Int| from Use site scope of /D [id: 3] + [Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /Explicit [id: 0] + [Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /C [id: 1] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 2] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /D [id: 3] + +Implicit: + [IntersectionOverride]: public abstract fun foo(): R|kotlin/Int| from Use site scope of /Implicit [id: 0] + [Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /C [id: 1] + [Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 2] + [Source]: public abstract fun foo(): R|kotlin/Int| from Use site scope of /D [id: 3] + [IntersectionOverride]: public abstract override val x: R|kotlin/Any| from Use site scope of /Implicit [id: 0] + [Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /C [id: 1] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 2] + [Source]: public abstract val x: R|kotlin/Any| from Use site scope of /D [id: 3] diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.fir.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.fir.txt new file mode 100644 index 00000000000..53cb2752fa5 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.fir.txt @@ -0,0 +1,23 @@ +FILE: C.kt + public open class C : R|B| { + public constructor(name: R|kotlin/String|): R|C| { + super() + } + + private final var name: R|kotlin/String| = R|/name| + private get(): R|kotlin/String| + private set(value: R|kotlin/String|): R|kotlin/Unit| + + public open override fun getName(): R|kotlin/String| { + ^getName this@R|/C|.R|/C.name| + } + + public open override fun setName(newName: R|kotlin/String|): R|kotlin/Any?| { + ^setName Null(null) + } + + } +FILE: main.kt + public final fun test(d: R|D|): R|kotlin/Unit| { + lval name: R|kotlin/String| = R|/d|.R|/C.name| + } diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.kt b/compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.kt new file mode 100644 index 00000000000..7d1ae513d17 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.kt @@ -0,0 +1,25 @@ +// SCOPE_DUMP: C:getName;setName;name, D:getName;setName;name +// FILE: A.java +public interface A { + String getName(); +} + +// FILE: B.java +public interface B extends A { + T setName(String newName); +} + +// FILE: C.kt +open class C(private var name: String) : B { + override fun getName(): String = name + override fun setName(newName: String): Any? = null +} + +// FILE: D.java +public class D extends C {} + +// FILE: main.kt +fun test(d: D) { + val name = d.name +} + diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.overrides.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.overrides.txt new file mode 100644 index 00000000000..1e04e82ef69 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.overrides.txt @@ -0,0 +1,14 @@ +C: + [Source]: public open override fun getName(): R|kotlin/String| from Use site scope of /C [id: 0] + [Enhancement]: public abstract fun getName(): R|ft| from Substitution scope for [Java enhancement scope for /B] for type C [id: 1] + [Source]: public open override fun setName(newName: R|kotlin/String|): R|kotlin/Any?| from Use site scope of /C [id: 0] + [SubstitutionOverride]: public abstract fun setName(newName: R|ft|): R|kotlin/Any?| from Substitution scope for [Java enhancement scope for /B] for type C [id: 1] + [Enhancement]: public abstract fun setName(newName: R|ft|): R|ft| from Java enhancement scope for /B [id: 2] + [Source]: private final var name: R|kotlin/String| = R|/name| from Use site scope of /C [id: 0] + +D: + [Source]: public open override fun getName(): R|kotlin/String| from Java enhancement scope for /D [id: 0] + [Enhancement]: public abstract fun getName(): R|ft| from Substitution scope for [Java enhancement scope for /B] for type C [id: 1] + [Source]: private final var name: R|kotlin/String| = R|/name| from Java enhancement scope for /D [id: 0] + [Source]: private final var name: R|kotlin/String| = R|/name| from Use site scope of /C [id: 0] + diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_1.fir.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_1.fir.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_1.kt b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_1.kt new file mode 100644 index 00000000000..8e00c3b9ff0 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_1.kt @@ -0,0 +1,41 @@ +// SCOPE_DUMP: Some:toByte;byteValue;toShort;shortValue;toInt;intValue;toLong;longValue MyNumber:toByte;byteValue + +// FILE: MyBaseNumber.java +public interface MyBaseNumber { + byte byteValue(); // (1) + short shortValue(); // (1) +} + +// FILE: MyNumber.java +public interface MyNumber extends MyBaseNumber { + @Override + byte byteValue(); // (2) + + @Override + short shortValue(); // (1) + + int intValue(); +} + +// FILE: Some.java +public abstract class Some extends Number implements MyNumber { + @Override + public abstract byte byteValue() // (3) +} + +/* + * Some.toByte() (3', renamed) overrides Number.toByte & MyNumber.toByte(2', renamed) + * MyNumber.toByte(2', renamed) overrides ??? + */ + +fun test(some: Some) { + some.toByte() + some.toShort() + some.toInt() + some.toLong() + + some.byteValue() + some.shortValue() + some.intValue() + some.longValue() +} diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_1.overrides.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_1.overrides.txt new file mode 100644 index 00000000000..f8cf0b7d515 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_1.overrides.txt @@ -0,0 +1,18 @@ +Some: + [Enhancement]: public abstract operator fun toByte(): R|kotlin/Byte| from Java enhancement scope for /Some [id: 0] + [Library]: public abstract fun toByte(): R|kotlin/Byte| from Use site scope of kotlin/Number [id: 1] + [RenamedForOverride]: public abstract fun toByte(): R|kotlin/Byte| from Java enhancement scope for /MyNumber [id: 2] + [Enhancement]: public abstract fun byteValue(): R|kotlin/Byte| from Java enhancement scope for /MyBaseNumber [id: 3] + [IntersectionOverride]: public abstract fun toShort(): R|kotlin/Short| from Java enhancement scope for /Some [id: 0] + [Library]: public abstract fun toShort(): R|kotlin/Short| from Use site scope of kotlin/Number [id: 1] + [RenamedForOverride]: public abstract fun toShort(): R|kotlin/Short| from Java enhancement scope for /MyNumber [id: 2] + [Enhancement]: public abstract fun shortValue(): R|kotlin/Short| from Java enhancement scope for /MyBaseNumber [id: 3] + [IntersectionOverride]: public abstract fun toInt(): R|kotlin/Int| from Java enhancement scope for /Some [id: 0] + [Library]: public abstract fun toInt(): R|kotlin/Int| from Use site scope of kotlin/Number [id: 1] + [RenamedForOverride]: public abstract fun toInt(): R|kotlin/Int| from Java enhancement scope for /MyNumber [id: 2] + [Library]: public abstract fun toLong(): R|kotlin/Long| from Java enhancement scope for /Some [id: 0] + +MyNumber: + [Enhancement]: public abstract fun byteValue(): R|kotlin/Byte| from Java enhancement scope for /MyNumber [id: 0] + [Enhancement]: public abstract fun byteValue(): R|kotlin/Byte| from Java enhancement scope for /MyBaseNumber [id: 1] + diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_2.fir.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_2.fir.txt new file mode 100644 index 00000000000..c492de0465d --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_2.fir.txt @@ -0,0 +1,11 @@ +FILE: main.kt + public final fun test(map: R|SomeMap|): R|kotlin/Unit| { + R|/map|.R|SubstitutionOverride|(Int(1)) + R|/map|.#(String()) + R|/map|.R|SubstitutionOverride|(String()) + R|/map|.#(Int(1)) + R|/map|.R|SubstitutionOverride|(Int(1)) + R|/map|.#(String()) + R|/map|.R|SubstitutionOverride|(Int(1)) + R|/map|.#(String()) + } diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_2.kt b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_2.kt new file mode 100644 index 00000000000..3639d39a382 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_2.kt @@ -0,0 +1,42 @@ +// SCOPE_DUMP: SomeMap:containsKey;containsValue;get;remove, MyMap:containsKey;containsValue;get + +// FILE: MyBaseMap.java +public interface MyBaseMap { + boolean containsKey(Object key); +} + +// FILE: MyMap.java +public interface MyMap extends MyBaseMap { + @Override + boolean containsKey(Object key); + boolean containsValue(Object key); + + V2 get(K2 key); +} + +// FILE: SomeMap.java +import java.util.Map; + +public abstract class SomeMap implements Map, MyMap { + @Override + public abstract boolean containsKey(Object key); + + @Override + public abstract V3 remove(Object key); +} + +// FILE: main.kt + +fun test(map: SomeMap) { + map.containsKey(1) // ok + map.containsKey("") // error + + map.containsValue("") // ok + map.containsValue(1) // error + + map.get(1) // ok + map.get("") // error + + map.remove(1) // ok + map.remove("") // error +} diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_2.overrides.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_2.overrides.txt new file mode 100644 index 00000000000..02ba2867527 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_2.overrides.txt @@ -0,0 +1,39 @@ +SomeMap: + [Enhancement]: public abstract fun containsKey(key: R|ft|): R|kotlin/Boolean| from Java enhancement scope for /SomeMap [id: 0] + [SubstitutionOverride]: public abstract fun containsKey(key: R|ft|): R|kotlin/Boolean| from Substitution scope for [Use site scope of kotlin/collections/MutableMap] for type SomeMap [id: 1] + [SubstitutionOverride]: public abstract fun containsKey(key: R|K|): R|kotlin/Boolean| from Use site scope of kotlin/collections/MutableMap [id: 2] + [Library]: public abstract fun containsKey(key: R|K|): R|kotlin/Boolean| from Use site scope of kotlin/collections/Map [id: 3] + [Library]: public abstract fun containsKey(key: R|K|): R|kotlin/Boolean| from Use site scope of kotlin/collections/Map [id: 3] + [SubstitutionOverride]: public abstract fun containsKey(key: R|ft|): R|kotlin/Boolean| from Substitution scope for [Java enhancement scope for /MyMap] for type SomeMap [id: 4] + [Enhancement]: public abstract fun containsKey(key: R|ft|): R|kotlin/Boolean| from Java enhancement scope for /MyMap [id: 5] + [SubstitutionOverride]: public abstract fun containsKey(key: R|ft|): R|kotlin/Boolean| from Substitution scope for [Java enhancement scope for /MyBaseMap] for type MyMap [id: 6] + [Enhancement]: public abstract fun containsKey(key: R|ft|): R|kotlin/Boolean| from Java enhancement scope for /MyBaseMap [id: 7] + [SubstitutionOverride]: public abstract fun containsKey(key: R|ft|): R|kotlin/Boolean| from Substitution scope for [Java enhancement scope for /MyBaseMap] for type MyMap [id: 6] + [Enhancement]: public abstract fun containsKey(key: R|ft|): R|kotlin/Boolean| from Java enhancement scope for /MyBaseMap [id: 7] + [IntersectionOverride]: public abstract fun containsValue(value: R|ft|): R|kotlin/Boolean| from Java enhancement scope for /SomeMap [id: 0] + [SubstitutionOverride]: public abstract fun containsValue(value: R|ft|): R|kotlin/Boolean| from Substitution scope for [Use site scope of kotlin/collections/MutableMap] for type SomeMap [id: 1] + [SubstitutionOverride]: public abstract fun containsValue(value: R|V|): R|kotlin/Boolean| from Use site scope of kotlin/collections/MutableMap [id: 2] + [Library]: public abstract fun containsValue(value: R|V|): R|kotlin/Boolean| from Use site scope of kotlin/collections/Map [id: 3] + [Library]: public abstract fun containsValue(value: R|V|): R|kotlin/Boolean| from Use site scope of kotlin/collections/Map [id: 3] + [SubstitutionOverride]: public abstract fun containsValue(key: R|ft|): R|kotlin/Boolean| from Substitution scope for [Java enhancement scope for /MyMap] for type SomeMap [id: 4] + [Enhancement]: public abstract fun containsValue(key: R|ft|): R|kotlin/Boolean| from Java enhancement scope for /MyMap [id: 5] + [IntersectionOverride]: public abstract operator fun get(key: R|ft|): R|V3?| from Java enhancement scope for /SomeMap [id: 0] + [SubstitutionOverride]: public abstract operator fun get(key: R|ft|): R|V3?| from Substitution scope for [Use site scope of kotlin/collections/MutableMap] for type SomeMap [id: 1] + [SubstitutionOverride]: public abstract operator fun get(key: R|K|): R|V?| from Use site scope of kotlin/collections/MutableMap [id: 2] + [Library]: public abstract operator fun get(key: R|K|): R|V?| from Use site scope of kotlin/collections/Map [id: 3] + [Library]: public abstract operator fun get(key: R|K|): R|V?| from Use site scope of kotlin/collections/Map [id: 3] + [SubstitutionOverride]: public abstract operator fun get(key: R|ft|): R|ft| from Substitution scope for [Java enhancement scope for /MyMap] for type SomeMap [id: 4] + [Enhancement]: public abstract operator fun get(key: R|ft|): R|ft| from Java enhancement scope for /MyMap [id: 5] + [Enhancement]: public abstract fun remove(key: R|ft|): R|V3?| from Java enhancement scope for /SomeMap [id: 0] + [SubstitutionOverride]: public abstract fun remove(key: R|ft|): R|V3?| from Substitution scope for [Use site scope of kotlin/collections/MutableMap] for type SomeMap [id: 1] + [Library]: public abstract fun remove(key: R|K|): R|V?| from Use site scope of kotlin/collections/MutableMap [id: 2] + [SubstitutionOverride]: public open fun remove(key: R|ft|, value: R|ft|): R|kotlin/Boolean| from Java enhancement scope for /SomeMap [id: 0] + [Library]: public open fun remove(key: R|K|, value: R|V|): R|kotlin/Boolean| from Use site scope of kotlin/collections/MutableMap [id: 1] + +MyMap: + [Enhancement]: public abstract fun containsKey(key: R|ft|): R|kotlin/Boolean| from Java enhancement scope for /MyMap [id: 0] + [SubstitutionOverride]: public abstract fun containsKey(key: R|ft|): R|kotlin/Boolean| from Substitution scope for [Java enhancement scope for /MyBaseMap] for type MyMap [id: 1] + [Enhancement]: public abstract fun containsKey(key: R|ft|): R|kotlin/Boolean| from Java enhancement scope for /MyBaseMap [id: 2] + [Enhancement]: public abstract fun containsValue(key: R|ft|): R|kotlin/Boolean| from Java enhancement scope for /MyMap [id: 0] + [Enhancement]: public abstract operator fun get(key: R|ft|): R|ft| from Java enhancement scope for /MyMap [id: 0] + diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_3.fir.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_3.fir.txt new file mode 100644 index 00000000000..3f878b2afe0 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_3.fir.txt @@ -0,0 +1,23 @@ +FILE: main.kt + public abstract class A : R|kotlin/Any| { + public constructor(): R|A| { + super() + } + + public open val x: R|kotlin/Int| + public get(): R|kotlin/Int| { + ^ Int(1) + } + + public open val y: R|kotlin/Int| + public get(): R|kotlin/Int| { + ^ Int(2) + } + + } + public final class DImpl : R|D| { + public constructor(): R|DImpl| { + super() + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_3.kt b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_3.kt new file mode 100644 index 00000000000..cf379fe2717 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_3.kt @@ -0,0 +1,28 @@ +// SCOPE_DUMP: D:x;getX;y;getY + +// FILE: B.java +public abstract class B extends A { + @Override + public int getX() { return 0; } +} + +// FILE: C.java +public interface C { + int getX(); + int getY(); +} + +// FILE: D.java +public abstract class D extends B implements C {} + +// FILE: main.kt + +abstract class A { + open val x: Int + get() = 1 + open val y: Int + get() = 2 +} + +class DImpl : D() + diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_3.overrides.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_3.overrides.txt new file mode 100644 index 00000000000..19d1cb9664a --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_3.overrides.txt @@ -0,0 +1,8 @@ +D: + [Synthetic]: public open val x: R|kotlin/Int| from Java enhancement scope for /D [id: 0] + [Synthetic]: public open val x: R|kotlin/Int| from Java enhancement scope for /B [id: 1] + [Source]: public open val x: R|kotlin/Int| from Use site scope of /A [id: 2] + [Synthetic]: public open val y: R|kotlin/Int| from Java enhancement scope for /D [id: 0] + [Source]: public open val y: R|kotlin/Int| from Java enhancement scope for /B [id: 1] + [Source]: public open val y: R|kotlin/Int| from Use site scope of /A [id: 1] + diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_4.fir.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_4.fir.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_4.fir.txt @@ -0,0 +1 @@ + diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_4.kt b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_4.kt new file mode 100644 index 00000000000..92920ee7535 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_4.kt @@ -0,0 +1,28 @@ +// SCOPE_DUMP: Some:toByte;byteValue MyNumber:toByte;byteValue +// -SCOPE_DUMP: Some:toInt;intValue;toByte;byteValue;toLong;longValue + +// FILE: MyBaseNumber.java +public interface MyBaseNumber { + byte byteValue(); // (1) +} + +// FILE: MyNumber.java +public interface MyNumber extends MyBaseNumber { + @Override + byte byteValue(); // (2) +} + +// FILE: Some.java +public abstract class Some extends Number implements MyNumber { + @Override + public abstract byte byteValue() // (3) +} + +/* + * Some.toByte() (3', renamed) overrides Number.toByte & MyNumber.toByte(2', renamed) + * MyNumber.toByte(2', renamed) overrides ??? + */ + +fun test(some: Some) { + some.toByte() +} diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_4.overrides.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_4.overrides.txt new file mode 100644 index 00000000000..4ca4a9dec21 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_4.overrides.txt @@ -0,0 +1,10 @@ +Some: + [Enhancement]: public abstract operator fun toByte(): R|kotlin/Byte| from Java enhancement scope for /Some [id: 0] + [Library]: public abstract fun toByte(): R|kotlin/Byte| from Use site scope of kotlin/Number [id: 1] + [RenamedForOverride]: public abstract fun toByte(): R|kotlin/Byte| from Java enhancement scope for /MyNumber [id: 2] + [Enhancement]: public abstract fun byteValue(): R|kotlin/Byte| from Java enhancement scope for /MyBaseNumber [id: 3] + +MyNumber: + [Enhancement]: public abstract fun byteValue(): R|kotlin/Byte| from Java enhancement scope for /MyNumber [id: 0] + [Enhancement]: public abstract fun byteValue(): R|kotlin/Byte| from Java enhancement scope for /MyBaseNumber [id: 1] + diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java index 278bae9231a..caaf19bcd85 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java @@ -3482,6 +3482,100 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest { } } + @Nested + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/scopes") + @TestDataPath("$PROJECT_ROOT") + public class Scopes { + @Test + public void testAllFilesPresentInScopes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("explicitOverrideOfTwoMembers.kt") + public void testExplicitOverrideOfTwoMembers() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.kt"); + } + + @Test + @TestMetadata("explicitOverrideOfTwoMembers_java.kt") + public void testExplicitOverrideOfTwoMembers_java() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers_java.kt"); + } + + @Test + @TestMetadata("getterOverrideAndKotlinProperty.kt") + public void testGetterOverrideAndKotlinProperty() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/getterOverrideAndKotlinProperty.kt"); + } + + @Test + @TestMetadata("intersectionOverrideOfTwoMembers.kt") + public void testIntersectionOverrideOfTwoMembers() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers.kt"); + } + + @Test + @TestMetadata("intersectionOverrideOfTwoMembers_java.kt") + public void testIntersectionOverrideOfTwoMembers_java() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers_java.kt"); + } + + @Test + @TestMetadata("javaFunctionAndKotlinPropertyFromDifferentSupertypes.kt") + public void testJavaFunctionAndKotlinPropertyFromDifferentSupertypes() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/javaFunctionAndKotlinPropertyFromDifferentSupertypes.kt"); + } + + @Test + @TestMetadata("kotlinAccessorsLikeFunctionsThrowJavaClass.kt") + public void testKotlinAccessorsLikeFunctionsThrowJavaClass() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/kotlinAccessorsLikeFunctionsThrowJavaClass.kt"); + } + + @Test + @TestMetadata("noIntersectionOverrideOfTwoMembers.kt") + public void testNoIntersectionOverrideOfTwoMembers() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers.kt"); + } + + @Test + @TestMetadata("noIntersectionOverrideOfTwoMembers_java.kt") + public void testNoIntersectionOverrideOfTwoMembers_java() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers_java.kt"); + } + + @Test + @TestMetadata("publicJavaAndPrivateKotlinVar.kt") + public void testPublicJavaAndPrivateKotlinVar() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.kt"); + } + + @Test + @TestMetadata("specialFunctionInJava_1.kt") + public void testSpecialFunctionInJava_1() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_1.kt"); + } + + @Test + @TestMetadata("specialFunctionInJava_2.kt") + public void testSpecialFunctionInJava_2() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_2.kt"); + } + + @Test + @TestMetadata("specialFunctionInJava_3.kt") + public void testSpecialFunctionInJava_3() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_3.kt"); + } + + @Test + @TestMetadata("specialFunctionInJava_4.kt") + public void testSpecialFunctionInJava_4() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_4.kt"); + } + } + @Nested @TestMetadata("compiler/fir/analysis-tests/testData/resolve/smartcasts") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java index 7007b00a1eb..afd1dfce582 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java @@ -3482,6 +3482,100 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos } } + @Nested + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/scopes") + @TestDataPath("$PROJECT_ROOT") + public class Scopes { + @Test + public void testAllFilesPresentInScopes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("explicitOverrideOfTwoMembers.kt") + public void testExplicitOverrideOfTwoMembers() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.kt"); + } + + @Test + @TestMetadata("explicitOverrideOfTwoMembers_java.kt") + public void testExplicitOverrideOfTwoMembers_java() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers_java.kt"); + } + + @Test + @TestMetadata("getterOverrideAndKotlinProperty.kt") + public void testGetterOverrideAndKotlinProperty() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/getterOverrideAndKotlinProperty.kt"); + } + + @Test + @TestMetadata("intersectionOverrideOfTwoMembers.kt") + public void testIntersectionOverrideOfTwoMembers() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers.kt"); + } + + @Test + @TestMetadata("intersectionOverrideOfTwoMembers_java.kt") + public void testIntersectionOverrideOfTwoMembers_java() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/intersectionOverrideOfTwoMembers_java.kt"); + } + + @Test + @TestMetadata("javaFunctionAndKotlinPropertyFromDifferentSupertypes.kt") + public void testJavaFunctionAndKotlinPropertyFromDifferentSupertypes() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/javaFunctionAndKotlinPropertyFromDifferentSupertypes.kt"); + } + + @Test + @TestMetadata("kotlinAccessorsLikeFunctionsThrowJavaClass.kt") + public void testKotlinAccessorsLikeFunctionsThrowJavaClass() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/kotlinAccessorsLikeFunctionsThrowJavaClass.kt"); + } + + @Test + @TestMetadata("noIntersectionOverrideOfTwoMembers.kt") + public void testNoIntersectionOverrideOfTwoMembers() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers.kt"); + } + + @Test + @TestMetadata("noIntersectionOverrideOfTwoMembers_java.kt") + public void testNoIntersectionOverrideOfTwoMembers_java() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers_java.kt"); + } + + @Test + @TestMetadata("publicJavaAndPrivateKotlinVar.kt") + public void testPublicJavaAndPrivateKotlinVar() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.kt"); + } + + @Test + @TestMetadata("specialFunctionInJava_1.kt") + public void testSpecialFunctionInJava_1() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_1.kt"); + } + + @Test + @TestMetadata("specialFunctionInJava_2.kt") + public void testSpecialFunctionInJava_2() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_2.kt"); + } + + @Test + @TestMetadata("specialFunctionInJava_3.kt") + public void testSpecialFunctionInJava_3() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_3.kt"); + } + + @Test + @TestMetadata("specialFunctionInJava_4.kt") + public void testSpecialFunctionInJava_4() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/scopes/specialFunctionInJava_4.kt"); + } + } + @Nested @TestMetadata("compiler/fir/analysis-tests/testData/resolve/smartcasts") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirNotImplementedOverrideChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirNotImplementedOverrideChecker.kt index 4b5de5909cf..270491654b6 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirNotImplementedOverrideChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirNotImplementedOverrideChecker.kt @@ -24,12 +24,10 @@ import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.resolve.toSymbol -import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenMembers -import org.jetbrains.kotlin.fir.scopes.impl.delegatedWrapperData -import org.jetbrains.kotlin.fir.scopes.impl.multipleDelegatesWithTheSameSignature -import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionCallableSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol +import org.jetbrains.kotlin.fir.scopes.MemberWithBaseScope +import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenMembersWithBaseScope +import org.jetbrains.kotlin.fir.scopes.impl.* +import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.unwrapFakeOverrides import org.jetbrains.kotlin.util.ImplementationStatus @@ -58,19 +56,25 @@ object FirNotImplementedOverrideChecker : FirClassChecker() { fun collectSymbol(symbol: FirCallableSymbol<*>) { val delegatedWrapperData = symbol.delegatedWrapperData if (delegatedWrapperData != null) { - val directOverriddenMembers = classScope.getDirectOverriddenMembers( - symbol, - unwrapIntersectionAndSubstitutionOverride = true + val directOverriddenMembersWithBaseScope = classScope.getDirectOverriddenMembersWithBaseScope( + symbol ) + @Suppress("UNCHECKED_CAST") + val filteredOverriddenMembers = when (symbol) { + is FirNamedFunctionSymbol -> filterOutOverriddenFunctions(directOverriddenMembersWithBaseScope as List>) + is FirPropertySymbol -> filterOutOverriddenProperties(directOverriddenMembersWithBaseScope as List>) + else -> directOverriddenMembersWithBaseScope + }.map { it.member } + val delegatedTo = delegatedWrapperData.wrapped.unwrapFakeOverrides().symbol if (symbol.multipleDelegatesWithTheSameSignature == true) { manyImplementationsDelegationSymbols.add(symbol) } - val firstFinal = directOverriddenMembers.firstOrNull { it.isFinal } - val firstOpen = directOverriddenMembers.firstOrNull { it.isOpen && delegatedTo != it.unwrapFakeOverrides() } + val firstFinal = filteredOverriddenMembers.firstOrNull { it.isFinal } + val firstOpen = filteredOverriddenMembers.firstOrNull { it.isOpen && delegatedTo != it.unwrapFakeOverrides() } when { firstFinal != null -> diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt index 0444b7b0930..a21af5c101d 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt @@ -333,7 +333,14 @@ object FirOverrideChecker : FirClassChecker() { with(FirOptInUsageBaseChecker) { val overriddenExperimentalities = mutableSetOf() val session = context.session - for (overriddenMemberSymbol in overriddenMemberSymbols) { + val overriddenSymbolsWithUnwrappedIntersectionOverrides = overriddenMemberSymbols.flatMap { + when (it) { + is FirIntersectionOverridePropertySymbol -> it.intersections + is FirIntersectionOverrideFunctionSymbol -> it.intersections + else -> listOf(it) + } + } + for (overriddenMemberSymbol in overriddenSymbolsWithUnwrappedIntersectionOverrides) { overriddenMemberSymbol.loadExperimentalitiesFromAnnotationTo(session, overriddenExperimentalities) } reportNotAcceptedOverrideExperimentalities( diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt index 223d44f379f..cd400190fd4 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt @@ -97,18 +97,10 @@ object JavaScopeProvider : FirScopeProvider() { } JavaClassUseSiteMemberScope( - regularClass, useSiteSession, - FirTypeIntersectionScope.prepareIntersectionScope( - useSiteSession, - JavaOverrideChecker( - useSiteSession, - regularClass.javaTypeParameterStack, - baseScope = null, - considerReturnTypeKinds = false, - ), - superTypeScopes, - regularClass.defaultType(), - ), declaredScope + regularClass, + useSiteSession, + superTypeScopes, + declaredScope ) } } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassMembersEnhancementScope.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassMembersEnhancementScope.kt index 0c2a32a2171..f76b59557b7 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassMembersEnhancementScope.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassMembersEnhancementScope.kt @@ -7,13 +7,15 @@ package org.jetbrains.kotlin.fir.java.scopes import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration -import org.jetbrains.kotlin.fir.declarations.FirProperty +import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction +import org.jetbrains.kotlin.fir.initialSignatureAttr import org.jetbrains.kotlin.fir.java.enhancement.FirSignatureEnhancement import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction -import org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScope +import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenMembers +import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenProperties import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.name.Name @@ -22,24 +24,18 @@ class JavaClassMembersEnhancementScope( private val owner: FirRegularClassSymbol, private val useSiteMemberScope: JavaClassUseSiteMemberScope, ) : FirTypeScope() { - private val overriddenFunctions = mutableMapOf>() - private val overriddenProperties = mutableMapOf>() + private val enhancedToOriginalFunctions = mutableMapOf() + private val enhancedToOriginalProperties = mutableMapOf() - private val overrideBindCache = mutableMapOf?, List>>() private val signatureEnhancement = FirSignatureEnhancement(owner.fir, session) { - overriddenMembersForEnhancement(name) + overriddenMembers() } override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { useSiteMemberScope.processPropertiesByName(name) process@{ original -> val enhancedPropertySymbol = signatureEnhancement.enhancedProperty(original, name) - val originalFir = original.fir - if (originalFir is FirProperty && enhancedPropertySymbol is FirPropertySymbol) { - val enhancedProperty = enhancedPropertySymbol.fir - overriddenProperties[enhancedPropertySymbol] = - originalFir - .overriddenMembers(enhancedProperty.name) - .mapNotNull { it.symbol as? FirPropertySymbol } + if (original is FirPropertySymbol && enhancedPropertySymbol is FirPropertySymbol) { + enhancedToOriginalProperties[enhancedPropertySymbol] = original } processor(enhancedPropertySymbol) @@ -55,9 +51,7 @@ class JavaClassMembersEnhancementScope( val enhancedFunctionSymbol = enhancedFunction?.symbol ?: symbol if (enhancedFunctionSymbol is FirNamedFunctionSymbol) { - overriddenFunctions[enhancedFunctionSymbol] = original.fir - .overriddenMembers(enhancedFunctionSymbol.fir.name) - .mapNotNull { it.symbol as? FirNamedFunctionSymbol } + enhancedToOriginalFunctions[enhancedFunctionSymbol] = original processor(enhancedFunctionSymbol) } } @@ -65,33 +59,12 @@ class JavaClassMembersEnhancementScope( return super.processFunctionsByName(name, processor) } - private fun FirCallableDeclaration.overriddenMembersForEnhancement(name: Name): List { - val directlyOverriddensFromScopeFir = overriddenMembers(name) - val superTypesScope = useSiteMemberScope.superTypesScope as? FirTypeIntersectionScope ?: return directlyOverriddensFromScopeFir - - val directlyOverriddensFromScope = directlyOverriddensFromScopeFir.map { it.symbol } - val result = mutableSetOf>() - for (intersectedOverriddenSymbol in directlyOverriddensFromScope) { - val newOverriddens = superTypesScope.getDirectOverriddenSymbols(intersectedOverriddenSymbol).map { it.member } - if (newOverriddens.isNotEmpty()) { - result += newOverriddens - } else { - result += intersectedOverriddenSymbol - } - } - return result.map { it.fir } - } - - private fun FirCallableDeclaration.overriddenMembers(name: Name): List { - val backMap = overrideBindCache.getOrPut(name) { - val result = mutableMapOf?, MutableList>() - for ((key, value) in useSiteMemberScope.overrideByBase) { - val resultItem = result.getOrPut(value) { mutableListOf() } - resultItem.add(key.fir) - } - result - } - return backMap[this.symbol] ?: emptyList() + private fun FirCallableDeclaration.overriddenMembers(): List { + return when (val symbol = this.symbol) { + is FirNamedFunctionSymbol -> useSiteMemberScope.getDirectOverriddenMembers(symbol) + is FirPropertySymbol -> useSiteMemberScope.getDirectOverriddenProperties(symbol) + else -> emptyList() + }.map { it.fir } } override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { @@ -110,18 +83,32 @@ class JavaClassMembersEnhancementScope( processor: (FirNamedFunctionSymbol, FirTypeScope) -> ProcessorAction ): ProcessorAction = doProcessDirectOverriddenCallables( - functionSymbol, processor, overriddenFunctions, useSiteMemberScope, - FirTypeScope::processDirectOverriddenFunctionsWithBaseScope + functionSymbol, processor, enhancedToOriginalFunctions, FirTypeScope::processDirectOverriddenFunctionsWithBaseScope ) override fun processDirectOverriddenPropertiesWithBaseScope( propertySymbol: FirPropertySymbol, processor: (FirPropertySymbol, FirTypeScope) -> ProcessorAction ): ProcessorAction = doProcessDirectOverriddenCallables( - propertySymbol, processor, overriddenProperties, useSiteMemberScope, - FirTypeScope::processDirectOverriddenPropertiesWithBaseScope + propertySymbol, processor, enhancedToOriginalProperties, FirTypeScope::processDirectOverriddenPropertiesWithBaseScope ) + private fun > doProcessDirectOverriddenCallables( + callableSymbol: S, + processor: (S, FirTypeScope) -> ProcessorAction, + enhancedToOriginalMap: Map, + processDirectOverriddenCallables: FirTypeScope.(S, (S, FirTypeScope) -> ProcessorAction) -> ProcessorAction + ): ProcessorAction { + val unwrappedSymbol = if (callableSymbol.origin == FirDeclarationOrigin.RenamedForOverride) { + @Suppress("UNCHECKED_CAST") + callableSymbol.fir.initialSignatureAttr?.symbol as? S ?: callableSymbol + } else { + callableSymbol + } + val original = enhancedToOriginalMap[unwrappedSymbol] ?: return ProcessorAction.NONE + return useSiteMemberScope.processDirectOverriddenCallables(original, processor) + } + override fun getCallableNames(): Set { return useSiteMemberScope.getCallableNames() } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassStaticUseSiteScope.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassStaticUseSiteScope.kt index ffdd5ed8ca3..5fe55a60e7d 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassStaticUseSiteScope.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassStaticUseSiteScope.kt @@ -23,7 +23,7 @@ class JavaClassStaticUseSiteScope internal constructor( ) : FirContainingNamesAwareScope() { private val functions = hashMapOf>() private val properties = hashMapOf>>() - private val overrideChecker = JavaOverrideChecker(session, javaTypeParameterStack, baseScope = null, considerReturnTypeKinds = false) + private val overrideChecker = JavaOverrideChecker(session, javaTypeParameterStack, baseScopes = null, considerReturnTypeKinds = false) override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { functions.getOrPut(name) { diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt index 76f01c4c10a..6be2a67f184 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt @@ -5,65 +5,64 @@ package org.jetbrains.kotlin.fir.java.scopes +import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunctionCopy +import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl +import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter +import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass +import org.jetbrains.kotlin.fir.java.declarations.FirJavaMethod import org.jetbrains.kotlin.fir.java.declarations.buildJavaMethodCopy import org.jetbrains.kotlin.fir.java.declarations.buildJavaValueParameterCopy import org.jetbrains.kotlin.fir.java.symbols.FirJavaOverriddenSyntheticPropertySymbol import org.jetbrains.kotlin.fir.java.toConeKotlinTypeProbablyFlexible -import org.jetbrains.kotlin.fir.resolve.toSymbol +import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.scopes.* import org.jetbrains.kotlin.fir.scopes.impl.AbstractFirUseSiteMemberScope +import org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScopeContext.ResultOfIntersection +import org.jetbrains.kotlin.fir.scopes.impl.MembersByScope +import org.jetbrains.kotlin.fir.scopes.impl.similarFunctionsOrBothProperties import org.jetbrains.kotlin.fir.scopes.jvm.computeJvmDescriptor -import org.jetbrains.kotlin.fir.scopes.jvm.computeJvmSignature import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.isStatic import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.load.java.BuiltinSpecialProperties -import org.jetbrains.kotlin.load.java.JvmAbi -import org.jetbrains.kotlin.load.java.SpecialGenericSignatures +import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef +import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef +import org.jetbrains.kotlin.load.java.* import org.jetbrains.kotlin.load.java.SpecialGenericSignatures.Companion.ERASED_COLLECTION_PARAMETER_NAMES import org.jetbrains.kotlin.load.java.SpecialGenericSignatures.Companion.sameAsBuiltinMethodWithErasedValueParameters import org.jetbrains.kotlin.load.java.SpecialGenericSignatures.Companion.sameAsRenamedInJvmBuiltin -import org.jetbrains.kotlin.load.java.getPropertyNamesCandidatesByAccessorName import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.types.AbstractTypeChecker +import org.jetbrains.kotlin.utils.addIfNotNull +import org.jetbrains.kotlin.utils.addToStdlib.runIf class JavaClassUseSiteMemberScope( klass: FirJavaClass, session: FirSession, - superTypesScope: FirTypeScope, + superTypeScopes: List, declaredMemberScope: FirContainingNamesAwareScope ) : AbstractFirUseSiteMemberScope( klass.classId, session, - JavaOverrideChecker(session, klass.javaTypeParameterStack, superTypesScope, considerReturnTypeKinds = true), - superTypesScope, + JavaOverrideChecker(session, klass.javaTypeParameterStack, superTypeScopes, considerReturnTypeKinds = true), + superTypeScopes, + klass.defaultType(), declaredMemberScope ) { private val typeParameterStack = klass.javaTypeParameterStack - private val specialFunctions = hashMapOf>() private val syntheticPropertyByNameMap = hashMapOf() private val canUseSpecialGetters: Boolean by lazy { !klass.hasKotlinSuper(session) } - private val callableNamesCached by lazy(LazyThreadSafetyMode.PUBLICATION) { - declaredMemberScope.getCallableNames() + superTypesScope.getCallableNames() - } - - override fun getCallableNames(): Set = callableNamesCached - - override fun getClassifierNames(): Set { - return declaredMemberScope.getClassifierNames() + superTypesScope.getClassifierNames() - } - private fun generateSyntheticPropertySymbol( getterSymbol: FirNamedFunctionSymbol, setterSymbol: FirNamedFunctionSymbol?, @@ -102,7 +101,7 @@ class JavaClassUseSiteMemberScope( return minOf(a, b) } - override fun doProcessProperties(name: Name): Collection> { + override fun collectProperties(name: Name): Collection> { val fields = mutableSetOf>() val fieldNames = mutableSetOf() val result = mutableSetOf>() @@ -115,36 +114,49 @@ class JavaClassUseSiteMemberScope( result += variableSymbol } - val fromSupertypes = superTypesScope.getProperties(name) + /* + * From supertype we can get at most two results: + * 1. Set of properties with same name + * 2. Field from some java superclass (only one, if class have more than one superclass then we can choose + * just one field because this is incorrect code anyway) + */ + val fromSupertypes = supertypeScopeContext.collectCallables(name, FirScope::processPropertiesByName) - for (propertyFromSupertype in fromSupertypes) { - if (propertyFromSupertype is FirFieldSymbol) { - if (propertyFromSupertype.fir.name !in fieldNames) { - result += propertyFromSupertype - } - continue - } - if (propertyFromSupertype !is FirPropertySymbol) continue - val overrideInClass = - propertyFromSupertype.createOverridePropertyIfExists(declaredMemberScope, takeModalityFromGetter = true) - ?: propertyFromSupertype.createOverridePropertyIfExists(superTypesScope, takeModalityFromGetter = false) - when { - overrideInClass != null -> { - directOverriddenProperties.getOrPut(overrideInClass) { mutableListOf() }.add(propertyFromSupertype) - overrideByBase[propertyFromSupertype] = overrideInClass - result += overrideInClass - } - else -> result += propertyFromSupertype + val (fieldsFromSupertype, propertiesFromSupertypes) = fromSupertypes.partition { + it is ResultOfIntersection.SingleMember && it.chosenSymbol is FirFieldSymbol + } + + assert(fieldsFromSupertype.size in 0..1) + assert(propertiesFromSupertypes.size in 0..1) + + fieldsFromSupertype.firstOrNull()?.chosenSymbol?.let { fieldSymbol -> + require(fieldSymbol is FirFieldSymbol) + if (fieldSymbol.name !in fieldNames) { + result.addIfNotNull(fieldSymbol) } } + + @Suppress("UNCHECKED_CAST") + val overriddenProperty = propertiesFromSupertypes.firstOrNull() as ResultOfIntersection? ?: return result + + val overrideInClass = overriddenProperty.overriddenMembers.firstNotNullOfOrNull { (symbol, _) -> + symbol.createOverridePropertyIfExists(declaredMemberScope, takeModalityFromGetter = true) + ?: superTypeScopes.firstNotNullOfOrNull { scope -> + symbol.createOverridePropertyIfExists(scope, takeModalityFromGetter = false) + } + } + + val chosenSymbol = overrideInClass ?: overriddenProperty.chosenSymbol + directOverriddenProperties[chosenSymbol] = listOf(overriddenProperty) + overriddenProperty.overriddenMembers.forEach { overrideByBase[it.member] = overrideInClass } + result += chosenSymbol return result } - private fun FirVariableSymbol<*>.createOverridePropertyIfExists( + private fun FirPropertySymbol.createOverridePropertyIfExists( scope: FirScope, takeModalityFromGetter: Boolean ): FirPropertySymbol? { - if (this !is FirPropertySymbol) return null val getterSymbol = this.findGetterOverride(scope) ?: return null val setterSymbol = if (this.fir.isVar) @@ -204,8 +216,7 @@ class JavaClassUseSiteMemberScope( private fun FirPropertySymbol.getBuiltinSpecialPropertyGetterName(): Name? { var result: Name? = null - - superTypesScope.processOverriddenPropertiesAndSelf(this) { overridden -> + superTypeScopes.processOverriddenPropertiesAndSelf(this) { overridden -> val fqName = overridden.fir.containingClass()?.classId?.asSingleFqName()?.child(overridden.fir.name) BuiltinSpecialProperties.PROPERTY_FQ_NAME_TO_JVM_GETTER_NAME_MAP[fqName]?.let { name -> @@ -219,158 +230,375 @@ class JavaClassUseSiteMemberScope( return result } - override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { + // --------------------------------------------------------------------------------------------------------- + + override fun FirNamedFunctionSymbol.isVisibleInCurrentClass(): Boolean { val potentialPropertyNames = getPropertyNamesCandidatesByAccessorName(name) - - val renamedSpecialBuiltInName = SpecialGenericSignatures.getBuiltinFunctionNamesByJvmName(name) - - if (potentialPropertyNames.isEmpty() && renamedSpecialBuiltInName == null && - !name.sameAsBuiltinMethodWithErasedValueParameters && !name.sameAsRenamedInJvmBuiltin - ) { - return super.processFunctionsByName(name, processor) + val hasCorrespondingProperty = potentialPropertyNames.any { propertyName -> + getProperties(propertyName).any l@{ propertySymbol -> + // TODO: add magic overrides from LazyJavaClassMemberScope.isVisibleAsFunctionInCurrentClass + if (propertySymbol !is FirPropertySymbol) return@l false + propertySymbol.isOverriddenInClassBy(this) + } } + if (hasCorrespondingProperty) return false - val overriddenProperties = potentialPropertyNames.flatMap(this::getProperties).filterIsInstance() + return !doesOverrideRenamedBuiltins() && + !shouldBeVisibleAsOverrideOfBuiltInWithErasedValueParameters() && + !doesOverrideSuspendFunction() + } - specialFunctions.getOrPut(name) { - doProcessSpecialFunctions(name, overriddenProperties, renamedSpecialBuiltInName) - }.forEach { - processor(it) + private fun FirNamedFunctionSymbol.doesOverrideRenamedBuiltins(): Boolean { + // e.g. 'removeAt' or 'toInt' + val builtinName = SpecialGenericSignatures.getBuiltinFunctionNamesByJvmName(name) ?: return false + val builtinSpecialFromSuperTypes = supertypeScopeContext.collectMembersByScope(builtinName, FirScope::processFunctionsByName) + .flatMap { (scope, symbols) -> + symbols.filter { it.doesOverrideBuiltinWithDifferentJvmName(scope, session) } + } + if (builtinSpecialFromSuperTypes.isEmpty()) return false + + return builtinSpecialFromSuperTypes.any { + // Here `this` and `it` have different names but it's ok because override checker does not consider + // names of declarations at all + overrideChecker.isOverriddenFunction(this.fir, it.fir) } } - private fun doProcessSpecialFunctions( - name: Name, - overriddenProperties: List, - renamedSpecialBuiltInName: Name? - ): List { + /** + * Checks if function is a valid override of JDK analogue of built-in method with erased value parameters (e.g. Map.containsKey(k: K)) + * + * Examples: + * - boolean containsKey(Object key) -> true + * - boolean containsKey(K key) -> false // Wrong JDK method override, while it's a valid Kotlin built-in override + */ + private fun FirNamedFunctionSymbol.shouldBeVisibleAsOverrideOfBuiltInWithErasedValueParameters(): Boolean { + if (!name.sameAsBuiltinMethodWithErasedValueParameters) return false + val candidatesToOverride = supertypeScopeContext.collectMembersByScope(name, FirScope::processFunctionsByName) + .flatMap { (scope, symbols) -> + symbols.mapNotNull { + BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(it, scope) + } + } + + val jvmDescriptor = fir.computeJvmDescriptor() + return candidatesToOverride.any { candidate -> + candidate.fir.computeJvmDescriptor() == jvmDescriptor && this.hasErasedParameters() + } + } + + private fun FirNamedFunctionSymbol.doesOverrideSuspendFunction(): Boolean { + val suspendView = createSuspendView() ?: return false + return superTypeScopes.any { scope -> + scope.getFunctions(name).any { it.isSuspend && overrideChecker.isOverriddenFunction(suspendView, it.fir) } + } + } + + private fun FirNamedFunctionSymbol.createSuspendView(): FirSimpleFunction? { + val continuationParameter = fir.valueParameters.lastOrNull() ?: return null + val continuationParameterType = continuationParameter + .returnTypeRef + .coneTypeSafe() + ?.lowerBoundIfFlexible() as? ConeClassLikeType + ?: return null + if (continuationParameterType.lookupTag.classId.asSingleFqName() != StandardNames.CONTINUATION_INTERFACE_FQ_NAME) return null + + return buildSimpleFunctionCopy(fir) { + valueParameters.clear() + valueParameters.addAll(fir.valueParameters.dropLast(1)) + returnTypeRef = buildResolvedTypeRef { + type = continuationParameterType.typeArguments[0].type ?: return null + } + (status as FirDeclarationStatusImpl).isSuspend = true + symbol = FirNamedFunctionSymbol(callableId) + } + } + + // --------------------------------------------------------------------------------------------------------- + + override fun collectFunctions(name: Name): Collection { val result = mutableListOf() + collectDeclaredFunctions(name, result) + val explicitlyDeclaredFunctions = result.toSet() - declaredMemberScope.processFunctionsByName(name) { functionSymbol -> - if (functionSymbol.isStatic) return@processFunctionsByName - if (overriddenProperties.none { it.isOverriddenInClassBy(functionSymbol) } && - !functionSymbol.doesOverrideRenamedBuiltins(renamedSpecialBuiltInName) && - !functionSymbol.shouldBeVisibleAsOverrideOfBuiltInWithErasedValueParameters() - ) { - result += functionSymbol + val functionsWithScopeFromSupertypes = supertypeScopeContext.collectMembersByScope(name, FirScope::processFunctionsByName) + + if ( + !name.sameAsRenamedInJvmBuiltin && + !name.sameAsBuiltinMethodWithErasedValueParameters && + functionsWithScopeFromSupertypes.all { it.second.none { functionSymbol -> functionSymbol.isSuspend } } + ) { + // Simple fast path in case of name is not suspicious (i.e. name is not one of builtins that have different signature in Java) + super.collectFunctionsFromSupertypes(name, result, explicitlyDeclaredFunctions) + return result + } + + processSpecialFunctions(name, explicitlyDeclaredFunctions, functionsWithScopeFromSupertypes, result) + return result.toSet() + } + + private fun processSpecialFunctions( + naturalName: Name, + explicitlyDeclaredFunctionsWithNaturalName: Collection, + functionsFromSupertypesWithNaturalName: MembersByScope, // candidates for override + destination: MutableCollection + ) { + val resultsOfIntersectionToSaveInCache = mutableListOf>() + val list = supertypeScopeContext.collectCallablesImpl(functionsFromSupertypesWithNaturalName) + for (resultOfIntersectionWithNaturalName in list) { + val someSymbolWithNaturalNameFromSuperType = resultOfIntersectionWithNaturalName.extractSomeSymbolFromSuperType() + val explicitlyDeclaredFunctionWithNaturalName = explicitlyDeclaredFunctionsWithNaturalName.firstOrNull { + overrideChecker.isOverriddenFunction(it, someSymbolWithNaturalNameFromSuperType) + } + val jvmName = resultOfIntersectionWithNaturalName.overriddenMembers.firstNotNullOfOrNull { + it.member.getJvmMethodNameIfSpecial(it.baseScope, session) + } + if (jvmName != null) { + processOverridesForFunctionsWithDifferentJvmName( + jvmName, + someSymbolWithNaturalNameFromSuperType, + explicitlyDeclaredFunctionWithNaturalName, + naturalName, + resultOfIntersectionWithNaturalName, + destination, + resultsOfIntersectionToSaveInCache + ) + continue + } + + if (processOverridesForFunctionsWithErasedValueParameter( + resultOfIntersectionWithNaturalName.overriddenMembers, + naturalName, + explicitlyDeclaredFunctionsWithNaturalName, + destination, + resultOfIntersectionWithNaturalName, + explicitlyDeclaredFunctionWithNaturalName + ) + ) continue + + // regular rules + when (explicitlyDeclaredFunctionWithNaturalName) { + null -> { + destination += resultOfIntersectionWithNaturalName.chosenSymbol + resultsOfIntersectionToSaveInCache += resultOfIntersectionWithNaturalName + } + else -> { + destination += explicitlyDeclaredFunctionWithNaturalName + directOverriddenFunctions[explicitlyDeclaredFunctionWithNaturalName] = listOf(resultOfIntersectionWithNaturalName) + for (overriddenMember in resultOfIntersectionWithNaturalName.overriddenMembers) { + overrideByBase[overriddenMember.member] = explicitlyDeclaredFunctionWithNaturalName + } + } + } + } + functionsFromSupertypes[naturalName] = resultsOfIntersectionToSaveInCache + } + + private fun processOverridesForFunctionsWithErasedValueParameter( + overriddenMembers: List>, + naturalName: Name, + explicitlyDeclaredFunctionsWithNaturalName: Collection, + destination: MutableCollection, + resultOfIntersectionWithNaturalName: ResultOfIntersection, + explicitlyDeclaredFunctionWithNaturalName: FirNamedFunctionSymbol? + ): Boolean { + val overriddenMemberWithErasedValueParameters = overriddenMembers.firstOrNull { + BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(it) != null + }?.member ?: return false + + val unwrappedSubstitutionOverride = overriddenMemberWithErasedValueParameters.fir.originalForSubstitutionOverride + ?: overriddenMemberWithErasedValueParameters.fir + + val functionFromSupertypeWithErasedParameterType = unwrappedSubstitutionOverride + .initialSignatureAttr + ?.symbol as? FirNamedFunctionSymbol + ?: unwrappedSubstitutionOverride.symbol + val originalDeclaredFunction = declaredMemberScope.getFunctions(naturalName).firstOrNull { + it.hasSameJvmDescriptorButDoesNotOverride(functionFromSupertypeWithErasedParameterType) + } ?: return false + val renamedDeclaredFunction = buildJavaMethodCopy(originalDeclaredFunction.fir as FirJavaMethod) { + name = naturalName + symbol = FirNamedFunctionSymbol(originalDeclaredFunction.callableId) + this.valueParameters.clear() + originalDeclaredFunction.fir.valueParameters.zip(overriddenMemberWithErasedValueParameters.fir.valueParameters) + .mapTo(this.valueParameters) { (overrideParameter, parameterFromSupertype) -> + buildJavaValueParameterCopy(overrideParameter) { + this@buildJavaValueParameterCopy.returnTypeRef = parameterFromSupertype.returnTypeRef + } + } + }.apply { + initialSignatureAttr = originalDeclaredFunction.fir + }.symbol + + val hasAccidentalOverrideWithDeclaredFunction = explicitlyDeclaredFunctionsWithNaturalName.any { + overrideChecker.isOverriddenFunction( + renamedDeclaredFunction, + it + ) + } + if (!hasAccidentalOverrideWithDeclaredFunction) { + destination += renamedDeclaredFunction + directOverriddenFunctions[renamedDeclaredFunction] = listOf(resultOfIntersectionWithNaturalName) + for (overriddenMember in overriddenMembers) { + overrideByBase[overriddenMember.member] = renamedDeclaredFunction + } + if (explicitlyDeclaredFunctionWithNaturalName != null) { + destination += explicitlyDeclaredFunctionWithNaturalName + } + return true + } + return false + } + + private fun FirNamedFunctionSymbol.hasSameJvmDescriptorButDoesNotOverride( + builtinWithErasedParameters: FirNamedFunctionSymbol + ): Boolean { + return fir.computeJvmDescriptor(includeReturnType = false) == builtinWithErasedParameters.fir.computeJvmDescriptor(includeReturnType = false) + && overrideChecker.isOverriddenFunction(this, builtinWithErasedParameters) + } + + private fun processOverridesForFunctionsWithDifferentJvmName( + jvmName: Name, + someSymbolWithNaturalNameFromSuperType: FirNamedFunctionSymbol, + explicitlyDeclaredFunctionWithNaturalName: FirNamedFunctionSymbol?, + naturalName: Name, + resultOfIntersectionWithNaturalName: ResultOfIntersection, + destination: MutableCollection, + resultsOfIntersectionToSaveInCache: MutableList> + ) { + /* + * name: toByte + * + * 1. find declared byteValue (a) + * 2. find toByte in supertypes (b) + * 3. find byteValue in supertypes (c) + * 4. create triples of (a), (b), (c) which are same overrides + * 5. for each triple: + * 6. if (a) is empty: + * 6.1. create renamed copies of (c): (c') + * 6.2. create result of intersection for (b) and (c'), save direct overrides + * 7. if (a) is not empty: + * 7.1 create renamed copies of (c): (c') + * 7.2 save direct overrides + */ + val overriddenMembers = resultOfIntersectionWithNaturalName.overriddenMembers + val explicitlyDeclaredFunctionWithBuiltinJvmName = declaredMemberScope.getFunctions(jvmName).firstOrNull { + overrideChecker.isOverriddenFunction(it, someSymbolWithNaturalNameFromSuperType) + } + val functionsFromSupertypesWithBuiltinJvmName = supertypeScopeContext.collectFunctions(jvmName).firstOrNull { + overrideChecker.similarFunctionsOrBothProperties( + it.extractSomeSymbolFromSuperType(), + someSymbolWithNaturalNameFromSuperType + ) + } + + val declaredFunction = explicitlyDeclaredFunctionWithNaturalName ?: explicitlyDeclaredFunctionWithBuiltinJvmName?.let { + val original = it.fir as FirJavaMethod + buildJavaMethodCopy(original) { + name = naturalName + symbol = FirNamedFunctionSymbol(it.callableId.copy(callableName = naturalName)) + status = original.status.copy(isOperator = true) + }.apply { + initialSignatureAttr = original + }.symbol + } + + val renamedFunctionsFromSupertypes = functionsFromSupertypesWithBuiltinJvmName?.overriddenMembers?.map { + val renamedFunction = buildSimpleFunctionCopy(it.member.fir) { + name = naturalName + symbol = FirNamedFunctionSymbol(it.member.callableId.copy(callableName = naturalName)) + origin = FirDeclarationOrigin.RenamedForOverride + }.apply { + initialSignatureAttr = it.member.fir + } + it.baseScope to listOf(renamedFunction.symbol) + } + + val resultsOfIntersection = when (renamedFunctionsFromSupertypes) { + null -> listOf(resultOfIntersectionWithNaturalName) + else -> { + val membersByScope = buildList { + overriddenMembers.mapTo(this) { it.baseScope to listOf(it.member) } + addAll(renamedFunctionsFromSupertypes) + } + supertypeScopeContext.collectCallablesImpl(membersByScope) } } - addOverriddenSpecialMethods(name, result, declaredMemberScope) - - val overrideCandidates = result.toMutableSet() - - superTypesScope.processFunctionsByName(name) { functionSymbol -> - val overriddenBy = functionSymbol.getOverridden(overrideCandidates) - if (overriddenBy == null && overriddenProperties.none { it.isOverriddenInClassBy(functionSymbol) }) { - result += functionSymbol + if (declaredFunction != null) { + destination += declaredFunction + directOverriddenFunctions[declaredFunction] = resultsOfIntersection + for (resultOfIntersection in resultsOfIntersection) { + for (overriddenMember in resultOfIntersection.overriddenMembers) { + overrideByBase[overriddenMember.member] = declaredFunction + } } + } else { + for (resultOfIntersection in resultsOfIntersection) { + destination += resultOfIntersection.chosenSymbol + } + resultsOfIntersectionToSaveInCache += resultsOfIntersection } - - return result } private fun FirPropertySymbol.isOverriddenInClassBy(functionSymbol: FirNamedFunctionSymbol): Boolean { - val fir = fir as? FirSyntheticProperty ?: return false - - if (fir.getter.delegate.symbol == functionSymbol || fir.setter?.delegate?.symbol == functionSymbol) return true + val accessorDescriptors = when (val fir = fir) { + is FirSyntheticProperty -> { + if (fir.getter.delegate.symbol == functionSymbol || fir.setter?.delegate?.symbol == functionSymbol) return true + val getterDescriptor = fir.getter.delegate.computeJvmDescriptor(includeReturnType = false) + val setterDescriptor = fir.setter?.delegate?.computeJvmDescriptor(includeReturnType = false) + listOf(getterDescriptor to setterDescriptor) + } + else -> { + val getterNames = + listOfNotNull(getJvmMethodNameIfSpecial(this@JavaClassUseSiteMemberScope, session)) + .takeIf { it.isNotEmpty() } + ?: possibleGetMethodNames(fir.name) + getterNames.map { getterName -> + val getterDescriptor = fir.computeJvmDescriptorForGetter( + customName = getterName.identifier, + includeReturnType = false + ) + val setterDescriptor = runIf(isVar) { + fir.computeJvmDescriptorForSetter( + customName = setMethodName(getterName).identifier, + includeReturnType = false + ) + } + getterDescriptor to setterDescriptor + } + } + } val currentJvmDescriptor = functionSymbol.fir.computeJvmDescriptor(includeReturnType = false) - val getterJvmDescriptor = fir.getter.delegate.computeJvmDescriptor(includeReturnType = false) - val setterJvmDescriptor = fir.setter?.delegate?.computeJvmDescriptor(includeReturnType = false) - return currentJvmDescriptor == getterJvmDescriptor || currentJvmDescriptor == setterJvmDescriptor - } - - private fun addOverriddenSpecialMethods( - name: Name, - result: MutableList, - scope: FirScope, - ) { - superTypesScope.processFunctionsByName(name) { fromSupertype -> - obtainOverrideForBuiltinWithDifferentJvmName(fromSupertype, scope, name)?.let { - directOverriddenFunctions[it] = listOf(fromSupertype) - overrideByBase[fromSupertype] = it - result += it - } - - obtainOverrideForBuiltInWithErasedValueParametersInJava(fromSupertype, scope)?.let { - directOverriddenFunctions[it] = listOf(fromSupertype) - overrideByBase[fromSupertype] = it - result += it - } - } - } - - private fun obtainOverrideForBuiltinWithDifferentJvmName( - symbol: FirNamedFunctionSymbol, - scope: FirScope, - name: Name, - ): FirNamedFunctionSymbol? { - val overriddenBuiltin = symbol.getOverriddenBuiltinWithDifferentJvmName() ?: return null - - //if (unrelated) method with special name is already defined, we don't add renamed method at all - //otherwise we get methods ambiguity - val alreadyDefined = declaredMemberScope.getFunctions(name).any { declaredSymbol -> - overrideChecker.isOverriddenFunction(declaredSymbol.fir, symbol.fir) - } - if (alreadyDefined) return null - - val nameInJava = - SpecialGenericSignatures.SIGNATURE_TO_JVM_REPRESENTATION_NAME[overriddenBuiltin.fir.computeJvmSignature() ?: return null] - ?: return null - - for (candidateSymbol in scope.getFunctions(nameInJava)) { - val candidateFir = candidateSymbol.fir - val renamedCopy = buildJavaMethodCopy(candidateFir) { - this.name = name - this.symbol = FirNamedFunctionSymbol(CallableId(candidateFir.symbol.callableId.classId!!, name)) - this.status = candidateFir.status.copy(isOperator = symbol.isOperator) - }.apply { - initialSignatureAttr = candidateFir - } - - if (overrideChecker.isOverriddenFunction(renamedCopy, overriddenBuiltin.fir)) { - return renamedCopy.symbol + val getterDescriptorMatches = accessorDescriptors.any { (getterJvmDescriptor, _) -> + val gettersAreSame = currentJvmDescriptor == getterJvmDescriptor && run { + val propertyType = this.fir.returnTypeRef.probablyJavaTypeRefToConeType() + val functionType = functionSymbol.fir.returnTypeRef.probablyJavaTypeRefToConeType() + functionType.isSubtypeOf(propertyType, session) } + gettersAreSame } - return null + if (getterDescriptorMatches && this.isVal) return true + + val setterDescriptorMatches = accessorDescriptors.any { (_, setterJvmDescriptor) -> + currentJvmDescriptor == setterJvmDescriptor + } + + if (!setterDescriptorMatches) return false + + val (getterOverride, setterOverride) = when (getterDescriptorMatches) { + true -> functionSymbol to findSetterOverride(this@JavaClassUseSiteMemberScope) + false -> findGetterOverride(this@JavaClassUseSiteMemberScope) to functionSymbol + } + return getterOverride?.modality == setterOverride?.modality } - private fun obtainOverrideForBuiltInWithErasedValueParametersInJava( - symbol: FirNamedFunctionSymbol, - scope: FirScope, - ): FirNamedFunctionSymbol? { - val overriddenBuiltin = - symbol.getOverriddenBuiltinFunctionWithErasedValueParametersInJava() - ?: return null - - return createOverrideForBuiltinFunctionWithErasedParameterIfNeeded(symbol, overriddenBuiltin, scope) - } - - private fun createOverrideForBuiltinFunctionWithErasedParameterIfNeeded( - fromSupertype: FirNamedFunctionSymbol, - overriddenBuiltin: FirNamedFunctionSymbol, - scope: FirScope, - ): FirNamedFunctionSymbol? { - return scope.getFunctions(overriddenBuiltin.fir.name).firstOrNull { candidateOverride -> - candidateOverride.fir.computeJvmDescriptor() == overriddenBuiltin.fir.computeJvmDescriptor() && - candidateOverride.hasErasedParameters() - }?.let { override -> - buildJavaMethodCopy(override.fir) { - this.valueParameters.clear() - override.fir.valueParameters.zip(fromSupertype.fir.valueParameters) - .mapTo(this.valueParameters) { (overrideParameter, parameterFromSupertype) -> - buildJavaValueParameterCopy(overrideParameter) { - this@buildJavaValueParameterCopy.returnTypeRef = parameterFromSupertype.returnTypeRef - } - } - - symbol = FirNamedFunctionSymbol(override.callableId) - }.apply { - initialSignatureAttr = override.fir - }.symbol + private fun FirTypeRef.probablyJavaTypeRefToConeType(): ConeKotlinType { + return when (this) { + is FirJavaTypeRef -> toConeKotlinTypeProbablyFlexible(session, typeParameterStack) + else -> coneType } } @@ -392,22 +620,32 @@ class JavaClassUseSiteMemberScope( return upperBound.classId == StandardClassIds.Any } - private fun FirNamedFunctionSymbol.doesOverrideRenamedBuiltins(renamedSpecialBuiltInName: Name?): Boolean { - if (renamedSpecialBuiltInName == null) return false - // e.g. 'removeAt' or 'toInt' - val builtinSpecialFromSuperTypes = - getFunctionsFromSupertypes(renamedSpecialBuiltInName).filter { it.getOverriddenBuiltinWithDifferentJvmName() != null } - if (builtinSpecialFromSuperTypes.isEmpty()) return false - - val currentJvmDescriptor = fir.computeJvmDescriptor(customName = renamedSpecialBuiltInName.asString()) - - return builtinSpecialFromSuperTypes.any { builtinSpecial -> - builtinSpecial.fir.computeJvmDescriptor() == currentJvmDescriptor - } + private fun FirProperty.computeJvmDescriptorForGetter(customName: String? = null, includeReturnType: Boolean = false): String { + getter?.computeJvmDescriptor(customName, includeReturnType)?.let { return it } + val syntheticGetter = FirDefaultPropertyGetter( + source = null, + moduleData = moduleData, + origin = origin, + propertyTypeRef = returnTypeRef, + visibility = status.visibility, + propertySymbol = symbol, + modality = status.modality ?: Modality.FINAL + ) + return syntheticGetter.computeJvmDescriptor(customName, includeReturnType) } - private fun FirFunction.computeJvmSignature(): String? { - return computeJvmSignature { it.toConeKotlinTypeProbablyFlexible(session, typeParameterStack) } + private fun FirProperty.computeJvmDescriptorForSetter(customName: String? = null, includeReturnType: Boolean = false): String { + setter?.computeJvmDescriptor(customName, includeReturnType)?.let { return it } + val syntheticSetter = FirDefaultPropertySetter( + source = null, + moduleData = moduleData, + origin = origin, + propertyTypeRef = returnTypeRef, + visibility = status.visibility, + propertySymbol = symbol, + modality = status.modality ?: Modality.FINAL + ) + return syntheticSetter.computeJvmDescriptor(customName, includeReturnType) } private fun FirFunction.computeJvmDescriptor(customName: String? = null, includeReturnType: Boolean = false): String { @@ -419,65 +657,6 @@ class JavaClassUseSiteMemberScope( } } - private fun getFunctionsFromSupertypes(name: Name): List { - val result = mutableListOf() - superTypesScope.processFunctionsByName(name) { - result += it - } - - return result - } - - private fun FirNamedFunctionSymbol.getOverriddenBuiltinWithDifferentJvmName(): FirNamedFunctionSymbol? { - var result: FirNamedFunctionSymbol? = null - - if (SpecialGenericSignatures.SIGNATURE_TO_JVM_REPRESENTATION_NAME.containsKey(this.fir.computeJvmSignature())) { - return this - } - - superTypesScope.processOverriddenFunctions(this) { - if (!it.isFromBuiltInClass(session)) return@processOverriddenFunctions ProcessorAction.NEXT - if (SpecialGenericSignatures.SIGNATURE_TO_JVM_REPRESENTATION_NAME.containsKey(it.fir.computeJvmSignature())) { - result = it - return@processOverriddenFunctions ProcessorAction.STOP - } - - ProcessorAction.NEXT - } - - return result - } - - private fun FirNamedFunctionSymbol.shouldBeVisibleAsOverrideOfBuiltInWithErasedValueParameters(): Boolean { - val name = fir.name - if (!name.sameAsBuiltinMethodWithErasedValueParameters) return false - val candidatesToOverride = - getFunctionsFromSupertypes(name).mapNotNull { - it.getOverriddenBuiltinFunctionWithErasedValueParametersInJava() - } - - val jvmDescriptor = fir.computeJvmDescriptor() - - return candidatesToOverride.any { candidate -> - candidate.fir.computeJvmDescriptor() == jvmDescriptor && this.hasErasedParameters() - } - } - - private fun FirNamedFunctionSymbol.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(): FirNamedFunctionSymbol? { - var result: FirNamedFunctionSymbol? = null - - superTypesScope.processOverriddenFunctionsAndSelf(this) { - if (it.fir.computeJvmSignature() in SpecialGenericSignatures.ERASED_VALUE_PARAMETERS_SIGNATURES) { - result = it - return@processOverriddenFunctionsAndSelf ProcessorAction.STOP - } - - ProcessorAction.NEXT - } - - return result - } - /** * Checks if class has any kotlin super-types apart from builtins and interfaces */ @@ -504,6 +683,3 @@ class JavaClassUseSiteMemberScope( return "Java use site scope of $classId" } } - -private fun FirCallableSymbol<*>.isFromBuiltInClass(session: FirSession) = - dispatchReceiverClassOrNull()?.toSymbol(session)?.fir?.origin == FirDeclarationOrigin.BuiltIns diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaOverrideChecker.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaOverrideChecker.kt index 15c73a5ed8e..075ba4de17a 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaOverrideChecker.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaOverrideChecker.kt @@ -28,7 +28,7 @@ import org.jetbrains.kotlin.name.StandardClassIds class JavaOverrideChecker internal constructor( private val session: FirSession, private val javaTypeParameterStack: JavaTypeParameterStack, - private val baseScope: FirTypeScope?, + private val baseScopes: List?, private val considerReturnTypeKinds: Boolean, ) : FirAbstractOverrideChecker() { private val context: ConeTypeContext = session.typeContext @@ -121,7 +121,7 @@ class JavaOverrideChecker internal constructor( var foundNonPrimitiveOverridden = false - baseScope?.processOverriddenFunctions(symbol) { + baseScopes?.processOverriddenFunctions(symbol) { val type = it.fir.returnTypeRef.toConeKotlinTypeProbablyFlexible(session, javaTypeParameterStack) if (!type.isPrimitiveInJava(isReturnType = true)) { foundNonPrimitiveOverridden = true diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaScopeUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaScopeUtils.kt new file mode 100644 index 00000000000..8babc598987 --- /dev/null +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaScopeUtils.kt @@ -0,0 +1,187 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.java.scopes + +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin +import org.jetbrains.kotlin.fir.dispatchReceiverClassOrNull +import org.jetbrains.kotlin.fir.java.scopes.ClassicBuiltinSpecialProperties.getBuiltinSpecialPropertyGetterName +import org.jetbrains.kotlin.fir.resolve.toSymbol +import org.jetbrains.kotlin.fir.scopes.* +import org.jetbrains.kotlin.fir.scopes.jvm.computeJvmSignature +import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol +import org.jetbrains.kotlin.load.java.BuiltinSpecialProperties +import org.jetbrains.kotlin.load.java.SpecialGenericSignatures +import org.jetbrains.kotlin.load.java.SpecialGenericSignatures.Companion.ERASED_VALUE_PARAMETERS_SHORT_NAMES +import org.jetbrains.kotlin.load.java.SpecialGenericSignatures.Companion.ERASED_VALUE_PARAMETERS_SIGNATURES +import org.jetbrains.kotlin.load.java.SpecialGenericSignatures.Companion.REMOVE_AT_NAME_AND_SIGNATURE +import org.jetbrains.kotlin.load.java.SpecialGenericSignatures.Companion.SIGNATURE_TO_JVM_REPRESENTATION_NAME +import org.jetbrains.kotlin.name.Name + +fun FirCallableSymbol<*>.doesOverrideBuiltinWithDifferentJvmName(containingScope: FirTypeScope, session: FirSession): Boolean { + return getOverriddenBuiltinWithDifferentJvmName(containingScope, session) != null +} + +fun > T.getOverriddenBuiltinWithDifferentJvmName(containingScope: FirTypeScope, session: FirSession): T? { + if ( + name !in SpecialGenericSignatures.ORIGINAL_SHORT_NAMES && name !in BuiltinSpecialProperties.SPECIAL_SHORT_NAMES + ) return null + + @Suppress("UNCHECKED_CAST") + return when (this) { + is FirNamedFunctionSymbol -> firstOverriddenFunction(containingScope) { + BuiltinMethodsWithDifferentJvmName.isBuiltinFunctionWithDifferentNameInJvm(it, session) + } as T? + + is FirPropertySymbol -> ClassicBuiltinSpecialProperties.findBuiltinSpecialPropertyFqName(this, containingScope) as T? + + else -> null + } +} + +fun FirCallableSymbol<*>.getJvmMethodNameIfSpecial(containingScope: FirTypeScope, session: FirSession): Name? { + val overriddenBuiltin = getOverriddenBuiltinWithDifferentJvmName(containingScope, session) + ?: return null + val name = when (overriddenBuiltin) { + is FirPropertySymbol -> overriddenBuiltin.getBuiltinSpecialPropertyGetterName(containingScope) + is FirNamedFunctionSymbol -> BuiltinMethodsWithDifferentJvmName.getJvmName(overriddenBuiltin)?.asString() + else -> null + } ?: return null + return Name.identifier(name) +} + + +object BuiltinMethodsWithSpecialGenericSignature { + private val FirNamedFunctionSymbol.hasErasedValueParametersInJava: Boolean + get() = fir.computeJvmSignature() in ERASED_VALUE_PARAMETERS_SIGNATURES + + fun getOverriddenBuiltinFunctionWithErasedValueParametersInJava( + memberWithBaseScope: MemberWithBaseScope + ): FirNamedFunctionSymbol? { + return getOverriddenBuiltinFunctionWithErasedValueParametersInJava(memberWithBaseScope.member, memberWithBaseScope.baseScope) + } + + + @JvmStatic + fun getOverriddenBuiltinFunctionWithErasedValueParametersInJava( + functionSymbol: FirNamedFunctionSymbol, + containingScope: FirTypeScope + ): FirNamedFunctionSymbol? { + if (!functionSymbol.name.sameAsBuiltinMethodWithErasedValueParameters) return null + return functionSymbol.firstOverriddenFunction(containingScope) { it.hasErasedValueParametersInJava } + } + + val Name.sameAsBuiltinMethodWithErasedValueParameters: Boolean + get() = this in ERASED_VALUE_PARAMETERS_SHORT_NAMES + + fun FirNamedFunctionSymbol.isBuiltinWithSpecialDescriptorInJvm(containingScope: FirTypeScope, session: FirSession): Boolean { + if (!isFromBuiltinClass(session)) return false + return getSpecialSignatureInfo(containingScope)?.isObjectReplacedWithTypeParameter ?: false || + doesOverrideBuiltinWithDifferentJvmName(containingScope, session) + } + + @JvmStatic + fun FirNamedFunctionSymbol.getSpecialSignatureInfo(containingScope: FirTypeScope): SpecialGenericSignatures.SpecialSignatureInfo? { + if (name !in ERASED_VALUE_PARAMETERS_SHORT_NAMES) return null + + val builtinSignature = firstOverriddenFunction(containingScope) { it.hasErasedValueParametersInJava } + ?.fir + ?.computeJvmSignature() + ?: return null + return SpecialGenericSignatures.getSpecialSignatureInfo(builtinSignature) + } +} + +object BuiltinMethodsWithDifferentJvmName { + fun getJvmName(functionSymbol: FirNamedFunctionSymbol): Name? { + return SIGNATURE_TO_JVM_REPRESENTATION_NAME[functionSymbol.fir.computeJvmSignature() ?: return null] + } + + fun isBuiltinFunctionWithDifferentNameInJvm(functionSymbol: FirNamedFunctionSymbol, session: FirSession): Boolean { + return functionSymbol.isFromBuiltinClass(session) && SIGNATURE_TO_JVM_REPRESENTATION_NAME.containsKey(functionSymbol.fir.computeJvmSignature()) + } + + val FirNamedFunctionSymbol.isRemoveAtByIndex: Boolean + get() = name.asString() == "removeAt" && fir.computeJvmSignature() == REMOVE_AT_NAME_AND_SIGNATURE.signature +} + +object ClassicBuiltinSpecialProperties { + fun FirCallableSymbol<*>.getBuiltinSpecialPropertyGetterName(containingScope: FirTypeScope): String? { + val overridden = findBuiltinSpecialPropertyFqName(this, containingScope) ?: return null + return BuiltinSpecialProperties.PROPERTY_FQ_NAME_TO_JVM_GETTER_NAME_MAP[overridden.callableId.asSingleFqName()]?.asString() + } + + fun findBuiltinSpecialPropertyFqName(symbol: FirCallableSymbol<*>, containingScope: FirTypeScope): FirCallableSymbol<*>? { + if (symbol.name !in BuiltinSpecialProperties.SPECIAL_SHORT_NAMES) return null + + return symbol.hasBuiltinSpecialPropertyFqNameImpl(containingScope) + } + + private fun FirCallableSymbol<*>.hasBuiltinSpecialPropertyFqNameImpl(containingScope: FirTypeScope): FirCallableSymbol<*>? { + if (callableId.asSingleFqName() in BuiltinSpecialProperties.SPECIAL_FQ_NAMES && valueParametersAreEmpty()) return this + // if (!KotlinBuiltIns.isBuiltIn(this)) return false + var result: FirCallableSymbol<*>? = null + + fun process(overridden: FirCallableSymbol<*>, scope: FirTypeScope): ProcessorAction { + val foundSymbol = findBuiltinSpecialPropertyFqName(overridden, scope) + return if (foundSymbol != null) { + result = foundSymbol + ProcessorAction.STOP + } else { + ProcessorAction.NEXT + } + } + + when (this) { + is FirNamedFunctionSymbol -> containingScope.processDirectOverriddenFunctionsWithBaseScope(this) { overridden, scope -> + process(overridden, scope) + } + + is FirPropertySymbol -> containingScope.processDirectOverriddenPropertiesWithBaseScope(this) { overridden, scope -> + process(overridden, scope) + } + } + + return result + } + + private fun FirCallableSymbol<*>.valueParametersAreEmpty(): Boolean { + return when (this) { + is FirNamedFunctionSymbol -> fir.valueParameters.isEmpty() + else -> true + } + } +} + +private fun FirCallableSymbol<*>.isFromBuiltinClass(session: FirSession): Boolean { + return dispatchReceiverClassOrNull()?.toSymbol(session)?.fir?.origin == FirDeclarationOrigin.BuiltIns +} + +private fun FirNamedFunctionSymbol.firstOverriddenFunction( + containingScope: FirTypeScope, + predicate: (FirNamedFunctionSymbol) -> Boolean +): FirNamedFunctionSymbol? { + return firstOverriddenCallable(containingScope, FirTypeScope::processOverriddenFunctionsAndSelf, predicate) +} + +private inline fun > T.firstOverriddenCallable( + containingScope: FirTypeScope, + processFunction: FirTypeScope.(T, (T) -> ProcessorAction) -> ProcessorAction, + noinline predicate: (T) -> Boolean, +): T? { + var result: T? = null + containingScope.processFunction(this) { symbol -> + if (predicate(symbol)) { + result = symbol + ProcessorAction.STOP + } else { + ProcessorAction.NEXT + } + } + return result +} diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/FirKotlinScopeProvider.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/FirKotlinScopeProvider.kt index 61e076db428..6e88f59a511 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/FirKotlinScopeProvider.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/FirKotlinScopeProvider.kt @@ -55,12 +55,9 @@ class FirKotlinScopeProvider( useSiteSuperType.scopeForSupertype(useSiteSession, scopeSession, klass) } FirClassUseSiteMemberScope( - klass.classId, + klass, useSiteSession, - FirTypeIntersectionScope.prepareIntersectionScope( - useSiteSession, FirStandardOverrideChecker(useSiteSession), scopes, - klass.defaultType(), - ), + scopes, decoratedDeclaredMemberScope, ) } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/FirOverrideChecker.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/FirOverrideChecker.kt index 29aa64e682c..3f75c189efa 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/FirOverrideChecker.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/FirOverrideChecker.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.scopes import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol interface FirOverrideChecker { fun isOverriddenFunction( @@ -20,3 +21,8 @@ interface FirOverrideChecker { baseDeclaration: FirProperty ): Boolean } + +fun FirOverrideChecker.isOverriddenFunction( + overrideCandidate: FirNamedFunctionSymbol, + baseDeclaration: FirNamedFunctionSymbol +): Boolean = isOverriddenFunction(overrideCandidate.fir, baseDeclaration.fir) diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirOverrideScope.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirOverrideScope.kt index f23ce25a89d..1f6cac0e67e 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirOverrideScope.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirOverrideScope.kt @@ -56,3 +56,10 @@ internal fun FirOverrideChecker.similarFunctionsOrBothProperties( else -> error("Unknown fir callable type: $overrideCandidate, $baseDeclaration") } } + +fun FirOverrideChecker.similarFunctionsOrBothProperties( + overrideCandidate: FirCallableSymbol<*>, + baseDeclaration: FirCallableSymbol<*> +): Boolean { + return similarFunctionsOrBothProperties(overrideCandidate.fir, baseDeclaration.fir) +} diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirUseSiteMemberScope.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirUseSiteMemberScope.kt index 5ffa71596a5..e949936b9a6 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirUseSiteMemberScope.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirUseSiteMemberScope.kt @@ -7,11 +7,10 @@ package org.jetbrains.kotlin.fir.scopes.impl import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor -import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope -import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker -import org.jetbrains.kotlin.fir.scopes.FirTypeScope -import org.jetbrains.kotlin.fir.scopes.ProcessorAction +import org.jetbrains.kotlin.fir.scopes.* +import org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScopeContext.ResultOfIntersection import org.jetbrains.kotlin.fir.symbols.impl.* +import org.jetbrains.kotlin.fir.types.ConeSimpleKotlinType import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name @@ -19,100 +18,207 @@ abstract class AbstractFirUseSiteMemberScope( val classId: ClassId, session: FirSession, overrideChecker: FirOverrideChecker, - val superTypesScope: FirTypeScope, + protected val superTypeScopes: List, + dispatchReceiverType: ConeSimpleKotlinType, protected val declaredMemberScope: FirContainingNamesAwareScope ) : AbstractFirOverrideScope(session, overrideChecker) { + protected val supertypeScopeContext = FirTypeIntersectionScopeContext(session, overrideChecker, superTypeScopes, dispatchReceiverType) - private val functions = hashMapOf>() - private val properties = hashMapOf>>() - val directOverriddenFunctions = hashMapOf>() - protected val directOverriddenProperties = hashMapOf>() + private val functions: MutableMap> = hashMapOf() + + private val properties: MutableMap>> = hashMapOf() + protected val directOverriddenFunctions: MutableMap>> = + hashMapOf() + protected val directOverriddenProperties: MutableMap>> = hashMapOf() + + protected val functionsFromSupertypes: MutableMap>> = mutableMapOf() + protected val propertiesFromSupertypes: MutableMap>> = mutableMapOf() + protected val fieldsFromSupertypes: MutableMap> = mutableMapOf() + + private val absentClassifiersFromSupertypes = mutableSetOf() private val callableNamesCached by lazy(LazyThreadSafetyMode.PUBLICATION) { - declaredMemberScope.getCallableNames() + superTypesScope.getCallableNames() + buildSet { + addAll(declaredMemberScope.getCallableNames()) + superTypeScopes.flatMapTo(this) { it.getCallableNames() } + } } - override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { + private val classifierNamesCached by lazy(LazyThreadSafetyMode.PUBLICATION) { + buildSet { + addAll(declaredMemberScope.getClassifierNames()) + superTypeScopes.flatMapTo(this) { it.getClassifierNames() } + } + } + + final override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { functions.getOrPut(name) { - doProcessFunctions(name) + collectFunctions(name) }.forEach { processor(it) } } - private fun doProcessFunctions( + protected open fun collectFunctions( name: Name ): Collection = mutableListOf().apply { - val overrideCandidates = mutableSetOf>() + collectDeclaredFunctions(name, this) + val explicitlyDeclaredFunctions = this.toSet() + collectFunctionsFromSupertypes(name, this, explicitlyDeclaredFunctions) + } + + protected fun collectDeclaredFunctions(name: Name, destination: MutableList) { declaredMemberScope.processFunctionsByName(name) { symbol -> if (symbol.isStatic) return@processFunctionsByName - val directOverridden = computeDirectOverridden(symbol) - this@AbstractFirUseSiteMemberScope.directOverriddenFunctions[symbol] = directOverridden - overrideCandidates += symbol - add(symbol) + if (!symbol.isVisibleInCurrentClass()) return@processFunctionsByName + val directOverridden = computeDirectOverriddenForDeclaredFunction(symbol) + directOverriddenFunctions[symbol] = directOverridden + destination += symbol } + } - superTypesScope.processFunctionsByName(name) { - val overriddenBy = it.getOverridden(overrideCandidates) + protected abstract fun FirNamedFunctionSymbol.isVisibleInCurrentClass(): Boolean + + protected fun collectFunctionsFromSupertypes( + name: Name, + destination: MutableList, + explicitlyDeclaredFunctions: Set + ) { + for (chosenSymbolFromSupertype in getFunctionsFromSupertypesByName(name)) { + val superSymbol = chosenSymbolFromSupertype.extractSomeSymbolFromSuperType() + if (!superSymbol.isVisibleInCurrentClass()) continue + val overriddenBy = superSymbol.getOverridden(explicitlyDeclaredFunctions) if (overriddenBy == null) { - add(it) + destination += chosenSymbolFromSupertype.chosenSymbol } } } + private fun getFunctionsFromSupertypesByName(name: Name): List> { + return functionsFromSupertypes.getOrPut(name) { + supertypeScopeContext.collectCallables(name, FirScope::processFunctionsByName) + } + } + final override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { properties.getOrPut(name) { - doProcessProperties(name) + collectProperties(name) }.forEach { processor(it) } } - protected abstract fun doProcessProperties(name: Name): Collection> + protected abstract fun collectProperties(name: Name): Collection> - private fun computeDirectOverridden(symbol: FirNamedFunctionSymbol): Collection { - val result = mutableListOf() - val firSimpleFunction = symbol.fir - superTypesScope.processFunctionsByName(symbol.callableId.callableName) { superSymbol -> - if (overrideChecker.isOverriddenFunction(firSimpleFunction, superSymbol.fir)) { - result.add(superSymbol) + private fun computeDirectOverriddenForDeclaredFunction(declaredFunctionSymbol: FirNamedFunctionSymbol): List> { + val result = mutableListOf>() + val declaredFunction = declaredFunctionSymbol.fir + for (resultOfIntersection in getFunctionsFromSupertypesByName(declaredFunctionSymbol.name)) { + val symbolFromSupertype = resultOfIntersection.extractSomeSymbolFromSuperType() + if (overrideChecker.isOverriddenFunction(declaredFunction, symbolFromSupertype.fir)) { + result.add(resultOfIntersection) } } - return result } + protected fun > ResultOfIntersection.extractSomeSymbolFromSuperType(): D { + return if (this.isIntersectionOverride()) { + /* + * we don't want to create intersection override if some declared function actually overrides some functions + * from supertypes, so instead of intersection override symbol we check actual symbol from supertype + * + * TODO: is it enough to check only one function? + */ + firstMember + } else { + chosenSymbol + } + } + override fun processDirectOverriddenFunctionsWithBaseScope( functionSymbol: FirNamedFunctionSymbol, processor: (FirNamedFunctionSymbol, FirTypeScope) -> ProcessorAction - ): ProcessorAction = - //directOverriddenFunctions might be not filled for functionSymbol if it is not from processFunctionsByName call - doProcessDirectOverriddenCallables( - functionSymbol, processor, directOverriddenFunctions, superTypesScope, + ): ProcessorAction { + return processDirectOverriddenMembersWithBaseScopeImpl( + directOverriddenFunctions, + functionsFromSupertypes, + functionSymbol, + processor, FirTypeScope::processDirectOverriddenFunctionsWithBaseScope ) + } override fun processDirectOverriddenPropertiesWithBaseScope( propertySymbol: FirPropertySymbol, processor: (FirPropertySymbol, FirTypeScope) -> ProcessorAction - ): ProcessorAction = - doProcessDirectOverriddenCallables( - propertySymbol, processor, directOverriddenProperties, superTypesScope, + ): ProcessorAction { + return processDirectOverriddenMembersWithBaseScopeImpl( + directOverriddenProperties, + propertiesFromSupertypes, + propertySymbol, + processor, FirTypeScope::processDirectOverriddenPropertiesWithBaseScope ) + } + + private fun > processDirectOverriddenMembersWithBaseScopeImpl( + directOverriddenMap: Map>>, + callablesFromSupertypes: Map>>, + callableSymbol: D, + processor: (D, FirTypeScope) -> ProcessorAction, + processDirectOverriddenCallables: FirTypeScope.(D, (D, FirTypeScope) -> ProcessorAction) -> ProcessorAction + ): ProcessorAction { + when (val directOverridden = directOverriddenMap[callableSymbol]) { + null -> { + val resultOfIntersection = callablesFromSupertypes[callableSymbol.name] + ?.firstOrNull { it.chosenSymbol == callableSymbol } + ?: return ProcessorAction.NONE + if (resultOfIntersection.isIntersectionOverride()) { + for ((overridden, baseScope) in resultOfIntersection.overriddenMembers) { + if (!processor(overridden, baseScope)) return ProcessorAction.STOP + } + return ProcessorAction.NONE + } else { + return resultOfIntersection.containingScope + ?.processDirectOverriddenCallables(callableSymbol, processor) + ?: ProcessorAction.NONE + } + } + else -> { + for (resultOfIntersection in directOverridden) { + for ((overridden, baseScope) in resultOfIntersection.overriddenMembers) { + if (!processor(overridden, baseScope)) return ProcessorAction.STOP + } + } + return ProcessorAction.NONE + } + } + } override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { declaredMemberScope.processClassifiersByNameWithSubstitution(name, processor) - superTypesScope.processClassifiersByNameWithSubstitution(name, processor) + + if (name in absentClassifiersFromSupertypes) return + val classifiers = supertypeScopeContext.collectClassifiers(name) + if (classifiers.isEmpty()) { + absentClassifiersFromSupertypes += name + return + } + for ((symbol, substitution) in classifiers) { + processor(symbol, substitution) + } } override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) { declaredMemberScope.processDeclaredConstructors(processor) } - override fun getCallableNames(): Set = callableNamesCached + override fun getCallableNames(): Set { + return callableNamesCached + } override fun getClassifierNames(): Set { - return declaredMemberScope.getClassifierNames() + superTypesScope.getClassifierNames() + return classifierNamesCached } } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassUseSiteMemberScope.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassUseSiteMemberScope.kt index 3d5180084a3..a7b6fe457b9 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassUseSiteMemberScope.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassUseSiteMemberScope.kt @@ -7,53 +7,86 @@ package org.jetbrains.kotlin.fir.scopes.impl import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirClass -import org.jetbrains.kotlin.fir.declarations.FirProperty +import org.jetbrains.kotlin.fir.declarations.utils.classId +import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope import org.jetbrains.kotlin.fir.scopes.FirTypeScope -import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol -import org.jetbrains.kotlin.fir.symbols.impl.isStatic -import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.name.Name class FirClassUseSiteMemberScope( - classId: ClassId, + klass: FirClass, session: FirSession, - superTypesScope: FirTypeScope, + superTypeScopes: List, declaredMemberScope: FirContainingNamesAwareScope -) : AbstractFirUseSiteMemberScope(classId, session, FirStandardOverrideChecker(session), superTypesScope, declaredMemberScope) { - - override fun doProcessProperties(name: Name): Collection> { - val seen = mutableSetOf>() - val result = mutableSetOf>() - declaredMemberScope.processPropertiesByName(name) l@{ - if (it.isStatic) return@l - if (it is FirPropertySymbol) { - val directOverridden = computeDirectOverridden(it.fir) - this@FirClassUseSiteMemberScope.directOverriddenProperties[it] = directOverridden +) : AbstractFirUseSiteMemberScope( + klass.classId, + session, + FirStandardOverrideChecker(session), + superTypeScopes, + klass.defaultType(), + declaredMemberScope +) { + override fun collectProperties(name: Name): Collection> { + return buildList { + val explicitlyDeclaredProperties = mutableSetOf>() + declaredMemberScope.processPropertiesByName(name) { symbol -> + if (symbol.isStatic) return@processPropertiesByName + if (symbol is FirPropertySymbol) { + val directOverridden = computeDirectOverriddenForDeclaredProperty(symbol) + directOverriddenProperties[symbol] = directOverridden + } + explicitlyDeclaredProperties += symbol + add(symbol) } - seen += it - result += it - } - superTypesScope.processPropertiesByName(name) { - val overriddenBy = it.getOverridden(seen) - if (overriddenBy == null) { - result += it + + val (properties, fields) = getPropertiesAndFieldsFromSupertypesByName(name) + for (propertyFromSupertype in properties) { + val superSymbol = propertyFromSupertype.extractSomeSymbolFromSuperType() + val overriddenBy = superSymbol.getOverridden(explicitlyDeclaredProperties) + if (overriddenBy == null) { + add(propertyFromSupertype.chosenSymbol) + } + } + addAll(fields) + } + } + + private fun computeDirectOverriddenForDeclaredProperty(declaredPropertySymbol: FirPropertySymbol): List> { + val result = mutableListOf>() + val declaredProperty = declaredPropertySymbol.fir + for (resultOfIntersection in getPropertiesAndFieldsFromSupertypesByName(declaredPropertySymbol.name).first) { + val symbolFromSupertype = resultOfIntersection.extractSomeSymbolFromSuperType() + if (overrideChecker.isOverriddenProperty(declaredProperty, symbolFromSupertype.fir)) { + result.add(resultOfIntersection) } } return result } - private fun computeDirectOverridden(property: FirProperty): MutableList { - val result = mutableListOf() - superTypesScope.processPropertiesByName(property.name) l@{ superSymbol -> - if (superSymbol !is FirPropertySymbol) return@l - if (overrideChecker.isOverriddenProperty(property, superSymbol.fir)) { - result.add(superSymbol) + private fun getPropertiesAndFieldsFromSupertypesByName(name: Name): Pair>, List> { + propertiesFromSupertypes[name]?.let { + return it to fieldsFromSupertypes.getValue(name) + } + + val fields = mutableListOf() + val properties = supertypeScopeContext.collectCallables(name) { propertyName, processor -> + processPropertiesByName(propertyName) { + when (it) { + is FirPropertySymbol -> processor(it) + is FirFieldSymbol -> fields += it + else -> {} + } } } - return result + propertiesFromSupertypes[name] = properties + fieldsFromSupertypes[name] = fields + return properties to fields + } + + override fun FirNamedFunctionSymbol.isVisibleInCurrentClass(): Boolean { + return true } override fun toString(): String { diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirOverrideUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirOverrideUtils.kt new file mode 100644 index 00000000000..21624c62525 --- /dev/null +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirOverrideUtils.kt @@ -0,0 +1,63 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.scopes.impl + +import org.jetbrains.kotlin.fir.PrivateForInline +import org.jetbrains.kotlin.fir.scopes.FirTypeScope +import org.jetbrains.kotlin.fir.scopes.MemberWithBaseScope +import org.jetbrains.kotlin.fir.scopes.ProcessOverriddenWithBaseScope +import org.jetbrains.kotlin.fir.scopes.ProcessorAction +import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol + +fun filterOutOverriddenFunctions(extractedOverridden: Collection>): Collection> { + return filterOutOverridden(extractedOverridden, FirTypeScope::processDirectOverriddenFunctionsWithBaseScope) +} + +fun filterOutOverriddenProperties(extractedOverridden: Collection>): Collection> { + return filterOutOverridden(extractedOverridden, FirTypeScope::processDirectOverriddenPropertiesWithBaseScope) +} + +@OptIn(PrivateForInline::class) +inline fun > filterOutOverridden( + extractedOverridden: Collection>, + processAllOverridden: ProcessOverriddenWithBaseScope, +): Collection> { + return extractedOverridden.filter { overridden1 -> + extractedOverridden.none { overridden2 -> + overridden1 !== overridden2 && overrides( + overridden2, + overridden1, + processAllOverridden + ) + } + } +} + +// Whether f overrides g +@PrivateForInline +inline fun > overrides( + f: MemberWithBaseScope, + g: MemberWithBaseScope, + processAllOverridden: ProcessOverriddenWithBaseScope, +): Boolean { + val (fMember, fScope) = f + val (gMember) = g + + var result = false + + fScope.processAllOverridden(fMember) { overridden, _ -> + if (overridden == gMember) { + result = true + ProcessorAction.STOP + } else { + ProcessorAction.NEXT + } + } + + return result +} diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt index 75993269c82..61f8895c430 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt @@ -7,10 +7,7 @@ package org.jetbrains.kotlin.fir.scopes.impl import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor -import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker -import org.jetbrains.kotlin.fir.scopes.FirScope -import org.jetbrains.kotlin.fir.scopes.FirTypeScope -import org.jetbrains.kotlin.fir.scopes.ProcessorAction +import org.jetbrains.kotlin.fir.scopes.* import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.ConeSimpleKotlinType import org.jetbrains.kotlin.name.Name @@ -58,9 +55,10 @@ class FirTypeIntersectionScope private constructor( return } - for ((chosenSymbol, overriddenMembers) in callablesWithOverridden) { - overriddenSymbols[chosenSymbol] = overriddenMembers - processor(chosenSymbol) + for (resultOfIntersection in callablesWithOverridden) { + val symbol = resultOfIntersection.chosenSymbol + overriddenSymbols[symbol] = resultOfIntersection.overriddenMembers + processor(symbol) } } 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 0133bdb26ae..21195af1fac 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 @@ -17,16 +17,21 @@ import org.jetbrains.kotlin.fir.declarations.utils.visibility import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.scopes.* import org.jetbrains.kotlin.fir.scopes.impl.FirIntersectionOverrideStorage.ContextForIntersectionOverrideConstruction +import org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScopeContext.ResultOfIntersection import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.AbstractTypeChecker +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.contract + +typealias MembersByScope = List>> class FirTypeIntersectionScopeContext( val session: FirSession, private val overrideChecker: FirOverrideChecker, - @property:PrivateForInline val scopes: List, + val scopes: List, private val dispatchReceiverType: ConeSimpleKotlinType, ) { private val typeCheckerState = session.typeContext.newTypeCheckerState( @@ -37,14 +42,40 @@ class FirTypeIntersectionScopeContext( val intersectionOverrides: FirCache, MemberWithBaseScope>, ContextForIntersectionOverrideConstruction<*>> = session.intersectionOverrideStorage.cacheByScope.getValue(dispatchReceiverType).intersectionOverrides - data class ResultOfIntersection>( - val chosenSymbol: D, - val overriddenMembers: List> + sealed class ResultOfIntersection>( + val overriddenMembers: List>, + val containingScope: FirTypeScope? ) { - constructor( - chosenSymbol: D, - overriddenMember: MemberWithBaseScope - ) : this(chosenSymbol, listOf(overriddenMember)) + abstract val chosenSymbol: D + + class SingleMember>( + override val chosenSymbol: D, + overriddenMembers: List>, + containingScope: FirTypeScope? + ) : ResultOfIntersection(overriddenMembers, containingScope) { + constructor( + chosenSymbol: D, + overriddenMember: MemberWithBaseScope + ) : this(chosenSymbol, listOf(overriddenMember), overriddenMember.baseScope) + } + + class NonTrivial>( + private val intersectionOverridesCache: FirCache, MemberWithBaseScope>, ContextForIntersectionOverrideConstruction<*>>, + private val context: ContextForIntersectionOverrideConstruction, + overriddenMembers: List>, + containingScope: FirTypeScope? + ) : ResultOfIntersection(overriddenMembers, containingScope) { + override val chosenSymbol: D by lazy { + @Suppress("UNCHECKED_CAST") + intersectionOverridesCache.getValue( + context.mostSpecific, + context + ).member as D + } + + val firstMember: D + get() = context.extractedOverrides.first().member + } } @OptIn(PrivateForInline::class) @@ -65,12 +96,16 @@ class FirTypeIntersectionScopeContext( return result } + fun collectFunctions(name: Name): List> { + return collectCallables(name, FirScope::processFunctionsByName) + } + @OptIn(PrivateForInline::class) - inline fun > collectCallables( + inline fun > collectMembersByScope( name: Name, processCallables: FirScope.(Name, (D) -> Unit) -> Unit - ): List> { - val membersByScope = scopes.mapNotNull { scope -> + ): MembersByScope { + return scopes.mapNotNull { scope -> val resultForScope = mutableListOf() scope.processCallables(name) { if (it !is FirConstructorSymbol) { @@ -82,19 +117,25 @@ class FirTypeIntersectionScopeContext( scope to it } } - return collectCallablesImpl(membersByScope) } - @PrivateForInline + @OptIn(PrivateForInline::class) + inline fun > collectCallables( + name: Name, + processCallables: FirScope.(Name, (D) -> Unit) -> Unit + ): List> { + return collectCallablesImpl(collectMembersByScope(name, processCallables)) + } + fun > collectCallablesImpl( - membersByScope: List>> + membersByScope: List>> ): List> { if (membersByScope.isEmpty()) { return emptyList() } membersByScope.singleOrNull()?.let { (scope, members) -> - return members.map { ResultOfIntersection(it, MemberWithBaseScope(it, scope)) } + return members.map { ResultOfIntersection.SingleMember(it, MemberWithBaseScope(it, scope)) } } val allMembersWithScope = membersByScope.flatMapTo(linkedSetOf()) { (scope, members) -> @@ -112,31 +153,32 @@ class FirTypeIntersectionScopeContext( val baseMembersForIntersection = extractedOverrides.calcBaseMembersForIntersectionOverride() if (baseMembersForIntersection.size > 1) { val (mostSpecific, scopeForMostSpecific) = selectMostSpecificMember(baseMembersForIntersection) - val intersectionOverride = intersectionOverrides.getValue( + val intersectionOverrideContext = ContextForIntersectionOverrideConstruction( mostSpecific, - ContextForIntersectionOverrideConstruction( - this, - extractedOverrides, - scopeForMostSpecific - ) + this, + extractedOverrides, + scopeForMostSpecific + ) + result += ResultOfIntersection.NonTrivial( + intersectionOverrides, + intersectionOverrideContext, + extractedOverrides, + containingScope = null ) - @Suppress("UNCHECKED_CAST") - result += ResultOfIntersection(intersectionOverride.member as D, extractedOverrides) } else { - val mostSpecific = baseMembersForIntersection.single().member - result += ResultOfIntersection(mostSpecific, extractedOverrides) + val (mostSpecific, containingScope) = baseMembersForIntersection.single() + result += ResultOfIntersection.SingleMember(mostSpecific, extractedOverrides, containingScope) } } if (allMembersWithScope.isNotEmpty()) { - val single = allMembersWithScope.single().member - result += ResultOfIntersection(single, allMembersWithScope.toList()) + val (single, containingScope) = allMembersWithScope.single() + result += ResultOfIntersection.SingleMember(single, allMembersWithScope.toList(), containingScope) } return result } - fun > createIntersectionOverride( extractedOverrides: List>, mostSpecific: D, @@ -384,45 +426,6 @@ class FirTypeIntersectionScopeContext( } } - - private fun > filterOutOverridden( - extractedOverridden: Collection>, - processAllOverridden: ProcessOverriddenWithBaseScope, - ): Collection> { - return extractedOverridden.filter { overridden1 -> - extractedOverridden.none { overridden2 -> - overridden1 !== overridden2 && overrides( - overridden2, - overridden1, - processAllOverridden - ) - } - } - } - - // Whether f overrides g - private fun > overrides( - f: MemberWithBaseScope, - g: MemberWithBaseScope, - processAllOverridden: ProcessOverriddenWithBaseScope, - ): Boolean { - val (fMember, fScope) = f - val (gMember) = g - - var result = false - - fScope.processAllOverridden(fMember) { overridden, _ -> - if (overridden == gMember) { - result = true - ProcessorAction.STOP - } else { - ProcessorAction.NEXT - } - } - - return result - } - private fun > chooseIntersectionVisibility( extractedOverrides: Collection> ): Visibility { @@ -492,19 +495,6 @@ class FirTypeIntersectionScopeContext( } } -class MemberWithBaseScope>(val member: D, val baseScope: FirTypeScope) { - operator fun component1() = member - operator fun component2() = baseScope - - override fun equals(other: Any?): Boolean { - return other is MemberWithBaseScope<*> && member == other.member - } - - override fun hashCode(): Int { - return member.hashCode() - } -} - private fun > D.withScope(baseScope: FirTypeScope) = MemberWithBaseScope(this, baseScope) class FirIntersectionOverrideStorage(val session: FirSession) : FirSessionComponent { @@ -513,12 +503,13 @@ class FirIntersectionOverrideStorage(val session: FirSession) : FirSessionCompon class CacheForScope(cachesFactory: FirCachesFactory) { val intersectionOverrides: FirCache, MemberWithBaseScope>, ContextForIntersectionOverrideConstruction<*>> = cachesFactory.createCache { mostSpecific, context -> - val (intersectionScope, extractedOverrides, scopeForMostSpecific) = context + val (_, intersectionScope, extractedOverrides, scopeForMostSpecific) = context intersectionScope.createIntersectionOverride(extractedOverrides, mostSpecific, scopeForMostSpecific) } } data class ContextForIntersectionOverrideConstruction>( + val mostSpecific: D, val intersectionContext: FirTypeIntersectionScopeContext, val extractedOverrides: List>, val scopeForMostSpecific: FirTypeScope @@ -529,3 +520,11 @@ class FirIntersectionOverrideStorage(val session: FirSession) : FirSessionCompon } private val FirSession.intersectionOverrideStorage: FirIntersectionOverrideStorage by FirSession.sessionComponentAccessor() + +@OptIn(ExperimentalContracts::class) +fun > ResultOfIntersection.isIntersectionOverride(): Boolean { + contract { + returns(true) implies (this@isIntersectionOverride is ResultOfIntersection.NonTrivial) + } + return this is ResultOfIntersection.NonTrivial +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt index 4fd22705353..cd61d735cfa 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt @@ -487,6 +487,7 @@ fun FirFunction.getAsForbiddenNamedArgumentsTarget(session: FirSession): Forbidd } } FirDeclarationOrigin.Synthetic -> null + FirDeclarationOrigin.RenamedForOverride -> null is FirDeclarationOrigin.Plugin -> null // TODO: figure out what to do with plugin generated functions } } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationOrigin.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationOrigin.kt index d8530fa2b28..ab739c3da96 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationOrigin.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationOrigin.kt @@ -18,6 +18,7 @@ sealed class FirDeclarationOrigin(private val displayName: String? = null, val f object SubstitutionOverride : FirDeclarationOrigin(fromSupertypes = true) object IntersectionOverride : FirDeclarationOrigin(fromSupertypes = true) object Delegated : FirDeclarationOrigin() + object RenamedForOverride : FirDeclarationOrigin() class Plugin(val key: FirPluginKey) : FirDeclarationOrigin(displayName = "Plugin[$key]", generated = true) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirScope.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirScope.kt index a28902171de..c534e9778bd 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirScope.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirScope.kt @@ -60,7 +60,7 @@ fun FirTypeScope.processOverriddenFunctionsAndSelf( ): ProcessorAction { if (!processor(functionSymbol)) return ProcessorAction.STOP - return processOverriddenFunctions(functionSymbol, processor) + return processOverriddenFunctions(functionSymbol, processor = processor) } fun FirTypeScope.processOverriddenPropertiesAndSelf( @@ -69,7 +69,15 @@ fun FirTypeScope.processOverriddenPropertiesAndSelf( ): ProcessorAction { if (!processor(propertySymbol)) return ProcessorAction.STOP - return processOverriddenProperties(propertySymbol, processor) + return processOverriddenProperties(propertySymbol, processor = processor) +} + +fun List.processOverriddenPropertiesAndSelf( + propertySymbol: FirPropertySymbol, + processor: (FirPropertySymbol) -> ProcessorAction +) { + if (!processor(propertySymbol)) return + processOverriddenProperties(propertySymbol, processor) } enum class ProcessorAction { diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirTypeScope.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirTypeScope.kt index 7bf8513c03f..c40bf9bbd69 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirTypeScope.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirTypeScope.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.fir.scopes import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration -import org.jetbrains.kotlin.fir.isIntersectionOverride import org.jetbrains.kotlin.fir.originalForSubstitutionOverride import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionCallableSymbol @@ -63,27 +62,18 @@ abstract class FirTypeScope : FirContainingNamesAwareScope() { return "Empty scope" } } +} - protected companion object { - fun > doProcessDirectOverriddenCallables( - callableSymbol: S, - processor: (S, FirTypeScope) -> ProcessorAction, - directOverriddenMap: Map>, - baseScope: FirTypeScope, - processDirectOverriddenCallables: FirTypeScope.(S, (S, FirTypeScope) -> ProcessorAction) -> ProcessorAction - ): ProcessorAction { - val directOverridden = directOverriddenMap[callableSymbol]?.takeIf { it.isNotEmpty() } - ?: return baseScope.processDirectOverriddenCallables(callableSymbol, processor) +class MemberWithBaseScope>(val member: D, val baseScope: FirTypeScope) { + operator fun component1() = member + operator fun component2() = baseScope - for (overridden in directOverridden) { - if (overridden.fir.isIntersectionOverride) { - if (!baseScope.processDirectOverriddenCallables(overridden, processor)) return ProcessorAction.STOP - } - if (!processor(overridden, baseScope)) return ProcessorAction.STOP - } + override fun equals(other: Any?): Boolean { + return other is MemberWithBaseScope<*> && member == other.member + } - return ProcessorAction.NONE - } + override fun hashCode(): Int { + return member.hashCode() } } @@ -100,6 +90,18 @@ fun FirTypeScope.processOverriddenFunctions( mutableSetOf() ) +private fun FirTypeScope.processOverriddenFunctionsWithVisited( + functionSymbol: FirNamedFunctionSymbol, + visited: MutableSet>, + processor: (FirNamedFunctionSymbol) -> ProcessorAction +): ProcessorAction = + doProcessAllOverriddenCallables( + functionSymbol, + processor, + FirTypeScope::processDirectOverriddenFunctionsWithBaseScope, + visited + ) + fun FirTypeScope.processOverriddenProperties( propertySymbol: FirPropertySymbol, processor: (FirPropertySymbol) -> ProcessorAction @@ -111,13 +113,45 @@ fun FirTypeScope.processOverriddenProperties( mutableSetOf() ) +private fun FirTypeScope.processOverriddenPropertiesWithVisited( + propertySymbol: FirPropertySymbol, + visited: MutableSet> = mutableSetOf(), + processor: (FirPropertySymbol) -> ProcessorAction +): ProcessorAction = + doProcessAllOverriddenCallables( + propertySymbol, + processor, + FirTypeScope::processDirectOverriddenPropertiesWithBaseScope, + visited + ) + +fun List.processOverriddenFunctions( + functionSymbol: FirNamedFunctionSymbol, + processor: (FirNamedFunctionSymbol) -> ProcessorAction +) { + val visited = mutableSetOf>() + for (scope in this) { + if (!scope.processOverriddenFunctionsWithVisited(functionSymbol, visited, processor)) return + } +} + +fun List.processOverriddenProperties( + propertySymbol: FirPropertySymbol, + processor: (FirPropertySymbol) -> ProcessorAction +) { + val visited = mutableSetOf>() + for (scope in this) { + if (!scope.processOverriddenPropertiesWithVisited(propertySymbol, visited, processor)) return + } +} + private fun > FirTypeScope.doProcessAllOverriddenCallables( callableSymbol: S, processor: (S, FirTypeScope) -> ProcessorAction, processDirectOverriddenCallablesWithBaseScope: FirTypeScope.(S, (S, FirTypeScope) -> ProcessorAction) -> ProcessorAction, - visited: MutableSet + visited: MutableSet> ): ProcessorAction { - if (!visited.add(callableSymbol)) return ProcessorAction.NONE + if (!visited.add(this to callableSymbol)) return ProcessorAction.NONE return processDirectOverriddenCallablesWithBaseScope(callableSymbol) { overridden, baseScope -> if (!processor(overridden, baseScope)) return@processDirectOverriddenCallablesWithBaseScope ProcessorAction.STOP @@ -129,7 +163,7 @@ private fun > FirTypeScope.doProcessAllOverriddenCallab callableSymbol: S, processor: (S) -> ProcessorAction, processDirectOverriddenCallablesWithBaseScope: FirTypeScope.(S, (S, FirTypeScope) -> ProcessorAction) -> ProcessorAction, - visited: MutableSet + visited: MutableSet> ): ProcessorAction = doProcessAllOverriddenCallables(callableSymbol, { s, _ -> processor(s) }, processDirectOverriddenCallablesWithBaseScope, visited) @@ -157,6 +191,41 @@ fun FirTypeScope.getDirectOverriddenMembers( else -> emptyList() } +fun FirTypeScope.getDirectOverriddenMembersWithBaseScope(member: FirCallableSymbol<*>): List>> { + return when (member) { + is FirNamedFunctionSymbol -> getDirectOverriddenFunctionsWithBaseScope(member) + is FirPropertySymbol -> getDirectOverriddenPropertiesWithBaseScope(member) + else -> emptyList() + } +} + +fun FirTypeScope.getDirectOverriddenFunctionsWithBaseScope( + function: FirNamedFunctionSymbol, +): List> { + val overriddenFunctions = mutableSetOf>() + + processDirectOverriddenFunctionsWithBaseScope(function) { symbol, baseScope -> + + overriddenFunctions += MemberWithBaseScope(symbol, baseScope) + ProcessorAction.NEXT + } + + return overriddenFunctions.toList() +} + +fun FirTypeScope.getDirectOverriddenPropertiesWithBaseScope( + property: FirPropertySymbol, +): List> { + val overriddenProperties = mutableSetOf>() + + processDirectOverriddenPropertiesWithBaseScope(property) { symbol, baseScope -> + overriddenProperties += MemberWithBaseScope(symbol, baseScope) + ProcessorAction.NEXT + } + + return overriddenProperties.toList() +} + fun FirTypeScope.getDirectOverriddenFunctions( function: FirNamedFunctionSymbol, unwrapIntersectionAndSubstitutionOverride: Boolean = false, diff --git a/compiler/testData/codegen/box/collections/irrelevantImplCharSequence.kt b/compiler/testData/codegen/box/collections/irrelevantImplCharSequence.kt index 9d8b7407c58..202ba6dde12 100644 --- a/compiler/testData/codegen/box/collections/irrelevantImplCharSequence.kt +++ b/compiler/testData/codegen/box/collections/irrelevantImplCharSequence.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR -// FIR status: wrong ABSTRACT_MEMBER_NOT_IMPLEMENTED, probably provoked by override mapping error // TARGET_BACKEND: JVM // FILE: J.java diff --git a/compiler/testData/codegen/box/collections/irrelevantImplMutableListSubstitution.kt b/compiler/testData/codegen/box/collections/irrelevantImplMutableListSubstitution.kt index aad68bfadcd..feb09779ff7 100644 --- a/compiler/testData/codegen/box/collections/irrelevantImplMutableListSubstitution.kt +++ b/compiler/testData/codegen/box/collections/irrelevantImplMutableListSubstitution.kt @@ -1,5 +1,5 @@ // IGNORE_BACKEND_FIR: JVM_IR -// FIR status: wrong ABSTRACT_MEMBER_NOT_IMPLEMENTED, probably provoked by override mapping error +// FIR status: wrong CONFLICTING_INHERITED_JVM_DECLARATIONS, probably provoked by override mapping error // TARGET_BACKEND: JVM // FILE: J.java diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/collectionStringImpl.fir.kt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/collectionStringImpl.fir.kt deleted file mode 100644 index 5a749cb4da4..00000000000 --- a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/collectionStringImpl.fir.kt +++ /dev/null @@ -1,85 +0,0 @@ -// FILE: CollectionStringImpl.java - -import java.util.Collection; -import java.util.Iterator; - -public class CollectionStringImpl implements Collection { - @Override - public int size() { - return 0; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public boolean contains(Object o) { - return false; - } - - - @Override - public Iterator iterator() { - return null; - } - - - @Override - public Object[] toArray() { - return new Object[0]; - } - - - @Override - public T[] toArray(T[] a) { - return null; - } - - @Override - public boolean add(String s) { - return false; - } - - @Override - public boolean remove(Object o) { - return false; - } - - @Override - public boolean containsAll(Collection c) { - return false; - } - - @Override - public boolean addAll(Collection c) { - return false; - } - - @Override - public boolean removeAll(Collection c) { - return false; - } - - @Override - public boolean retainAll(Collection c) { - return false; - } - - @Override - public void clear() { - - } - - public boolean contains(String o) { - return true; - } -} - -// FILE: main.kt - -fun test(x: CollectionStringImpl) { - x.contains("") - (x as Collection).contains("") -} diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/collectionStringImpl.kt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/collectionStringImpl.kt index 08b86b53d45..13e04293af0 100644 --- a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/collectionStringImpl.kt +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/collectionStringImpl.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // FILE: CollectionStringImpl.java import java.util.Collection; diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAndOverload.fir.kt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAndOverload.fir.kt index f13b2046c8d..b2c06bdd860 100644 --- a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAndOverload.fir.kt +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAndOverload.fir.kt @@ -12,10 +12,10 @@ abstract class KA : A() { } fun foo(a: A, ka: KA) { - a.contains("") - a.contains(1) - "" in a - 1 in a + a.contains("") + a.contains(1) + "" in a + 1 in a ka.contains("") ka.contains(1) diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequence.fir.kt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequence.fir.kt deleted file mode 100644 index 57c713db1dd..00000000000 --- a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequence.fir.kt +++ /dev/null @@ -1,25 +0,0 @@ -// FILE: AImpl.java - -abstract public class AImpl { - public char charAt(int index) { - return '1'; - } - - public final int length() { return 1; } -} - -// FILE: A.java -public class A extends AImpl implements CharSequence { - public CharSequence subSequence(int start, int end) { - return null; - } -} - -// FILE: X.kt -class X : A() - -fun main() { - val x = X() - x[0] - x.length -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequence.kt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequence.kt index e544b2be1c8..1bafe6c0180 100644 --- a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequence.kt +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequence.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // FILE: AImpl.java abstract public class AImpl { diff --git a/compiler/testData/diagnostics/tests/override/FakeOverrideModality3.fir.kt b/compiler/testData/diagnostics/tests/override/FakeOverrideModality3.fir.kt new file mode 100644 index 00000000000..9aca1afc65f --- /dev/null +++ b/compiler/testData/diagnostics/tests/override/FakeOverrideModality3.fir.kt @@ -0,0 +1,16 @@ +interface A { + fun foo() {} +} + +interface B : A { + abstract override fun foo() +} + +interface C : A { + abstract override fun foo() +} + +interface D : A + +// Fake override Z#foo should be abstract +class Z : B, C, D diff --git a/compiler/testData/diagnostics/tests/override/FakeOverrideModality3.kt b/compiler/testData/diagnostics/tests/override/FakeOverrideModality3.kt index e199f95f23d..485981df58d 100644 --- a/compiler/testData/diagnostics/tests/override/FakeOverrideModality3.kt +++ b/compiler/testData/diagnostics/tests/override/FakeOverrideModality3.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL interface A { fun foo() {} } diff --git a/compiler/testData/diagnostics/tests/scopes/kt1822.fir.kt b/compiler/testData/diagnostics/tests/scopes/kt1822.fir.kt index 3b9ba501690..4950f774aab 100644 --- a/compiler/testData/diagnostics/tests/scopes/kt1822.fir.kt +++ b/compiler/testData/diagnostics/tests/scopes/kt1822.fir.kt @@ -10,7 +10,7 @@ interface T { } class G : C(), T { - override fun foo() {} //should be an error "cannot infer visibility"; for now 'public' is inferred in such cases + override fun foo() {} //should be an error "cannot infer visibility"; for now 'public' is inferred in such cases } open class A { diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/javaOverride.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/javaOverride.fir.kt new file mode 100644 index 00000000000..c18a5c1724b --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/javaOverride.fir.kt @@ -0,0 +1,72 @@ +// !JVM_DEFAULT_MODE: enable +// !JVM_TARGET: 1.8 + +// FILE: JavaInterface.java +public interface JavaInterface { + default void test() {} + + default void testForNonDefault() {} + + void testAbstract(); +} + +// FILE: 1.kt + +interface KotlinInterface : JavaInterface { + @JvmDefault + override fun test() {} + + override fun testForNonDefault() {} + + override fun testAbstract() {} +} + +interface KotlinInterface2 : JavaInterface, KotlinInterface { + @JvmDefault + override fun test() {} + + override fun testForNonDefault() {} + + override fun testAbstract() {} +} + + +interface KotlinInterfaceForIndirect : JavaInterface { + +} + +interface KotlinInterfaceIndirectInheritance : KotlinInterfaceForIndirect { + + @JvmDefault + override fun test() {} + + override fun testForNonDefault() {} + + override fun testAbstract() {} +} + +open class KotlinClass : JavaInterface { + override fun test() {} + + override fun testForNonDefault() {} + + override fun testAbstract() {} +} + +interface KotlinInterfaceX { + + fun test() {} + + fun testForNonDefault() {} + + fun testAbstract() {} +} + +interface KotlinInterfaceManySuper: JavaInterface, KotlinInterfaceX { + @JvmDefault + override fun test() {} + + override fun testForNonDefault() {} + + override fun testAbstract() {} +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/javaOverride.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/javaOverride.kt index 542afa1506d..9a87a0a26a0 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/javaOverride.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/javaOverride.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL // !JVM_DEFAULT_MODE: enable // !JVM_TARGET: 1.8 diff --git a/compiler/testData/ir/irText/classes/kt45853.fir.ir.txt b/compiler/testData/ir/irText/classes/kt45853.fir.ir.txt new file mode 100644 index 00000000000..4dfaa290b1a --- /dev/null +++ b/compiler/testData/ir/irText/classes/kt45853.fir.ir.txt @@ -0,0 +1,61 @@ +FILE fqName: fileName:/kt45853.kt + CLASS CLASS name:A modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.A + CONSTRUCTOR visibility:public <> () returnType:.A [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:A modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' + PROPERTY name:a visibility:public modality:ABSTRACT [val] + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:ABSTRACT <> ($this:.A) returnType:.A? + correspondingProperty: PROPERTY name:a visibility:public modality:ABSTRACT [val] + $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 [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:B modality:FINAL visibility:public superTypes:[.AX] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.B + CONSTRUCTOR visibility:public <> () returnType:.B [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in .AX' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:B modality:FINAL visibility:public superTypes:[.AX]' + FUN name:getA visibility:public modality:FINAL <> ($this:.B) returnType:.X? + overridden: + public abstract fun getA (): @[FlexibleNullability] .X? [fake_override] declared in .AX + $this: VALUE_PARAMETER name: type:.B + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun getA (): .X? declared in .B' + CALL 'public open fun (): @[FlexibleNullability] .AX? declared in .AX' superQualifier='CLASS IR_EXTERNAL_JAVA_DECLARATION_STUB CLASS name:AX modality:ABSTRACT visibility:public superTypes:[.A; .X]' type=@[FlexibleNullability] .AX? origin=GET_PROPERTY + $this: GET_VAR ': .B declared in .B.getA' type=.B origin=null + PROPERTY FAKE_OVERRIDE name:a visibility:public modality:OPEN [fake_override,val] + overridden: + public open a: @[FlexibleNullability] .AX? [val] + FUN FAKE_OVERRIDE name: visibility:public modality:OPEN <> ($this:.AX) returnType:@[FlexibleNullability] .AX? [fake_override] + annotations: + Override + correspondingProperty: PROPERTY FAKE_OVERRIDE name:a visibility:public modality:OPEN [fake_override,val] + overridden: + public open fun (): @[FlexibleNullability] .AX? declared in .AX + $this: VALUE_PARAMETER name: type:.AX + 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 .AX + $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 .AX + $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 .AX + $this: VALUE_PARAMETER name: type:kotlin.Any diff --git a/compiler/testData/ir/irText/classes/kt45853.kt b/compiler/testData/ir/irText/classes/kt45853.kt index fdd516c3dd9..d56f3664e5d 100644 --- a/compiler/testData/ir/irText/classes/kt45853.kt +++ b/compiler/testData/ir/irText/classes/kt45853.kt @@ -1,5 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_BACKEND_FIR: JVM_IR // SKIP_KT_DUMP // DUMP_EXTERNAL_CLASS: X // DUMP_EXTERNAL_CLASS: AX @@ -9,8 +8,6 @@ abstract class A { abstract val a: A? } -//Fir doesn't treat B.getA as an override, because it is not return-type compatible with AX.getA -// Which might be correct behaivour. So disable fir till KT-46042 class B() : AX() { override fun getA(): X? = super.a } diff --git a/compiler/testData/ir/irText/firProblems/DelegationAndInheritanceFromJava.fir.ir.txt b/compiler/testData/ir/irText/firProblems/DelegationAndInheritanceFromJava.fir.ir.txt index 1d823c21619..0de2c7286d7 100644 --- a/compiler/testData/ir/irText/firProblems/DelegationAndInheritanceFromJava.fir.ir.txt +++ b/compiler/testData/ir/irText/firProblems/DelegationAndInheritanceFromJava.fir.ir.txt @@ -9,6 +9,7 @@ FILE fqName: fileName:/DelegationAndInheritanceFromJava.kt FUN DELEGATED_MEMBER name:add visibility:public modality:OPEN <> ($this:.Impl, element:@[FlexibleNullability] kotlin.String?) returnType:kotlin.Boolean overridden: public abstract fun add (element: @[FlexibleNullability] kotlin.String?): kotlin.Boolean [fake_override] declared in .Foo.A + public abstract fun add (element: @[FlexibleNullability] kotlin.String?): kotlin.Boolean [fake_override] declared in .Foo.B $this: VALUE_PARAMETER name: type:.Impl VALUE_PARAMETER name:element index:0 type:@[FlexibleNullability] kotlin.String? BLOCK_BODY @@ -20,6 +21,7 @@ FILE fqName: fileName:/DelegationAndInheritanceFromJava.kt FUN DELEGATED_MEMBER name:addAll visibility:public modality:OPEN <> ($this:.Impl, elements:kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>) returnType:kotlin.Boolean overridden: public abstract fun addAll (elements: kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>): kotlin.Boolean [fake_override] declared in .Foo.A + public abstract fun addAll (elements: kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>): kotlin.Boolean [fake_override] declared in .Foo.B $this: VALUE_PARAMETER name: type:.Impl VALUE_PARAMETER name:elements index:0 type:kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?> BLOCK_BODY @@ -31,6 +33,7 @@ FILE fqName: fileName:/DelegationAndInheritanceFromJava.kt FUN DELEGATED_MEMBER name:clear visibility:public modality:OPEN <> ($this:.Impl) returnType:kotlin.Unit overridden: public abstract fun clear (): kotlin.Unit [fake_override] declared in .Foo.A + public abstract fun clear (): kotlin.Unit [fake_override] declared in .Foo.B $this: VALUE_PARAMETER name: type:.Impl BLOCK_BODY CALL 'public abstract fun clear (): kotlin.Unit [fake_override] declared in .Foo.B' type=kotlin.Unit origin=null @@ -39,6 +42,7 @@ FILE fqName: fileName:/DelegationAndInheritanceFromJava.kt FUN DELEGATED_MEMBER name:iterator visibility:public modality:OPEN <> ($this:.Impl) returnType:kotlin.collections.MutableIterator<@[FlexibleNullability] kotlin.String?> [operator] overridden: public abstract fun iterator (): kotlin.collections.MutableIterator<@[FlexibleNullability] kotlin.String?> [fake_override,operator] declared in .Foo.A + public abstract fun iterator (): kotlin.collections.MutableIterator<@[FlexibleNullability] kotlin.String?> [fake_override,operator] declared in .Foo.B $this: VALUE_PARAMETER name: type:.Impl BLOCK_BODY RETURN type=kotlin.Nothing from='public open fun iterator (): kotlin.collections.MutableIterator<@[FlexibleNullability] kotlin.String?> [operator] declared in .Impl' @@ -48,6 +52,7 @@ FILE fqName: fileName:/DelegationAndInheritanceFromJava.kt FUN DELEGATED_MEMBER name:remove visibility:public modality:OPEN <> ($this:.Impl, element:@[FlexibleNullability] kotlin.String?) returnType:kotlin.Boolean overridden: public abstract fun remove (element: @[FlexibleNullability] kotlin.String?): kotlin.Boolean [fake_override] declared in .Foo.A + public abstract fun remove (element: @[FlexibleNullability] kotlin.String?): kotlin.Boolean [fake_override] declared in .Foo.B $this: VALUE_PARAMETER name: type:.Impl VALUE_PARAMETER name:element index:0 type:@[FlexibleNullability] kotlin.String? BLOCK_BODY @@ -59,6 +64,7 @@ FILE fqName: fileName:/DelegationAndInheritanceFromJava.kt FUN DELEGATED_MEMBER name:removeAll visibility:public modality:OPEN <> ($this:.Impl, elements:kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>) returnType:kotlin.Boolean overridden: public abstract fun removeAll (elements: kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>): kotlin.Boolean [fake_override] declared in .Foo.A + public abstract fun removeAll (elements: kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>): kotlin.Boolean [fake_override] declared in .Foo.B $this: VALUE_PARAMETER name: type:.Impl VALUE_PARAMETER name:elements index:0 type:kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?> BLOCK_BODY @@ -70,6 +76,7 @@ FILE fqName: fileName:/DelegationAndInheritanceFromJava.kt FUN DELEGATED_MEMBER name:retainAll visibility:public modality:OPEN <> ($this:.Impl, elements:kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>) returnType:kotlin.Boolean overridden: public abstract fun retainAll (elements: kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>): kotlin.Boolean [fake_override] declared in .Foo.A + public abstract fun retainAll (elements: kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>): kotlin.Boolean [fake_override] declared in .Foo.B $this: VALUE_PARAMETER name: type:.Impl VALUE_PARAMETER name:elements index:0 type:kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?> BLOCK_BODY @@ -81,6 +88,7 @@ FILE fqName: fileName:/DelegationAndInheritanceFromJava.kt FUN DELEGATED_MEMBER name:contains visibility:public modality:OPEN <> ($this:.Impl, element:@[FlexibleNullability] kotlin.String?) returnType:kotlin.Boolean [operator] overridden: public abstract fun contains (element: @[FlexibleNullability] kotlin.String?): kotlin.Boolean [fake_override,operator] declared in .Foo.A + public abstract fun contains (element: @[FlexibleNullability] kotlin.String?): kotlin.Boolean [fake_override,operator] declared in .Foo.B $this: VALUE_PARAMETER name: type:.Impl VALUE_PARAMETER name:element index:0 type:@[FlexibleNullability] kotlin.String? BLOCK_BODY @@ -92,6 +100,7 @@ FILE fqName: fileName:/DelegationAndInheritanceFromJava.kt FUN DELEGATED_MEMBER name:containsAll visibility:public modality:OPEN <> ($this:.Impl, elements:kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>) returnType:kotlin.Boolean overridden: public abstract fun containsAll (elements: kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>): kotlin.Boolean [fake_override] declared in .Foo.A + public abstract fun containsAll (elements: kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>): kotlin.Boolean [fake_override] declared in .Foo.B $this: VALUE_PARAMETER name: type:.Impl VALUE_PARAMETER name:elements index:0 type:kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?> BLOCK_BODY @@ -103,6 +112,7 @@ FILE fqName: fileName:/DelegationAndInheritanceFromJava.kt FUN DELEGATED_MEMBER name:isEmpty visibility:public modality:OPEN <> ($this:.Impl) returnType:kotlin.Boolean overridden: public abstract fun isEmpty (): kotlin.Boolean [fake_override] declared in .Foo.A + public abstract fun isEmpty (): kotlin.Boolean [fake_override] declared in .Foo.B $this: VALUE_PARAMETER name: type:.Impl BLOCK_BODY RETURN type=kotlin.Nothing from='public open fun isEmpty (): kotlin.Boolean declared in .Impl' @@ -112,10 +122,12 @@ FILE fqName: fileName:/DelegationAndInheritanceFromJava.kt PROPERTY DELEGATED_MEMBER name:size visibility:public modality:OPEN [val] overridden: public abstract size: kotlin.Int [fake_override,val] + public abstract size: kotlin.Int [fake_override,val] FUN DELEGATED_MEMBER name: visibility:public modality:OPEN <> ($this:.Impl) returnType:kotlin.Int correspondingProperty: PROPERTY DELEGATED_MEMBER name:size visibility:public modality:OPEN [val] overridden: public abstract fun (): kotlin.Int [fake_override] declared in .Foo.A + public abstract fun (): kotlin.Int [fake_override] declared in .Foo.B $this: VALUE_PARAMETER name: type:.Impl BLOCK_BODY RETURN type=kotlin.Nothing from='public open fun (): kotlin.Int declared in .Impl' diff --git a/compiler/testData/ir/irText/firProblems/ImplicitReceiverStack.fir.ir.txt b/compiler/testData/ir/irText/firProblems/ImplicitReceiverStack.fir.ir.txt index bf7e1eb20f5..f0812a61485 100644 --- a/compiler/testData/ir/irText/firProblems/ImplicitReceiverStack.fir.ir.txt +++ b/compiler/testData/ir/irText/firProblems/ImplicitReceiverStack.fir.ir.txt @@ -154,6 +154,7 @@ FILE fqName: fileName:/ImplicitReceiverStack.kt FUN name:iterator visibility:public modality:FINAL <> ($this:.PersistentImplicitReceiverStack) returnType:kotlin.collections.Iterator<.ImplicitReceiverValue<*>> [operator] overridden: public abstract fun iterator (): kotlin.collections.Iterator<.ImplicitReceiverValue<*>> [fake_override,operator] declared in .ImplicitReceiverStack + public abstract fun iterator (): kotlin.collections.Iterator [operator] declared in kotlin.collections.Iterable $this: VALUE_PARAMETER name: type:.PersistentImplicitReceiverStack BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun iterator (): kotlin.collections.Iterator<.ImplicitReceiverValue<*>> [operator] declared in .PersistentImplicitReceiverStack' diff --git a/compiler/testData/ir/irText/firProblems/MultiList.fir.ir.txt b/compiler/testData/ir/irText/firProblems/MultiList.fir.ir.txt index 585c220fc82..53a329845b0 100644 --- a/compiler/testData/ir/irText/firProblems/MultiList.fir.ir.txt +++ b/compiler/testData/ir/irText/firProblems/MultiList.fir.ir.txt @@ -378,9 +378,9 @@ FILE fqName: fileName:/MultiList.kt public open fun sort (p0: @[FlexibleNullability] java.util.Comparator?): kotlin.Unit declared in java.util.ArrayList $this: VALUE_PARAMETER name: type:java.util.ArrayList VALUE_PARAMETER name:p0 index:0 type:@[FlexibleNullability] java.util.Comparator.Some.SomeList>?>? - FUN FAKE_OVERRIDE name:removeAt visibility:public modality:OPEN <> ($this:java.util.ArrayList, p0:kotlin.Int) returnType:@[EnhancedNullability] .Some.SomeList> [fake_override] + FUN FAKE_OVERRIDE name:removeAt visibility:public modality:OPEN <> ($this:java.util.ArrayList, p0:kotlin.Int) returnType:@[EnhancedNullability] .Some.SomeList> [fake_override,operator] overridden: - public open fun removeAt (p0: kotlin.Int): @[EnhancedNullability] E of java.util.ArrayList declared in java.util.ArrayList + public open fun removeAt (p0: kotlin.Int): @[EnhancedNullability] E of java.util.ArrayList [operator] declared in java.util.ArrayList $this: VALUE_PARAMETER name: type:java.util.ArrayList VALUE_PARAMETER name:p0 index:0 type:kotlin.Int CLASS CLASS name:FinalList modality:FINAL visibility:public superTypes:[.SomeList] @@ -572,8 +572,8 @@ FILE fqName: fileName:/MultiList.kt public open fun sort (p0: @[FlexibleNullability] java.util.Comparator.Some.SomeList>?>?): kotlin.Unit [fake_override] declared in .SomeList $this: VALUE_PARAMETER name: type:java.util.ArrayList VALUE_PARAMETER name:p0 index:0 type:@[FlexibleNullability] java.util.Comparator.Some?>? - FUN FAKE_OVERRIDE name:removeAt visibility:public modality:OPEN <> ($this:java.util.ArrayList, p0:kotlin.Int) returnType:@[EnhancedNullability] .Some [fake_override] + FUN FAKE_OVERRIDE name:removeAt visibility:public modality:OPEN <> ($this:java.util.ArrayList, p0:kotlin.Int) returnType:@[EnhancedNullability] .Some [fake_override,operator] overridden: - public open fun removeAt (p0: kotlin.Int): @[EnhancedNullability] .Some.SomeList> [fake_override] declared in .SomeList + public open fun removeAt (p0: kotlin.Int): @[EnhancedNullability] .Some.SomeList> [fake_override,operator] declared in .SomeList $this: VALUE_PARAMETER name: type:java.util.ArrayList VALUE_PARAMETER name:p0 index:0 type:kotlin.Int