[FIR] Replace single supertype scope with list of scopes of supertypes in use site scopes
This big refactoring is needed to cleanup building of overrides
mappings and prevent creating redundant intersection overrides in
cases when there is no need in them:
```kotlin
interface A {
fun foo()
}
interface B {
fun foo()
}
interface C : A, B {
override fun foo()
}
```
Before this refactoring there was next override tree:
C.foo
intersection override (A.foo, B.foo)
A.foo
B.foo
Also this commit fixes special mapping of overrides in jvm scopes
for declarations which have kotlin builtins in supertypes with
special java mapping rules (collections, for example)
This commit is contained in:
+94
@@ -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")
|
||||
|
||||
+83
@@ -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)
|
||||
|
||||
+22
@@ -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|
|
||||
|
||||
}
|
||||
+16
@@ -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
|
||||
}
|
||||
Vendored
+8
@@ -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]
|
||||
|
||||
Vendored
+26
@@ -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|<local>/d|.R|/C.x|
|
||||
lval b: R|kotlin/Int| = R|<local>/d|.R|/D.y|
|
||||
}
|
||||
+42
@@ -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
|
||||
}
|
||||
Vendored
+21
@@ -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<kotlin/Any, kotlin/Any?>| 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<kotlin/Any, kotlin/Any?>| from Java enhancement scope for /E [id: 0]
|
||||
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
FILE: B.kt
|
||||
public abstract class B : R|A| {
|
||||
public constructor(): R|B| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
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<R|C|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test(d: R|D|): R|kotlin/Unit| {
|
||||
R|<local>/d|.R|/B.foo|.R|kotlin/String.length|
|
||||
}
|
||||
+22
@@ -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
|
||||
}
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
A:
|
||||
[Enhancement]: public abstract fun getFoo(): R|ft<kotlin/String, kotlin/String?>| 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<kotlin/String, kotlin/String?>| 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<kotlin/String, kotlin/String?>| 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<kotlin/String, kotlin/String?>| from Java enhancement scope for /A [id: 1]
|
||||
|
||||
Vendored
+24
@@ -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|
|
||||
|
||||
}
|
||||
+18
@@ -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
|
||||
}
|
||||
Vendored
+18
@@ -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]
|
||||
|
||||
Vendored
+24
@@ -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|
|
||||
|
||||
}
|
||||
Vendored
+18
@@ -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
|
||||
}
|
||||
+17
@@ -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]
|
||||
+13
@@ -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<R|C|>()
|
||||
}
|
||||
|
||||
}
|
||||
+18
@@ -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()
|
||||
+4
@@ -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]
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
FILE: A.kt
|
||||
public open class A : R|kotlin/Any| {
|
||||
public constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
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|<local>/b|.R|/B.getScope|()
|
||||
R|<local>/b|.R|/A.setScope|(R|<local>/s|)
|
||||
}
|
||||
Vendored
+23
@@ -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)
|
||||
}
|
||||
Vendored
+33
@@ -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| {
|
||||
}
|
||||
+25
@@ -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
|
||||
compiler/fir/analysis-tests/testData/resolve/scopes/noIntersectionOverrideOfTwoMembers.overrides.txt
Vendored
+26
@@ -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]
|
||||
|
||||
Vendored
+33
@@ -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| {
|
||||
}
|
||||
Vendored
+25
@@ -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
|
||||
+25
@@ -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]
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
FILE: C.kt
|
||||
public open class C : R|B<kotlin/Any?>| {
|
||||
public constructor(name: R|kotlin/String|): R|C| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
private final var name: R|kotlin/String| = R|<local>/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|<local>/d|.R|/C.name|
|
||||
}
|
||||
+25
@@ -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<T> extends A {
|
||||
T setName(String newName);
|
||||
}
|
||||
|
||||
// FILE: C.kt
|
||||
open class C(private var name: String) : B<Any?> {
|
||||
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
|
||||
}
|
||||
|
||||
Vendored
+14
@@ -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<kotlin/String, kotlin/String?>| 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<kotlin/String, kotlin/String?>|): 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<kotlin/String, kotlin/String?>|): R|ft<T, T?>| from Java enhancement scope for /B [id: 2]
|
||||
[Source]: private final var name: R|kotlin/String| = R|<local>/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<kotlin/String, kotlin/String?>| from Substitution scope for [Java enhancement scope for /B] for type C [id: 1]
|
||||
[Source]: private final var name: R|kotlin/String| = R|<local>/name| from Java enhancement scope for /D [id: 0]
|
||||
[Source]: private final var name: R|kotlin/String| = R|<local>/name| from Use site scope of /C [id: 0]
|
||||
|
||||
+41
@@ -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()
|
||||
}
|
||||
+18
@@ -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]
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
FILE: main.kt
|
||||
public final fun test(map: R|SomeMap<kotlin/Int, kotlin/String>|): R|kotlin/Unit| {
|
||||
R|<local>/map|.R|SubstitutionOverride</SomeMap.containsKey: R|kotlin/Boolean|>|(Int(1))
|
||||
R|<local>/map|.<Inapplicable(INAPPLICABLE): /SomeMap.containsKey>#(String())
|
||||
R|<local>/map|.R|SubstitutionOverride</SomeMap.containsValue: R|kotlin/Boolean|>|(String())
|
||||
R|<local>/map|.<Inapplicable(INAPPLICABLE): /SomeMap.containsValue>#(Int(1))
|
||||
R|<local>/map|.R|SubstitutionOverride</SomeMap.get: R|kotlin/String?|>|(Int(1))
|
||||
R|<local>/map|.<Inapplicable(INAPPLICABLE): /SomeMap.get>#(String())
|
||||
R|<local>/map|.R|SubstitutionOverride</SomeMap.remove: R|kotlin/String?|>|(Int(1))
|
||||
R|<local>/map|.<Inapplicable(INAPPLICABLE): /SomeMap.remove>#(String())
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
// SCOPE_DUMP: SomeMap:containsKey;containsValue;get;remove, MyMap:containsKey;containsValue;get
|
||||
|
||||
// FILE: MyBaseMap.java
|
||||
public interface MyBaseMap<K1, V1> {
|
||||
boolean containsKey(Object key);
|
||||
}
|
||||
|
||||
// FILE: MyMap.java
|
||||
public interface MyMap<K2, V2> extends MyBaseMap<K2, V2> {
|
||||
@Override
|
||||
boolean containsKey(Object key);
|
||||
boolean containsValue(Object key);
|
||||
|
||||
V2 get(K2 key);
|
||||
}
|
||||
|
||||
// FILE: SomeMap.java
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class SomeMap<K3, V3> implements Map<K3, V3>, MyMap<K3, V3> {
|
||||
@Override
|
||||
public abstract boolean containsKey(Object key);
|
||||
|
||||
@Override
|
||||
public abstract V3 remove(Object key);
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
fun test(map: SomeMap<Int, String>) {
|
||||
map.containsKey(1) // ok
|
||||
map.containsKey(<!ARGUMENT_TYPE_MISMATCH!>""<!>) // error
|
||||
|
||||
map.containsValue("") // ok
|
||||
map.containsValue(<!ARGUMENT_TYPE_MISMATCH!>1<!>) // error
|
||||
|
||||
map.get(1) // ok
|
||||
map.get(<!ARGUMENT_TYPE_MISMATCH!>""<!>) // error
|
||||
|
||||
map.remove(1) // ok
|
||||
map.remove(<!ARGUMENT_TYPE_MISMATCH!>""<!>) // error
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
SomeMap:
|
||||
[Enhancement]: public abstract fun containsKey(key: R|ft<K3, K3?>|): R|kotlin/Boolean| from Java enhancement scope for /SomeMap [id: 0]
|
||||
[SubstitutionOverride]: public abstract fun containsKey(key: R|ft<K3, K3?>|): R|kotlin/Boolean| from Substitution scope for [Use site scope of kotlin/collections/MutableMap] for type SomeMap<K3, V3> [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<kotlin/Any, kotlin/Any?>|): R|kotlin/Boolean| from Substitution scope for [Java enhancement scope for /MyMap] for type SomeMap<K3, V3> [id: 4]
|
||||
[Enhancement]: public abstract fun containsKey(key: R|ft<kotlin/Any, kotlin/Any?>|): R|kotlin/Boolean| from Java enhancement scope for /MyMap [id: 5]
|
||||
[SubstitutionOverride]: public abstract fun containsKey(key: R|ft<kotlin/Any, kotlin/Any?>|): R|kotlin/Boolean| from Substitution scope for [Java enhancement scope for /MyBaseMap] for type MyMap<K2, V2> [id: 6]
|
||||
[Enhancement]: public abstract fun containsKey(key: R|ft<kotlin/Any, kotlin/Any?>|): R|kotlin/Boolean| from Java enhancement scope for /MyBaseMap [id: 7]
|
||||
[SubstitutionOverride]: public abstract fun containsKey(key: R|ft<kotlin/Any, kotlin/Any?>|): R|kotlin/Boolean| from Substitution scope for [Java enhancement scope for /MyBaseMap] for type MyMap<K2, V2> [id: 6]
|
||||
[Enhancement]: public abstract fun containsKey(key: R|ft<kotlin/Any, kotlin/Any?>|): R|kotlin/Boolean| from Java enhancement scope for /MyBaseMap [id: 7]
|
||||
[IntersectionOverride]: public abstract fun containsValue(value: R|ft<V3, V3?>|): R|kotlin/Boolean| from Java enhancement scope for /SomeMap [id: 0]
|
||||
[SubstitutionOverride]: public abstract fun containsValue(value: R|ft<V3, V3?>|): R|kotlin/Boolean| from Substitution scope for [Use site scope of kotlin/collections/MutableMap] for type SomeMap<K3, V3> [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<kotlin/Any, kotlin/Any?>|): R|kotlin/Boolean| from Substitution scope for [Java enhancement scope for /MyMap] for type SomeMap<K3, V3> [id: 4]
|
||||
[Enhancement]: public abstract fun containsValue(key: R|ft<kotlin/Any, kotlin/Any?>|): R|kotlin/Boolean| from Java enhancement scope for /MyMap [id: 5]
|
||||
[IntersectionOverride]: public abstract operator fun get(key: R|ft<K3, K3?>|): R|V3?| from Java enhancement scope for /SomeMap [id: 0]
|
||||
[SubstitutionOverride]: public abstract operator fun get(key: R|ft<K3, K3?>|): R|V3?| from Substitution scope for [Use site scope of kotlin/collections/MutableMap] for type SomeMap<K3, V3> [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<K3, K3?>|): R|ft<V3, V3?>| from Substitution scope for [Java enhancement scope for /MyMap] for type SomeMap<K3, V3> [id: 4]
|
||||
[Enhancement]: public abstract operator fun get(key: R|ft<K2, K2?>|): R|ft<V2, V2?>| from Java enhancement scope for /MyMap [id: 5]
|
||||
[Enhancement]: public abstract fun remove(key: R|ft<K3, K3?>|): R|V3?| from Java enhancement scope for /SomeMap [id: 0]
|
||||
[SubstitutionOverride]: public abstract fun remove(key: R|ft<K3, K3?>|): R|V3?| from Substitution scope for [Use site scope of kotlin/collections/MutableMap] for type SomeMap<K3, V3> [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<K3, K3?>|, value: R|ft<V3, V3?>|): 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<kotlin/Any, kotlin/Any?>|): R|kotlin/Boolean| from Java enhancement scope for /MyMap [id: 0]
|
||||
[SubstitutionOverride]: public abstract fun containsKey(key: R|ft<kotlin/Any, kotlin/Any?>|): R|kotlin/Boolean| from Substitution scope for [Java enhancement scope for /MyBaseMap] for type MyMap<K2, V2> [id: 1]
|
||||
[Enhancement]: public abstract fun containsKey(key: R|ft<kotlin/Any, kotlin/Any?>|): R|kotlin/Boolean| from Java enhancement scope for /MyBaseMap [id: 2]
|
||||
[Enhancement]: public abstract fun containsValue(key: R|ft<kotlin/Any, kotlin/Any?>|): R|kotlin/Boolean| from Java enhancement scope for /MyMap [id: 0]
|
||||
[Enhancement]: public abstract operator fun get(key: R|ft<K2, K2?>|): R|ft<V2, V2?>| from Java enhancement scope for /MyMap [id: 0]
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
FILE: main.kt
|
||||
public abstract class A : R|kotlin/Any| {
|
||||
public constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
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<R|D|>()
|
||||
}
|
||||
|
||||
}
|
||||
+28
@@ -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()
|
||||
|
||||
+8
@@ -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]
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
|
||||
+28
@@ -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()
|
||||
}
|
||||
+10
@@ -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]
|
||||
|
||||
+94
@@ -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")
|
||||
|
||||
+94
@@ -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")
|
||||
|
||||
+15
-11
@@ -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<MemberWithBaseScope<FirNamedFunctionSymbol>>)
|
||||
is FirPropertySymbol -> filterOutOverriddenProperties(directOverriddenMembersWithBaseScope as List<MemberWithBaseScope<FirPropertySymbol>>)
|
||||
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 ->
|
||||
|
||||
+8
-1
@@ -333,7 +333,14 @@ object FirOverrideChecker : FirClassChecker() {
|
||||
with(FirOptInUsageBaseChecker) {
|
||||
val overriddenExperimentalities = mutableSetOf<Experimentality>()
|
||||
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(
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+34
-47
@@ -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<FirNamedFunctionSymbol, Collection<FirNamedFunctionSymbol>>()
|
||||
private val overriddenProperties = mutableMapOf<FirPropertySymbol, Collection<FirPropertySymbol>>()
|
||||
private val enhancedToOriginalFunctions = mutableMapOf<FirNamedFunctionSymbol, FirNamedFunctionSymbol>()
|
||||
private val enhancedToOriginalProperties = mutableMapOf<FirPropertySymbol, FirPropertySymbol>()
|
||||
|
||||
private val overrideBindCache = mutableMapOf<Name, Map<FirCallableSymbol<*>?, List<FirCallableDeclaration>>>()
|
||||
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<FirCallableDeclaration> {
|
||||
val directlyOverriddensFromScopeFir = overriddenMembers(name)
|
||||
val superTypesScope = useSiteMemberScope.superTypesScope as? FirTypeIntersectionScope ?: return directlyOverriddensFromScopeFir
|
||||
|
||||
val directlyOverriddensFromScope = directlyOverriddensFromScopeFir.map { it.symbol }
|
||||
val result = mutableSetOf<FirCallableSymbol<*>>()
|
||||
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<FirCallableDeclaration> {
|
||||
val backMap = overrideBindCache.getOrPut(name) {
|
||||
val result = mutableMapOf<FirCallableSymbol<*>?, MutableList<FirCallableDeclaration>>()
|
||||
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<FirCallableDeclaration> {
|
||||
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 <S : FirCallableSymbol<*>> doProcessDirectOverriddenCallables(
|
||||
callableSymbol: S,
|
||||
processor: (S, FirTypeScope) -> ProcessorAction,
|
||||
enhancedToOriginalMap: Map<S, S>,
|
||||
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<Name> {
|
||||
return useSiteMemberScope.getCallableNames()
|
||||
}
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ class JavaClassStaticUseSiteScope internal constructor(
|
||||
) : FirContainingNamesAwareScope() {
|
||||
private val functions = hashMapOf<Name, Collection<FirNamedFunctionSymbol>>()
|
||||
private val properties = hashMapOf<Name, Collection<FirVariableSymbol<*>>>()
|
||||
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) {
|
||||
|
||||
+423
-247
@@ -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<FirTypeScope>,
|
||||
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<Name, Collection<FirNamedFunctionSymbol>>()
|
||||
private val syntheticPropertyByNameMap = hashMapOf<Name, FirSyntheticPropertySymbol>()
|
||||
|
||||
private val canUseSpecialGetters: Boolean by lazy { !klass.hasKotlinSuper(session) }
|
||||
|
||||
private val callableNamesCached by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
declaredMemberScope.getCallableNames() + superTypesScope.getCallableNames()
|
||||
}
|
||||
|
||||
override fun getCallableNames(): Set<Name> = callableNamesCached
|
||||
|
||||
override fun getClassifierNames(): Set<Name> {
|
||||
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<FirVariableSymbol<*>> {
|
||||
override fun collectProperties(name: Name): Collection<FirVariableSymbol<*>> {
|
||||
val fields = mutableSetOf<FirCallableSymbol<*>>()
|
||||
val fieldNames = mutableSetOf<Name>()
|
||||
val result = mutableSetOf<FirVariableSymbol<*>>()
|
||||
@@ -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<FirPropertySymbol>? ?: 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<FirPropertySymbol>()
|
||||
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<FirPropertySymbol>,
|
||||
renamedSpecialBuiltInName: Name?
|
||||
): List<FirNamedFunctionSymbol> {
|
||||
/**
|
||||
* 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<ConeKotlinType>()
|
||||
?.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<FirNamedFunctionSymbol> {
|
||||
val result = mutableListOf<FirNamedFunctionSymbol>()
|
||||
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<FirNamedFunctionSymbol>,
|
||||
functionsFromSupertypesWithNaturalName: MembersByScope<FirNamedFunctionSymbol>, // candidates for override
|
||||
destination: MutableCollection<FirNamedFunctionSymbol>
|
||||
) {
|
||||
val resultsOfIntersectionToSaveInCache = mutableListOf<ResultOfIntersection<FirNamedFunctionSymbol>>()
|
||||
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<MemberWithBaseScope<FirNamedFunctionSymbol>>,
|
||||
naturalName: Name,
|
||||
explicitlyDeclaredFunctionsWithNaturalName: Collection<FirNamedFunctionSymbol>,
|
||||
destination: MutableCollection<FirNamedFunctionSymbol>,
|
||||
resultOfIntersectionWithNaturalName: ResultOfIntersection<FirNamedFunctionSymbol>,
|
||||
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<FirNamedFunctionSymbol>,
|
||||
destination: MutableCollection<FirNamedFunctionSymbol>,
|
||||
resultsOfIntersectionToSaveInCache: MutableList<ResultOfIntersection<FirNamedFunctionSymbol>>
|
||||
) {
|
||||
/*
|
||||
* 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<FirNamedFunctionSymbol>,
|
||||
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<FirNamedFunctionSymbol> {
|
||||
val result = mutableListOf<FirNamedFunctionSymbol>()
|
||||
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
|
||||
|
||||
@@ -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<FirTypeScope>?,
|
||||
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
|
||||
|
||||
@@ -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 : FirCallableSymbol<*>> 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>
|
||||
): 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 : FirCallableSymbol<*>> 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
|
||||
}
|
||||
+2
-5
@@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
+7
@@ -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)
|
||||
}
|
||||
|
||||
+146
-40
@@ -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<FirTypeScope>,
|
||||
dispatchReceiverType: ConeSimpleKotlinType,
|
||||
protected val declaredMemberScope: FirContainingNamesAwareScope
|
||||
) : AbstractFirOverrideScope(session, overrideChecker) {
|
||||
protected val supertypeScopeContext = FirTypeIntersectionScopeContext(session, overrideChecker, superTypeScopes, dispatchReceiverType)
|
||||
|
||||
private val functions = hashMapOf<Name, Collection<FirNamedFunctionSymbol>>()
|
||||
private val properties = hashMapOf<Name, Collection<FirVariableSymbol<*>>>()
|
||||
val directOverriddenFunctions = hashMapOf<FirNamedFunctionSymbol, Collection<FirNamedFunctionSymbol>>()
|
||||
protected val directOverriddenProperties = hashMapOf<FirPropertySymbol, MutableList<FirPropertySymbol>>()
|
||||
private val functions: MutableMap<Name, Collection<FirNamedFunctionSymbol>> = hashMapOf()
|
||||
|
||||
private val properties: MutableMap<Name, Collection<FirVariableSymbol<*>>> = hashMapOf()
|
||||
protected val directOverriddenFunctions: MutableMap<FirNamedFunctionSymbol, List<ResultOfIntersection<FirNamedFunctionSymbol>>> =
|
||||
hashMapOf()
|
||||
protected val directOverriddenProperties: MutableMap<FirPropertySymbol, List<ResultOfIntersection<FirPropertySymbol>>> = hashMapOf()
|
||||
|
||||
protected val functionsFromSupertypes: MutableMap<Name, List<ResultOfIntersection<FirNamedFunctionSymbol>>> = mutableMapOf()
|
||||
protected val propertiesFromSupertypes: MutableMap<Name, List<ResultOfIntersection<FirPropertySymbol>>> = mutableMapOf()
|
||||
protected val fieldsFromSupertypes: MutableMap<Name, List<FirFieldSymbol>> = mutableMapOf()
|
||||
|
||||
private val absentClassifiersFromSupertypes = mutableSetOf<Name>()
|
||||
|
||||
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<FirNamedFunctionSymbol> = mutableListOf<FirNamedFunctionSymbol>().apply {
|
||||
val overrideCandidates = mutableSetOf<FirFunctionSymbol<*>>()
|
||||
collectDeclaredFunctions(name, this)
|
||||
val explicitlyDeclaredFunctions = this.toSet()
|
||||
collectFunctionsFromSupertypes(name, this, explicitlyDeclaredFunctions)
|
||||
}
|
||||
|
||||
protected fun collectDeclaredFunctions(name: Name, destination: MutableList<FirNamedFunctionSymbol>) {
|
||||
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<FirNamedFunctionSymbol>,
|
||||
explicitlyDeclaredFunctions: Set<FirNamedFunctionSymbol>
|
||||
) {
|
||||
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<ResultOfIntersection<FirNamedFunctionSymbol>> {
|
||||
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<FirVariableSymbol<*>>
|
||||
protected abstract fun collectProperties(name: Name): Collection<FirVariableSymbol<*>>
|
||||
|
||||
private fun computeDirectOverridden(symbol: FirNamedFunctionSymbol): Collection<FirNamedFunctionSymbol> {
|
||||
val result = mutableListOf<FirNamedFunctionSymbol>()
|
||||
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<ResultOfIntersection<FirNamedFunctionSymbol>> {
|
||||
val result = mutableListOf<ResultOfIntersection<FirNamedFunctionSymbol>>()
|
||||
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 <D : FirCallableSymbol<*>> ResultOfIntersection<D>.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 <D : FirCallableSymbol<*>> processDirectOverriddenMembersWithBaseScopeImpl(
|
||||
directOverriddenMap: Map<D, List<ResultOfIntersection<D>>>,
|
||||
callablesFromSupertypes: Map<Name, List<ResultOfIntersection<D>>>,
|
||||
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<Name> = callableNamesCached
|
||||
override fun getCallableNames(): Set<Name> {
|
||||
return callableNamesCached
|
||||
}
|
||||
|
||||
override fun getClassifierNames(): Set<Name> {
|
||||
return declaredMemberScope.getClassifierNames() + superTypesScope.getClassifierNames()
|
||||
return classifierNamesCached
|
||||
}
|
||||
}
|
||||
|
||||
+64
-31
@@ -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<FirTypeScope>,
|
||||
declaredMemberScope: FirContainingNamesAwareScope
|
||||
) : AbstractFirUseSiteMemberScope(classId, session, FirStandardOverrideChecker(session), superTypesScope, declaredMemberScope) {
|
||||
|
||||
override fun doProcessProperties(name: Name): Collection<FirVariableSymbol<*>> {
|
||||
val seen = mutableSetOf<FirVariableSymbol<*>>()
|
||||
val result = mutableSetOf<FirVariableSymbol<*>>()
|
||||
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<FirVariableSymbol<*>> {
|
||||
return buildList {
|
||||
val explicitlyDeclaredProperties = mutableSetOf<FirVariableSymbol<*>>()
|
||||
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<FirTypeIntersectionScopeContext.ResultOfIntersection<FirPropertySymbol>> {
|
||||
val result = mutableListOf<FirTypeIntersectionScopeContext.ResultOfIntersection<FirPropertySymbol>>()
|
||||
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<FirPropertySymbol> {
|
||||
val result = mutableListOf<FirPropertySymbol>()
|
||||
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<FirTypeIntersectionScopeContext.ResultOfIntersection<FirPropertySymbol>>, List<FirFieldSymbol>> {
|
||||
propertiesFromSupertypes[name]?.let {
|
||||
return it to fieldsFromSupertypes.getValue(name)
|
||||
}
|
||||
|
||||
val fields = mutableListOf<FirFieldSymbol>()
|
||||
val properties = supertypeScopeContext.collectCallables<FirPropertySymbol>(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 {
|
||||
|
||||
@@ -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<MemberWithBaseScope<FirNamedFunctionSymbol>>): Collection<MemberWithBaseScope<FirNamedFunctionSymbol>> {
|
||||
return filterOutOverridden(extractedOverridden, FirTypeScope::processDirectOverriddenFunctionsWithBaseScope)
|
||||
}
|
||||
|
||||
fun filterOutOverriddenProperties(extractedOverridden: Collection<MemberWithBaseScope<FirPropertySymbol>>): Collection<MemberWithBaseScope<FirPropertySymbol>> {
|
||||
return filterOutOverridden(extractedOverridden, FirTypeScope::processDirectOverriddenPropertiesWithBaseScope)
|
||||
}
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
inline fun <D : FirCallableSymbol<*>> filterOutOverridden(
|
||||
extractedOverridden: Collection<MemberWithBaseScope<D>>,
|
||||
processAllOverridden: ProcessOverriddenWithBaseScope<D>,
|
||||
): Collection<MemberWithBaseScope<D>> {
|
||||
return extractedOverridden.filter { overridden1 ->
|
||||
extractedOverridden.none { overridden2 ->
|
||||
overridden1 !== overridden2 && overrides(
|
||||
overridden2,
|
||||
overridden1,
|
||||
processAllOverridden
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Whether f overrides g
|
||||
@PrivateForInline
|
||||
inline fun <D : FirCallableSymbol<*>> overrides(
|
||||
f: MemberWithBaseScope<D>,
|
||||
g: MemberWithBaseScope<D>,
|
||||
processAllOverridden: ProcessOverriddenWithBaseScope<D>,
|
||||
): 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
|
||||
}
|
||||
+5
-7
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+80
-81
@@ -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<D> = List<Pair<FirTypeScope, List<D>>>
|
||||
|
||||
class FirTypeIntersectionScopeContext(
|
||||
val session: FirSession,
|
||||
private val overrideChecker: FirOverrideChecker,
|
||||
@property:PrivateForInline val scopes: List<FirTypeScope>,
|
||||
val scopes: List<FirTypeScope>,
|
||||
private val dispatchReceiverType: ConeSimpleKotlinType,
|
||||
) {
|
||||
private val typeCheckerState = session.typeContext.newTypeCheckerState(
|
||||
@@ -37,14 +42,40 @@ class FirTypeIntersectionScopeContext(
|
||||
val intersectionOverrides: FirCache<FirCallableSymbol<*>, MemberWithBaseScope<FirCallableSymbol<*>>, ContextForIntersectionOverrideConstruction<*>> =
|
||||
session.intersectionOverrideStorage.cacheByScope.getValue(dispatchReceiverType).intersectionOverrides
|
||||
|
||||
data class ResultOfIntersection<D : FirCallableSymbol<*>>(
|
||||
val chosenSymbol: D,
|
||||
val overriddenMembers: List<MemberWithBaseScope<D>>
|
||||
sealed class ResultOfIntersection<D : FirCallableSymbol<*>>(
|
||||
val overriddenMembers: List<MemberWithBaseScope<D>>,
|
||||
val containingScope: FirTypeScope?
|
||||
) {
|
||||
constructor(
|
||||
chosenSymbol: D,
|
||||
overriddenMember: MemberWithBaseScope<D>
|
||||
) : this(chosenSymbol, listOf(overriddenMember))
|
||||
abstract val chosenSymbol: D
|
||||
|
||||
class SingleMember<D : FirCallableSymbol<*>>(
|
||||
override val chosenSymbol: D,
|
||||
overriddenMembers: List<MemberWithBaseScope<D>>,
|
||||
containingScope: FirTypeScope?
|
||||
) : ResultOfIntersection<D>(overriddenMembers, containingScope) {
|
||||
constructor(
|
||||
chosenSymbol: D,
|
||||
overriddenMember: MemberWithBaseScope<D>
|
||||
) : this(chosenSymbol, listOf(overriddenMember), overriddenMember.baseScope)
|
||||
}
|
||||
|
||||
class NonTrivial<D : FirCallableSymbol<*>>(
|
||||
private val intersectionOverridesCache: FirCache<FirCallableSymbol<*>, MemberWithBaseScope<FirCallableSymbol<*>>, ContextForIntersectionOverrideConstruction<*>>,
|
||||
private val context: ContextForIntersectionOverrideConstruction<D>,
|
||||
overriddenMembers: List<MemberWithBaseScope<D>>,
|
||||
containingScope: FirTypeScope?
|
||||
) : ResultOfIntersection<D>(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<ResultOfIntersection<FirNamedFunctionSymbol>> {
|
||||
return collectCallables(name, FirScope::processFunctionsByName)
|
||||
}
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
inline fun <D : FirCallableSymbol<*>> collectCallables(
|
||||
inline fun <D : FirCallableSymbol<*>> collectMembersByScope(
|
||||
name: Name,
|
||||
processCallables: FirScope.(Name, (D) -> Unit) -> Unit
|
||||
): List<ResultOfIntersection<D>> {
|
||||
val membersByScope = scopes.mapNotNull { scope ->
|
||||
): MembersByScope<D> {
|
||||
return scopes.mapNotNull { scope ->
|
||||
val resultForScope = mutableListOf<D>()
|
||||
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 <D : FirCallableSymbol<*>> collectCallables(
|
||||
name: Name,
|
||||
processCallables: FirScope.(Name, (D) -> Unit) -> Unit
|
||||
): List<ResultOfIntersection<D>> {
|
||||
return collectCallablesImpl(collectMembersByScope(name, processCallables))
|
||||
}
|
||||
|
||||
fun <D : FirCallableSymbol<*>> collectCallablesImpl(
|
||||
membersByScope: List<Pair<FirTypeScope, MutableList<D>>>
|
||||
membersByScope: List<Pair<FirTypeScope, List<D>>>
|
||||
): List<ResultOfIntersection<D>> {
|
||||
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 <D : FirCallableSymbol<*>> createIntersectionOverride(
|
||||
extractedOverrides: List<MemberWithBaseScope<D>>,
|
||||
mostSpecific: D,
|
||||
@@ -384,45 +426,6 @@ class FirTypeIntersectionScopeContext(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun <D : FirCallableSymbol<*>> filterOutOverridden(
|
||||
extractedOverridden: Collection<MemberWithBaseScope<D>>,
|
||||
processAllOverridden: ProcessOverriddenWithBaseScope<D>,
|
||||
): Collection<MemberWithBaseScope<D>> {
|
||||
return extractedOverridden.filter { overridden1 ->
|
||||
extractedOverridden.none { overridden2 ->
|
||||
overridden1 !== overridden2 && overrides(
|
||||
overridden2,
|
||||
overridden1,
|
||||
processAllOverridden
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Whether f overrides g
|
||||
private fun <D : FirCallableSymbol<*>> overrides(
|
||||
f: MemberWithBaseScope<D>,
|
||||
g: MemberWithBaseScope<D>,
|
||||
processAllOverridden: ProcessOverriddenWithBaseScope<D>,
|
||||
): 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 <D : FirCallableSymbol<*>> chooseIntersectionVisibility(
|
||||
extractedOverrides: Collection<MemberWithBaseScope<D>>
|
||||
): Visibility {
|
||||
@@ -492,19 +495,6 @@ class FirTypeIntersectionScopeContext(
|
||||
}
|
||||
}
|
||||
|
||||
class MemberWithBaseScope<out D : FirCallableSymbol<*>>(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 : FirCallableSymbol<*>> 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<FirCallableSymbol<*>, MemberWithBaseScope<FirCallableSymbol<*>>, ContextForIntersectionOverrideConstruction<*>> =
|
||||
cachesFactory.createCache { mostSpecific, context ->
|
||||
val (intersectionScope, extractedOverrides, scopeForMostSpecific) = context
|
||||
val (_, intersectionScope, extractedOverrides, scopeForMostSpecific) = context
|
||||
intersectionScope.createIntersectionOverride(extractedOverrides, mostSpecific, scopeForMostSpecific)
|
||||
}
|
||||
}
|
||||
|
||||
data class ContextForIntersectionOverrideConstruction<D : FirCallableSymbol<*>>(
|
||||
val mostSpecific: D,
|
||||
val intersectionContext: FirTypeIntersectionScopeContext,
|
||||
val extractedOverrides: List<MemberWithBaseScope<D>>,
|
||||
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 <D : FirCallableSymbol<*>> ResultOfIntersection<D>.isIntersectionOverride(): Boolean {
|
||||
contract {
|
||||
returns(true) implies (this@isIntersectionOverride is ResultOfIntersection.NonTrivial<D>)
|
||||
}
|
||||
return this is ResultOfIntersection.NonTrivial
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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<FirTypeScope>.processOverriddenPropertiesAndSelf(
|
||||
propertySymbol: FirPropertySymbol,
|
||||
processor: (FirPropertySymbol) -> ProcessorAction
|
||||
) {
|
||||
if (!processor(propertySymbol)) return
|
||||
processOverriddenProperties(propertySymbol, processor)
|
||||
}
|
||||
|
||||
enum class ProcessorAction {
|
||||
|
||||
@@ -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 <S : FirCallableSymbol<*>> doProcessDirectOverriddenCallables(
|
||||
callableSymbol: S,
|
||||
processor: (S, FirTypeScope) -> ProcessorAction,
|
||||
directOverriddenMap: Map<S, Collection<S>>,
|
||||
baseScope: FirTypeScope,
|
||||
processDirectOverriddenCallables: FirTypeScope.(S, (S, FirTypeScope) -> ProcessorAction) -> ProcessorAction
|
||||
): ProcessorAction {
|
||||
val directOverridden = directOverriddenMap[callableSymbol]?.takeIf { it.isNotEmpty() }
|
||||
?: return baseScope.processDirectOverriddenCallables(callableSymbol, processor)
|
||||
class MemberWithBaseScope<out D : FirCallableSymbol<*>>(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<Pair<FirTypeScope, FirNamedFunctionSymbol>>,
|
||||
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<Pair<FirTypeScope, FirPropertySymbol>> = mutableSetOf(),
|
||||
processor: (FirPropertySymbol) -> ProcessorAction
|
||||
): ProcessorAction =
|
||||
doProcessAllOverriddenCallables(
|
||||
propertySymbol,
|
||||
processor,
|
||||
FirTypeScope::processDirectOverriddenPropertiesWithBaseScope,
|
||||
visited
|
||||
)
|
||||
|
||||
fun List<FirTypeScope>.processOverriddenFunctions(
|
||||
functionSymbol: FirNamedFunctionSymbol,
|
||||
processor: (FirNamedFunctionSymbol) -> ProcessorAction
|
||||
) {
|
||||
val visited = mutableSetOf<Pair<FirTypeScope, FirNamedFunctionSymbol>>()
|
||||
for (scope in this) {
|
||||
if (!scope.processOverriddenFunctionsWithVisited(functionSymbol, visited, processor)) return
|
||||
}
|
||||
}
|
||||
|
||||
fun List<FirTypeScope>.processOverriddenProperties(
|
||||
propertySymbol: FirPropertySymbol,
|
||||
processor: (FirPropertySymbol) -> ProcessorAction
|
||||
) {
|
||||
val visited = mutableSetOf<Pair<FirTypeScope, FirPropertySymbol>>()
|
||||
for (scope in this) {
|
||||
if (!scope.processOverriddenPropertiesWithVisited(propertySymbol, visited, processor)) return
|
||||
}
|
||||
}
|
||||
|
||||
private fun <S : FirCallableSymbol<*>> FirTypeScope.doProcessAllOverriddenCallables(
|
||||
callableSymbol: S,
|
||||
processor: (S, FirTypeScope) -> ProcessorAction,
|
||||
processDirectOverriddenCallablesWithBaseScope: FirTypeScope.(S, (S, FirTypeScope) -> ProcessorAction) -> ProcessorAction,
|
||||
visited: MutableSet<S>
|
||||
visited: MutableSet<Pair<FirTypeScope, S>>
|
||||
): 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 <S : FirCallableSymbol<*>> FirTypeScope.doProcessAllOverriddenCallab
|
||||
callableSymbol: S,
|
||||
processor: (S) -> ProcessorAction,
|
||||
processDirectOverriddenCallablesWithBaseScope: FirTypeScope.(S, (S, FirTypeScope) -> ProcessorAction) -> ProcessorAction,
|
||||
visited: MutableSet<S>
|
||||
visited: MutableSet<Pair<FirTypeScope, S>>
|
||||
): ProcessorAction =
|
||||
doProcessAllOverriddenCallables(callableSymbol, { s, _ -> processor(s) }, processDirectOverriddenCallablesWithBaseScope, visited)
|
||||
|
||||
@@ -157,6 +191,41 @@ fun FirTypeScope.getDirectOverriddenMembers(
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
fun FirTypeScope.getDirectOverriddenMembersWithBaseScope(member: FirCallableSymbol<*>): List<MemberWithBaseScope<FirCallableSymbol<*>>> {
|
||||
return when (member) {
|
||||
is FirNamedFunctionSymbol -> getDirectOverriddenFunctionsWithBaseScope(member)
|
||||
is FirPropertySymbol -> getDirectOverriddenPropertiesWithBaseScope(member)
|
||||
else -> emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
fun FirTypeScope.getDirectOverriddenFunctionsWithBaseScope(
|
||||
function: FirNamedFunctionSymbol,
|
||||
): List<MemberWithBaseScope<FirNamedFunctionSymbol>> {
|
||||
val overriddenFunctions = mutableSetOf<MemberWithBaseScope<FirNamedFunctionSymbol>>()
|
||||
|
||||
processDirectOverriddenFunctionsWithBaseScope(function) { symbol, baseScope ->
|
||||
|
||||
overriddenFunctions += MemberWithBaseScope(symbol, baseScope)
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
|
||||
return overriddenFunctions.toList()
|
||||
}
|
||||
|
||||
fun FirTypeScope.getDirectOverriddenPropertiesWithBaseScope(
|
||||
property: FirPropertySymbol,
|
||||
): List<MemberWithBaseScope<FirPropertySymbol>> {
|
||||
val overriddenProperties = mutableSetOf<MemberWithBaseScope<FirPropertySymbol>>()
|
||||
|
||||
processDirectOverriddenPropertiesWithBaseScope(property) { symbol, baseScope ->
|
||||
overriddenProperties += MemberWithBaseScope(symbol, baseScope)
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
|
||||
return overriddenProperties.toList()
|
||||
}
|
||||
|
||||
fun FirTypeScope.getDirectOverriddenFunctions(
|
||||
function: FirNamedFunctionSymbol,
|
||||
unwrapIntersectionAndSubstitutionOverride: Boolean = false,
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
-85
@@ -1,85 +0,0 @@
|
||||
// FILE: CollectionStringImpl.java
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class CollectionStringImpl implements Collection<String> {
|
||||
@Override
|
||||
public int size() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Iterator<String> iterator() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
return new Object[0];
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T> 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<? extends String> 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.<!OVERLOAD_RESOLUTION_AMBIGUITY!>contains<!>("")
|
||||
(x as Collection<String>).contains("")
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// FILE: CollectionStringImpl.java
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
+4
-4
@@ -12,10 +12,10 @@ abstract class KA : A() {
|
||||
}
|
||||
|
||||
fun foo(a: A, ka: KA) {
|
||||
a.<!OVERLOAD_RESOLUTION_AMBIGUITY!>contains<!>("")
|
||||
a.<!NONE_APPLICABLE!>contains<!>(1)
|
||||
"" <!OVERLOAD_RESOLUTION_AMBIGUITY!>in<!> a
|
||||
1 <!NONE_APPLICABLE!>in<!> a
|
||||
a.contains("")
|
||||
a.contains(<!ARGUMENT_TYPE_MISMATCH!>1<!>)
|
||||
"" in a
|
||||
<!ARGUMENT_TYPE_MISMATCH!>1<!> in a
|
||||
|
||||
ka.contains("")
|
||||
ka.contains(<!ARGUMENT_TYPE_MISMATCH!>1<!>)
|
||||
|
||||
Vendored
-25
@@ -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
|
||||
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class X<!> : A()
|
||||
|
||||
fun main() {
|
||||
val x = X()
|
||||
x[0]
|
||||
x.length
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// FILE: AImpl.java
|
||||
|
||||
abstract public class AImpl {
|
||||
|
||||
@@ -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
|
||||
<!MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED!>class Z<!> : B, C, D
|
||||
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
interface A {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
@@ -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 <!CANNOT_CHANGE_ACCESS_PRIVILEGE!>foo<!>() {} //should be an error "cannot infer visibility"; for now 'public' is inferred in such cases
|
||||
}
|
||||
|
||||
open class A {
|
||||
|
||||
+72
@@ -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 {
|
||||
@<!DEPRECATION!>JvmDefault<!>
|
||||
override fun test() {}
|
||||
|
||||
<!NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT!>override fun testForNonDefault()<!> {}
|
||||
|
||||
override fun testAbstract() {}
|
||||
}
|
||||
|
||||
interface KotlinInterface2 : JavaInterface, KotlinInterface {
|
||||
@<!DEPRECATION!>JvmDefault<!>
|
||||
override fun test() {}
|
||||
|
||||
<!NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT!>override fun testForNonDefault()<!> {}
|
||||
|
||||
override fun testAbstract() {}
|
||||
}
|
||||
|
||||
|
||||
interface KotlinInterfaceForIndirect : JavaInterface {
|
||||
|
||||
}
|
||||
|
||||
interface KotlinInterfaceIndirectInheritance : KotlinInterfaceForIndirect {
|
||||
|
||||
@<!DEPRECATION!>JvmDefault<!>
|
||||
override fun test() {}
|
||||
|
||||
<!NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT!>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 {
|
||||
@<!DEPRECATION!>JvmDefault<!>
|
||||
override fun test() {}
|
||||
|
||||
<!NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT!>override fun testForNonDefault()<!> {}
|
||||
|
||||
override fun testAbstract() {}
|
||||
}
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
// !JVM_DEFAULT_MODE: enable
|
||||
// !JVM_TARGET: 1.8
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
FILE fqName:<root> fileName:/kt45853.kt
|
||||
CLASS CLASS name:A modality:ABSTRACT visibility:public superTypes:[kotlin.Any]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.A
|
||||
CONSTRUCTOR visibility:public <> () returnType:<root>.A [primary]
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [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:<get-a> visibility:public modality:ABSTRACT <> ($this:<root>.A) returnType:<root>.A?
|
||||
correspondingProperty: PROPERTY name:a visibility:public modality:ABSTRACT [val]
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.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:<this> 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:<this> 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:<this> type:kotlin.Any
|
||||
CLASS CLASS name:B modality:FINAL visibility:public superTypes:[<root>.AX]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.B
|
||||
CONSTRUCTOR visibility:public <> () returnType:<root>.B [primary]
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.AX'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:B modality:FINAL visibility:public superTypes:[<root>.AX]'
|
||||
FUN name:getA visibility:public modality:FINAL <> ($this:<root>.B) returnType:<root>.X?
|
||||
overridden:
|
||||
public abstract fun getA (): @[FlexibleNullability] <root>.X? [fake_override] declared in <root>.AX
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.B
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun getA (): <root>.X? declared in <root>.B'
|
||||
CALL 'public open fun <get-a> (): @[FlexibleNullability] <root>.AX? declared in <root>.AX' superQualifier='CLASS IR_EXTERNAL_JAVA_DECLARATION_STUB CLASS name:AX modality:ABSTRACT visibility:public superTypes:[<root>.A; <root>.X]' type=@[FlexibleNullability] <root>.AX? origin=GET_PROPERTY
|
||||
$this: GET_VAR '<this>: <root>.B declared in <root>.B.getA' type=<root>.B origin=null
|
||||
PROPERTY FAKE_OVERRIDE name:a visibility:public modality:OPEN [fake_override,val]
|
||||
overridden:
|
||||
public open a: @[FlexibleNullability] <root>.AX? [val]
|
||||
FUN FAKE_OVERRIDE name:<get-a> visibility:public modality:OPEN <> ($this:<root>.AX) returnType:@[FlexibleNullability] <root>.AX? [fake_override]
|
||||
annotations:
|
||||
Override
|
||||
correspondingProperty: PROPERTY FAKE_OVERRIDE name:a visibility:public modality:OPEN [fake_override,val]
|
||||
overridden:
|
||||
public open fun <get-a> (): @[FlexibleNullability] <root>.AX? declared in <root>.AX
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.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 <root>.AX
|
||||
$this: VALUE_PARAMETER name:<this> 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 <root>.AX
|
||||
$this: VALUE_PARAMETER name:<this> 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 <root>.AX
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
@@ -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
|
||||
}
|
||||
|
||||
+12
@@ -9,6 +9,7 @@ FILE fqName:<root> fileName:/DelegationAndInheritanceFromJava.kt
|
||||
FUN DELEGATED_MEMBER name:add visibility:public modality:OPEN <> ($this:<root>.Impl, element:@[FlexibleNullability] kotlin.String?) returnType:kotlin.Boolean
|
||||
overridden:
|
||||
public abstract fun add (element: @[FlexibleNullability] kotlin.String?): kotlin.Boolean [fake_override] declared in <root>.Foo.A
|
||||
public abstract fun add (element: @[FlexibleNullability] kotlin.String?): kotlin.Boolean [fake_override] declared in <root>.Foo.B
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Impl
|
||||
VALUE_PARAMETER name:element index:0 type:@[FlexibleNullability] kotlin.String?
|
||||
BLOCK_BODY
|
||||
@@ -20,6 +21,7 @@ FILE fqName:<root> fileName:/DelegationAndInheritanceFromJava.kt
|
||||
FUN DELEGATED_MEMBER name:addAll visibility:public modality:OPEN <> ($this:<root>.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 <root>.Foo.A
|
||||
public abstract fun addAll (elements: kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>): kotlin.Boolean [fake_override] declared in <root>.Foo.B
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Impl
|
||||
VALUE_PARAMETER name:elements index:0 type:kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>
|
||||
BLOCK_BODY
|
||||
@@ -31,6 +33,7 @@ FILE fqName:<root> fileName:/DelegationAndInheritanceFromJava.kt
|
||||
FUN DELEGATED_MEMBER name:clear visibility:public modality:OPEN <> ($this:<root>.Impl) returnType:kotlin.Unit
|
||||
overridden:
|
||||
public abstract fun clear (): kotlin.Unit [fake_override] declared in <root>.Foo.A
|
||||
public abstract fun clear (): kotlin.Unit [fake_override] declared in <root>.Foo.B
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Impl
|
||||
BLOCK_BODY
|
||||
CALL 'public abstract fun clear (): kotlin.Unit [fake_override] declared in <root>.Foo.B' type=kotlin.Unit origin=null
|
||||
@@ -39,6 +42,7 @@ FILE fqName:<root> fileName:/DelegationAndInheritanceFromJava.kt
|
||||
FUN DELEGATED_MEMBER name:iterator visibility:public modality:OPEN <> ($this:<root>.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 <root>.Foo.A
|
||||
public abstract fun iterator (): kotlin.collections.MutableIterator<@[FlexibleNullability] kotlin.String?> [fake_override,operator] declared in <root>.Foo.B
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Impl
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun iterator (): kotlin.collections.MutableIterator<@[FlexibleNullability] kotlin.String?> [operator] declared in <root>.Impl'
|
||||
@@ -48,6 +52,7 @@ FILE fqName:<root> fileName:/DelegationAndInheritanceFromJava.kt
|
||||
FUN DELEGATED_MEMBER name:remove visibility:public modality:OPEN <> ($this:<root>.Impl, element:@[FlexibleNullability] kotlin.String?) returnType:kotlin.Boolean
|
||||
overridden:
|
||||
public abstract fun remove (element: @[FlexibleNullability] kotlin.String?): kotlin.Boolean [fake_override] declared in <root>.Foo.A
|
||||
public abstract fun remove (element: @[FlexibleNullability] kotlin.String?): kotlin.Boolean [fake_override] declared in <root>.Foo.B
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Impl
|
||||
VALUE_PARAMETER name:element index:0 type:@[FlexibleNullability] kotlin.String?
|
||||
BLOCK_BODY
|
||||
@@ -59,6 +64,7 @@ FILE fqName:<root> fileName:/DelegationAndInheritanceFromJava.kt
|
||||
FUN DELEGATED_MEMBER name:removeAll visibility:public modality:OPEN <> ($this:<root>.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 <root>.Foo.A
|
||||
public abstract fun removeAll (elements: kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>): kotlin.Boolean [fake_override] declared in <root>.Foo.B
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Impl
|
||||
VALUE_PARAMETER name:elements index:0 type:kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>
|
||||
BLOCK_BODY
|
||||
@@ -70,6 +76,7 @@ FILE fqName:<root> fileName:/DelegationAndInheritanceFromJava.kt
|
||||
FUN DELEGATED_MEMBER name:retainAll visibility:public modality:OPEN <> ($this:<root>.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 <root>.Foo.A
|
||||
public abstract fun retainAll (elements: kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>): kotlin.Boolean [fake_override] declared in <root>.Foo.B
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Impl
|
||||
VALUE_PARAMETER name:elements index:0 type:kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>
|
||||
BLOCK_BODY
|
||||
@@ -81,6 +88,7 @@ FILE fqName:<root> fileName:/DelegationAndInheritanceFromJava.kt
|
||||
FUN DELEGATED_MEMBER name:contains visibility:public modality:OPEN <> ($this:<root>.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 <root>.Foo.A
|
||||
public abstract fun contains (element: @[FlexibleNullability] kotlin.String?): kotlin.Boolean [fake_override,operator] declared in <root>.Foo.B
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Impl
|
||||
VALUE_PARAMETER name:element index:0 type:@[FlexibleNullability] kotlin.String?
|
||||
BLOCK_BODY
|
||||
@@ -92,6 +100,7 @@ FILE fqName:<root> fileName:/DelegationAndInheritanceFromJava.kt
|
||||
FUN DELEGATED_MEMBER name:containsAll visibility:public modality:OPEN <> ($this:<root>.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 <root>.Foo.A
|
||||
public abstract fun containsAll (elements: kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>): kotlin.Boolean [fake_override] declared in <root>.Foo.B
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Impl
|
||||
VALUE_PARAMETER name:elements index:0 type:kotlin.collections.Collection<@[FlexibleNullability] kotlin.String?>
|
||||
BLOCK_BODY
|
||||
@@ -103,6 +112,7 @@ FILE fqName:<root> fileName:/DelegationAndInheritanceFromJava.kt
|
||||
FUN DELEGATED_MEMBER name:isEmpty visibility:public modality:OPEN <> ($this:<root>.Impl) returnType:kotlin.Boolean
|
||||
overridden:
|
||||
public abstract fun isEmpty (): kotlin.Boolean [fake_override] declared in <root>.Foo.A
|
||||
public abstract fun isEmpty (): kotlin.Boolean [fake_override] declared in <root>.Foo.B
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Impl
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun isEmpty (): kotlin.Boolean declared in <root>.Impl'
|
||||
@@ -112,10 +122,12 @@ FILE fqName:<root> 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:<get-size> visibility:public modality:OPEN <> ($this:<root>.Impl) returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY DELEGATED_MEMBER name:size visibility:public modality:OPEN [val]
|
||||
overridden:
|
||||
public abstract fun <get-size> (): kotlin.Int [fake_override] declared in <root>.Foo.A
|
||||
public abstract fun <get-size> (): kotlin.Int [fake_override] declared in <root>.Foo.B
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Impl
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun <get-size> (): kotlin.Int declared in <root>.Impl'
|
||||
|
||||
@@ -154,6 +154,7 @@ FILE fqName:<root> fileName:/ImplicitReceiverStack.kt
|
||||
FUN name:iterator visibility:public modality:FINAL <> ($this:<root>.PersistentImplicitReceiverStack) returnType:kotlin.collections.Iterator<<root>.ImplicitReceiverValue<*>> [operator]
|
||||
overridden:
|
||||
public abstract fun iterator (): kotlin.collections.Iterator<<root>.ImplicitReceiverValue<*>> [fake_override,operator] declared in <root>.ImplicitReceiverStack
|
||||
public abstract fun iterator (): kotlin.collections.Iterator<T of kotlin.collections.Iterable> [operator] declared in kotlin.collections.Iterable
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.PersistentImplicitReceiverStack
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun iterator (): kotlin.collections.Iterator<<root>.ImplicitReceiverValue<*>> [operator] declared in <root>.PersistentImplicitReceiverStack'
|
||||
|
||||
@@ -378,9 +378,9 @@ FILE fqName:<root> fileName:/MultiList.kt
|
||||
public open fun sort (p0: @[FlexibleNullability] java.util.Comparator<in @[FlexibleNullability] E of java.util.ArrayList?>?): kotlin.Unit declared in java.util.ArrayList
|
||||
$this: VALUE_PARAMETER name:<this> type:java.util.ArrayList<E of java.util.ArrayList>
|
||||
VALUE_PARAMETER name:p0 index:0 type:@[FlexibleNullability] java.util.Comparator<in @[FlexibleNullability] <root>.Some<T of <root>.SomeList>?>?
|
||||
FUN FAKE_OVERRIDE name:removeAt visibility:public modality:OPEN <> ($this:java.util.ArrayList<E of java.util.ArrayList>, p0:kotlin.Int) returnType:@[EnhancedNullability] <root>.Some<T of <root>.SomeList> [fake_override]
|
||||
FUN FAKE_OVERRIDE name:removeAt visibility:public modality:OPEN <> ($this:java.util.ArrayList<E of java.util.ArrayList>, p0:kotlin.Int) returnType:@[EnhancedNullability] <root>.Some<T of <root>.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:<this> type:java.util.ArrayList<E of java.util.ArrayList>
|
||||
VALUE_PARAMETER name:p0 index:0 type:kotlin.Int
|
||||
CLASS CLASS name:FinalList modality:FINAL visibility:public superTypes:[<root>.SomeList<kotlin.String>]
|
||||
@@ -572,8 +572,8 @@ FILE fqName:<root> fileName:/MultiList.kt
|
||||
public open fun sort (p0: @[FlexibleNullability] java.util.Comparator<in @[FlexibleNullability] <root>.Some<T of <root>.SomeList>?>?): kotlin.Unit [fake_override] declared in <root>.SomeList
|
||||
$this: VALUE_PARAMETER name:<this> type:java.util.ArrayList<E of java.util.ArrayList>
|
||||
VALUE_PARAMETER name:p0 index:0 type:@[FlexibleNullability] java.util.Comparator<in @[FlexibleNullability] <root>.Some<kotlin.String>?>?
|
||||
FUN FAKE_OVERRIDE name:removeAt visibility:public modality:OPEN <> ($this:java.util.ArrayList<E of java.util.ArrayList>, p0:kotlin.Int) returnType:@[EnhancedNullability] <root>.Some<kotlin.String> [fake_override]
|
||||
FUN FAKE_OVERRIDE name:removeAt visibility:public modality:OPEN <> ($this:java.util.ArrayList<E of java.util.ArrayList>, p0:kotlin.Int) returnType:@[EnhancedNullability] <root>.Some<kotlin.String> [fake_override,operator]
|
||||
overridden:
|
||||
public open fun removeAt (p0: kotlin.Int): @[EnhancedNullability] <root>.Some<T of <root>.SomeList> [fake_override] declared in <root>.SomeList
|
||||
public open fun removeAt (p0: kotlin.Int): @[EnhancedNullability] <root>.Some<T of <root>.SomeList> [fake_override,operator] declared in <root>.SomeList
|
||||
$this: VALUE_PARAMETER name:<this> type:java.util.ArrayList<E of java.util.ArrayList>
|
||||
VALUE_PARAMETER name:p0 index:0 type:kotlin.Int
|
||||
|
||||
Reference in New Issue
Block a user