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