FIR checker: substitute type parameters in dispatch receiver type

Consider the following code:

```
fun test(a: List<String>) {
  a.first()
}
```

The dispatch receiver type of `first` in this case is `List<T>` before
this change. After this change, it's `List<String>`.

In addition, this change also replace the dispatch receiver type with
the more specific type if available. For example, consider the following

```
class MyList: ArrayList<String>()

fun test(a: MyList) {
  a.get(0)
}
```
The dispatch receiver type of `get` is `MyList`, instead of
`ArrayList<String>`. That is, a fake override is created in this case.
This commit is contained in:
Tianyu Geng
2021-08-06 14:56:37 -07:00
committed by teamcityserver
parent c047adbaec
commit 765cad8448
61 changed files with 342 additions and 145 deletions
@@ -0,0 +1,41 @@
// FILE: foo/Super.java
package foo
public abstract class Super<T> {
protected abstract String getName();
protected abstract void setName(String s);
protected abstract String getName2();
protected abstract void setName2(String s);
protected abstract void doSomething();
protected abstract void doSomething2();
}
// FILE: bar/Sub.kt
package bar
abstract class Sub<T>: foo.Super<T>() {
abstract override fun getName(): String
abstract override fun setName(s: String)
abstract override fun doSomething()
}
// FILE: foo/test.kt
package foo
fun test(s: bar.Sub<String>) {
s.<!INVISIBLE_REFERENCE!>name<!>
s.<!INVISIBLE_REFERENCE!>name<!> = ""
s.name2
s.name2 = ""
s.<!INVISIBLE_REFERENCE!>doSomething<!>()
s.doSomething2()
val s2: Super<String> = s
s2.<!INVISIBLE_REFERENCE!>name<!>
s2.<!INVISIBLE_REFERENCE!>name<!> = ""
s2.name2
s2.name2 = ""
s2.<!INVISIBLE_REFERENCE!>doSomething<!>()
s2.doSomething2()
}
@@ -0,0 +1,41 @@
// FILE: foo/Super.java
package foo
public abstract class Super<T> {
protected abstract String getName();
protected abstract void setName(String s);
protected abstract String getName2();
protected abstract void setName2(String s);
protected abstract void doSomething();
protected abstract void doSomething2();
}
// FILE: bar/Sub.kt
package bar
abstract class Sub<T>: foo.Super<T>() {
abstract override fun getName(): String
abstract override fun setName(s: String)
abstract override fun doSomething()
}
// FILE: foo/test.kt
package foo
fun test(s: bar.Sub<String>) {
s.<!INVISIBLE_MEMBER!>name<!>
s.<!INVISIBLE_MEMBER!>name<!> = ""
s.name2
s.name2 = ""
s.<!INVISIBLE_MEMBER!>doSomething<!>()
s.doSomething2()
val s2: Super<String> = s
s2.name
s2.name = ""
s2.name2
s2.name2 = ""
s2.doSomething()
s2.doSomething2()
}
@@ -0,0 +1,35 @@
package
package bar {
public abstract class Sub</*0*/ T> : foo.Super<T> {
public constructor Sub</*0*/ T>()
protected abstract override /*1*/ fun doSomething(): kotlin.Unit
protected/*protected and package*/ abstract override /*1*/ /*fake_override*/ fun doSomething2(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
protected abstract override /*1*/ fun getName(): kotlin.String
protected/*protected and package*/ abstract override /*1*/ /*fake_override*/ fun getName2(): kotlin.String!
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
protected abstract override /*1*/ fun setName(/*0*/ s: kotlin.String): kotlin.Unit
protected/*protected and package*/ abstract override /*1*/ /*fake_override*/ fun setName2(/*0*/ s: kotlin.String!): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
package foo {
public fun test(/*0*/ s: bar.Sub<kotlin.String>): kotlin.Unit
public abstract class Super</*0*/ T : kotlin.Any!> {
public constructor Super</*0*/ T : kotlin.Any!>()
protected/*protected and package*/ abstract fun doSomething(): kotlin.Unit
protected/*protected and package*/ abstract fun doSomething2(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
protected/*protected and package*/ abstract fun getName(): kotlin.String!
protected/*protected and package*/ abstract fun getName2(): kotlin.String!
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
protected/*protected and package*/ abstract fun setName(/*0*/ s: kotlin.String!): kotlin.Unit
protected/*protected and package*/ abstract fun setName2(/*0*/ s: kotlin.String!): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}