FIR: Support SAM conversion

This commit is contained in:
Denis Zharkov
2019-09-11 14:04:34 +03:00
parent f501730d86
commit 5567620563
24 changed files with 688 additions and 25 deletions
@@ -0,0 +1,41 @@
// FILE: MyFunction.java
public interface MyFunction<T, R> {
R foo(T x);
}
// FILE: JavaUsage.java
public class JavaUsage {
public static void foo1(MyFunction<Integer, String> x) {}
public static void foo2(MyFunction<? super Number, ? extends CharSequence> x) {}
public static <X, Y> Y foo3(MyFunction<X, Y> f, X x) {}
}
// FILE: main.kt
fun main() {
JavaUsage.foo1 { x ->
x.toInt().toString()
}
JavaUsage.foo2 { x ->
x.toInt().toString()
}
JavaUsage.foo2 { x: Int ->
x.toString()
}
JavaUsage.foo3(
{ x ->
(x + 1).toString()
},
1
)
JavaUsage.foo3(
{ x: Number ->
x.toInt().toString()
},
2
)
}
@@ -0,0 +1,23 @@
FILE: main.kt
public final fun main(): R|kotlin/Unit| {
Q|JavaUsage|.R|/JavaUsage.foo1|(<L> = foo1@fun <anonymous>(x: R|ft<kotlin/Int, kotlin/Int?>!|): R|ft<kotlin/String, kotlin/String?>!| <kind=EXACTLY_ONCE> {
R|<local>/x|.R|kotlin/Int.toInt|().R|kotlin/Any.toString|()
}
)
Q|JavaUsage|.R|/JavaUsage.foo2|(<L> = foo2@fun <anonymous>(x: R|ft<kotlin/Number, kotlin/Number?>!|): R|ft<kotlin/CharSequence, kotlin/CharSequence?>!| <kind=EXACTLY_ONCE> {
R|<local>/x|.R|kotlin/Number.toInt|().R|kotlin/Any.toString|()
}
)
Q|JavaUsage|.R|/JavaUsage.foo2|(<L> = foo2@fun <anonymous>(x: R|kotlin/Int|): R|ft<kotlin/CharSequence, kotlin/CharSequence?>!| <kind=EXACTLY_ONCE> {
R|<local>/x|.R|kotlin/Any.toString|()
}
)
Q|JavaUsage|.R|/JavaUsage.foo3|<R|ft<kotlin/Int, kotlin/Int>|, R|ft<kotlin/String, kotlin/String>|>(foo3@fun <anonymous>(x: R|ft<kotlin/Int, kotlin/Int>|): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
R|<local>/x|.R|kotlin/Int.plus|(Int(1)).R|kotlin/Any.toString|()
}
, Int(1))
Q|JavaUsage|.R|/JavaUsage.foo3|<R|ft<kotlin/Int, kotlin/Int>|, R|ft<kotlin/String, kotlin/String>|>(foo3@fun <anonymous>(x: R|kotlin/Number|): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
R|<local>/x|.R|kotlin/Number.toInt|().R|kotlin/Any.toString|()
}
, Int(2))
}
@@ -0,0 +1,42 @@
// TODO: These interfaces must be marked as "fun" ones that modifier is supported
interface MyRunnable {
fun foo(x: Int): Boolean
}
interface WithProperty {
val x: Int
}
interface TwoAbstract : MyRunnable {
fun bar()
}
interface Super {
fun foo(x: Int): Any
}
interface Derived : Super {
override fun foo(x: Int): Boolean
}
fun foo1(m: MyRunnable) {}
fun foo2(m: WithProperty) {}
fun foo3(m: TwoAbstract) {}
fun foo3(m: Derived) {}
fun main() {
val f = { t: Int -> t > 1}
foo1 { x -> x > 1 }
foo1(f)
foo2 { x -> x > 1 }
foo2(f)
foo3 { x -> x > 1 }
foo3(f)
foo4 { x -> x > 1 }
foo4(f)
}
@@ -0,0 +1,56 @@
FILE: kotlinSam.kt
public abstract interface MyRunnable : R|kotlin/Any| {
public abstract fun foo(x: R|kotlin/Int|): R|kotlin/Boolean|
}
public abstract interface WithProperty : R|kotlin/Any| {
public abstract val x: R|kotlin/Int|
public get(): R|kotlin/Int|
}
public abstract interface TwoAbstract : R|MyRunnable| {
public abstract fun bar(): R|kotlin/Unit|
}
public abstract interface Super : R|kotlin/Any| {
public abstract fun foo(x: R|kotlin/Int|): R|kotlin/Any|
}
public abstract interface Derived : R|Super| {
public abstract override fun foo(x: R|kotlin/Int|): R|kotlin/Boolean|
}
public final fun foo1(m: R|MyRunnable|): R|kotlin/Unit| {
}
public final fun foo2(m: R|WithProperty|): R|kotlin/Unit| {
}
public final fun foo3(m: R|TwoAbstract|): R|kotlin/Unit| {
}
public final fun foo3(m: R|Derived|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
lval f: R|kotlin/Function1<kotlin/Int, kotlin/Boolean>| = fun <anonymous>(t: R|kotlin/Int|): kotlin/Boolean {
>(R|<local>/t|, Int(1))
}
R|/foo1|(<L> = foo1@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| <kind=EXACTLY_ONCE> {
>(R|<local>/x|, Int(1))
}
)
R|/foo1|(R|<local>/f|)
R|/foo2|(<L> = foo2@fun <anonymous>(x: R|kotlin/Nothing|): kotlin/Boolean <kind=EXACTLY_ONCE> {
>(R|<local>/x|, Int(1))
}
)
<Inapplicable(INAPPLICABLE): [/foo2]>#(R|<local>/f|)
<Ambiguity: foo3, [/foo3, /foo3]>#(<L> = foo3@fun <implicit>.<anonymous>(x: <implicit>): <implicit> <kind=EXACTLY_ONCE> {
>(x#, Int(1))
}
)
R|/foo3|(R|<local>/f|)
<Unresolved name: foo4>#(<L> = foo4@fun <implicit>.<anonymous>(x: <implicit>): <implicit> <kind=EXACTLY_ONCE> {
>(x#, Int(1))
}
)
<Unresolved name: foo4>#(R|<local>/f|)
}
@@ -0,0 +1,31 @@
// FILE: MyRunnable.java
public interface MyRunnable {
void bar();
}
// FILE: DerivedRunnable.java
public interface DerivedRunnable extends MyRunnable {
boolean foo(int x);
}
// FILE: JavaUsage.java
public class JavaUsage {
public static void foo(DerivedRunnable x) {}
}
// FILE: main.kt
fun foo(m: MyRunnable) {}
fun main() {
JavaUsage.foo {
x ->
x > 1
}
JavaUsage.foo({ it > 1 })
val x = { x: Int -> x > 1 }
JavaUsage.foo(x)
}
@@ -0,0 +1,18 @@
FILE: main.kt
public final fun foo(m: R|MyRunnable|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
Q|JavaUsage|.R|/JavaUsage.foo|(<L> = foo@fun <anonymous>(x: R|kotlin/Nothing|): kotlin/Boolean <kind=EXACTLY_ONCE> {
>(R|<local>/x|, Int(1))
}
)
Q|JavaUsage|.R|/JavaUsage.foo|(foo@fun <anonymous>(): kotlin/Boolean <kind=EXACTLY_ONCE> {
>(<Unresolved name: it>#, Int(1))
}
)
lval x: R|kotlin/Function1<kotlin/Int, kotlin/Boolean>| = fun <anonymous>(x: R|kotlin/Int|): kotlin/Boolean {
>(R|<local>/x|, Int(1))
}
Q|JavaUsage|.<Inapplicable(INAPPLICABLE): [/JavaUsage.foo]>#(R|<local>/x|)
}
@@ -0,0 +1,16 @@
// FILE: JavaClass.java
public class JavaClass {
public static void foo(Runnable x) {}
public void bar(Runnable x) {}
}
// FILE: main.kt
fun main() {
JavaClass.foo {
""
}
JavaClass().bar {
""
}
}
@@ -0,0 +1,11 @@
FILE: main.kt
public final fun main(): R|kotlin/Unit| {
Q|JavaClass|.R|/JavaClass.foo|(<L> = foo@fun <anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
String()
}
)
R|/JavaClass.JavaClass|().R|/JavaClass.bar|(<L> = bar@fun <anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
String()
}
)
}
@@ -0,0 +1,32 @@
// FILE: MyRunnable.java
public interface MyRunnable {
boolean foo(int x);
default void bar() {}
}
// FILE: DerivedRunnable.java
public interface DerivedRunnable extends MyRunnable {
default void baz() {}
}
// FILE: JavaUsage.java
public class JavaUsage {
public static void foo(DerivedRunnable x) {}
}
// FILE: main.kt
fun foo(m: MyRunnable) {}
fun main() {
JavaUsage.foo {
x ->
x > 1
}
JavaUsage.foo({ it > 1 })
val x = { x: Int -> x > 1 }
JavaUsage.foo(x)
}
@@ -0,0 +1,18 @@
FILE: main.kt
public final fun foo(m: R|MyRunnable|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
Q|JavaUsage|.R|/JavaUsage.foo|(<L> = foo@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| <kind=EXACTLY_ONCE> {
>(R|<local>/x|, Int(1))
}
)
Q|JavaUsage|.R|/JavaUsage.foo|(foo@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Boolean| <kind=EXACTLY_ONCE> {
>(R|<local>/it|, Int(1))
}
)
lval x: R|kotlin/Function1<kotlin/Int, kotlin/Boolean>| = fun <anonymous>(x: R|kotlin/Int|): kotlin/Boolean {
>(R|<local>/x|, Int(1))
}
Q|JavaUsage|.R|/JavaUsage.foo|(R|<local>/x|)
}
@@ -0,0 +1,34 @@
// FILE: MyRunnable.java
public interface MyRunnable {
Object foo(int x);
default void bar() {}
}
// FILE: DerivedRunnable.java
public interface DerivedRunnable extends MyRunnable {
@Override
Boolean foo(int x);
default void baz() {}
}
// FILE: JavaUsage.java
public class JavaUsage {
public static void foo(DerivedRunnable x) {}
}
// FILE: main.kt
fun foo(m: MyRunnable) {}
fun main() {
JavaUsage.foo {
x ->
x > 1
}
JavaUsage.foo({ it > 1 })
val x = { x: Int -> x > 1 }
JavaUsage.foo(x)
}
@@ -0,0 +1,18 @@
FILE: main.kt
public final fun foo(m: R|MyRunnable|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
Q|JavaUsage|.R|/JavaUsage.foo|(<L> = foo@fun <anonymous>(x: R|kotlin/Int|): R|ft<kotlin/Boolean, kotlin/Boolean?>!| <kind=EXACTLY_ONCE> {
>(R|<local>/x|, Int(1))
}
)
Q|JavaUsage|.R|/JavaUsage.foo|(foo@fun <anonymous>(it: R|kotlin/Int|): R|ft<kotlin/Boolean, kotlin/Boolean?>!| <kind=EXACTLY_ONCE> {
>(R|<local>/it|, Int(1))
}
)
lval x: R|kotlin/Function1<kotlin/Int, kotlin/Boolean>| = fun <anonymous>(x: R|kotlin/Int|): kotlin/Boolean {
>(R|<local>/x|, Int(1))
}
Q|JavaUsage|.R|/JavaUsage.foo|(R|<local>/x|)
}
@@ -0,0 +1,26 @@
// FILE: MyRunnable.java
public interface MyRunnable {
boolean foo(int x);
}
// FILE: JavaUsage.java
public class JavaUsage {
public static void foo(MyRunnable x) {}
}
// FILE: main.kt
fun foo(m: MyRunnable) {}
fun main() {
JavaUsage.foo {
x ->
x > 1
}
JavaUsage.foo({ it > 1 })
val x = { x: Int -> x > 1 }
JavaUsage.foo(x)
}
@@ -0,0 +1,18 @@
FILE: main.kt
public final fun foo(m: R|MyRunnable|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
Q|JavaUsage|.R|/JavaUsage.foo|(<L> = foo@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| <kind=EXACTLY_ONCE> {
>(R|<local>/x|, Int(1))
}
)
Q|JavaUsage|.R|/JavaUsage.foo|(foo@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Boolean| <kind=EXACTLY_ONCE> {
>(R|<local>/it|, Int(1))
}
)
lval x: R|kotlin/Function1<kotlin/Int, kotlin/Boolean>| = fun <anonymous>(x: R|kotlin/Int|): kotlin/Boolean {
>(R|<local>/x|, Int(1))
}
Q|JavaUsage|.R|/JavaUsage.foo|(R|<local>/x|)
}