[FIR] Support builder (coroutine) inference

#KT-37431 Fixed
This commit is contained in:
Dmitriy Novozhilov
2020-06-22 16:41:28 +03:00
parent 6a9504f26a
commit dbbb999952
49 changed files with 549 additions and 458 deletions
@@ -1,19 +0,0 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
import kotlin.experimental.ExperimentalTypeInference
suspend fun main() {
iFlow { <!INAPPLICABLE_CANDIDATE!>emit<!>(1) }
}
@OptIn(ExperimentalTypeInference::class)
fun <K> iFlow(@BuilderInference block: suspend iFlowCollector<in K>.() -> Unit): iFlow<K> = TODO()
interface iFlowCollector<S> {
suspend fun emit(value: S)
}
interface iFlow<out V>
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
@@ -1,25 +0,0 @@
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
@file:OptIn(ExperimentalTypeInference::class)
import kotlin.experimental.ExperimentalTypeInference
interface Controller<T> {
suspend fun yield(t: T) {}
fun justString(): String = ""
fun <Z> generidFun(t: Z) = t
}
fun <S> generate(@BuilderInference g: suspend Controller<S>.() -> Unit): S = TODO()
val test1 = generate {
<!INAPPLICABLE_CANDIDATE!>yield<!>(justString())
}
val test2 = generate {
<!INAPPLICABLE_CANDIDATE!>yield<!>(generidFun(2))
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
@@ -1,38 +0,0 @@
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -UNUSED_EXPRESSION
@file:OptIn(ExperimentalTypeInference::class)
package a.b
import kotlin.experimental.ExperimentalTypeInference
class BatchInfo1(val batchSize: Int)
class BatchInfo2<T>(val data: T)
object Obj
fun test1() {
val a: Sequence<String> = sequence {
val x = BatchInfo1::class
val y = a.b.BatchInfo1::class
val z = Obj::class
val x1 = BatchInfo1::batchSize
val y1 = a.b.BatchInfo1::class
}
}
interface Scope<T> {
fun yield(t: T) {}
}
fun <S> generate(@BuilderInference g: Scope<S>.() -> Unit): S = TODO()
val test2 = generate {
{ <!INAPPLICABLE_CANDIDATE!>yield<!>("foo") }::class
}
val test3 = generate {
({ <!INAPPLICABLE_CANDIDATE!>yield<!>("foo") })::class
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -UNUSED_EXPRESSION
@@ -1,43 +0,0 @@
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
@file:OptIn(ExperimentalTypeInference::class)
import kotlin.experimental.ExperimentalTypeInference
class GenericController<T> {
suspend fun yield(t: T) {}
}
@BuilderInference
suspend fun <K> GenericController<K>.yieldAll(s: Collection<K>) {}
fun <S> generate(@BuilderInference g: suspend GenericController<S>.() -> Unit): S = TODO()
val test1 = generate {
<!INAPPLICABLE_CANDIDATE!>yield<!>(4)
<!INAPPLICABLE_CANDIDATE!>yieldAll<!>(setOf(4, 5))
}
val test2 = generate {
<!INAPPLICABLE_CANDIDATE!>yieldAll<!>(setOf(B))
}
val test3 = generate {
<!INAPPLICABLE_CANDIDATE!>yieldAll<!>(setOf(B, C))
}
val test4 = generate {
<!INAPPLICABLE_CANDIDATE!>yieldAll<!>(setOf(B))
<!INAPPLICABLE_CANDIDATE!>yield<!>(C)
}
// Utils
fun <X> setOf(vararg x: X): Set<X> = TODO()
interface A
object B : A
object C : A
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
@@ -25,7 +25,7 @@ fun <S> Controller<S>.genericExtension() {}
fun Controller<String>.safeExtension() {}
val test1 = generate {
<!INAPPLICABLE_CANDIDATE!>yield<!>("foo")
yield("foo")
baseExtension()
}
@@ -34,7 +34,7 @@ val test2 = generate {
}
val test3 = generate {
<!INAPPLICABLE_CANDIDATE!>yield<!>(42)
yield(42)
outNullableAnyExtension()
}
@@ -43,20 +43,20 @@ val test4 = generate {
}
val test5 = generate {
<!INAPPLICABLE_CANDIDATE!>yield<!>(42)
yield(42)
outAnyExtension()
}
val test6 = generate {
<!INAPPLICABLE_CANDIDATE!>yield<!>("bar")
<!INAPPLICABLE_CANDIDATE!>invNullableAnyExtension<!>()
yield("bar")
invNullableAnyExtension()
}
val test7 = generate {
<!INAPPLICABLE_CANDIDATE!>yield<!>("baz")
<!INAPPLICABLE_CANDIDATE!>genericExtension<!><Int>()
yield("baz")
genericExtension<Int>()
}
val test8 = generate {
<!INAPPLICABLE_CANDIDATE!>safeExtension<!>()
safeExtension()
}
@@ -25,7 +25,7 @@ fun Base<String>.stringBase() {}
val test1 = generate {
starBase()
<!INAPPLICABLE_CANDIDATE!>yield<!>("foo")
yield("foo")
}
val test2 = generate {
@@ -33,17 +33,17 @@ val test2 = generate {
}
val test3 = generate {
<!INAPPLICABLE_CANDIDATE!>yield<!>("bar")
<!INAPPLICABLE_CANDIDATE!>stringBase<!>()
yield("bar")
stringBase()
}
val test4 = generateSpecific {
<!INAPPLICABLE_CANDIDATE!>yield<!>(42)
yield(42)
starBase()
}
val test5 = generateSpecific {
<!INAPPLICABLE_CANDIDATE!>yield<!>(42)
yield(42)
stringBase()
}
@@ -17,20 +17,20 @@ class GenericController<T> {
fun <S> generate(@BuilderInference g: suspend GenericController<S>.() -> Unit): List<S> = TODO()
val test1 = generate {
<!INAPPLICABLE_CANDIDATE!>yield<!>(3)
yield(3)
}
val test2 = generate {
<!INAPPLICABLE_CANDIDATE!>yield<!>(3)
<!INAPPLICABLE_CANDIDATE!>notYield<!>(3)
yield(3)
notYield(3)
}
val test3 = generate {
<!INAPPLICABLE_CANDIDATE!>yield<!>(3)
<!INAPPLICABLE_CANDIDATE!>yieldBarReturnType<!>(3)
yield(3)
yieldBarReturnType(3)
}
val test4 = generate {
<!INAPPLICABLE_CANDIDATE!>yield<!>(3)
yield(3)
barReturnType()
}
@@ -6,21 +6,21 @@
import kotlin.experimental.ExperimentalTypeInference
fun test_1() {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>sequence {
<!INAPPLICABLE_CANDIDATE!>yield<!>(<!DEBUG_INFO_EXPRESSION_TYPE("Inv<kotlin.Any?>")!>materialize()<!>)
<!INAPPLICABLE_CANDIDATE!>yield<!>(materialize<Int>())
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<kotlin.Int>")!>sequence {
yield(<!DEBUG_INFO_EXPRESSION_TYPE("Inv<kotlin.Int>")!>materialize()<!>)
yield(materialize<Int>())
}<!>
}
fun test_2() {
sequence {
<!INAPPLICABLE_CANDIDATE!>yield<!>(materialize())
yield(materialize())
}
}
fun test_3() {
sequence {
<!INAPPLICABLE_CANDIDATE!>yield<!>(materialize<Int>())
yield(materialize<Int>())
materialize()
}
}
@@ -1,34 +0,0 @@
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION
import kotlin.experimental.ExperimentalTypeInference
abstract class AnimationVector
class AnimationVector1D : AnimationVector()
interface PropKey<T, V : AnimationVector>
class IntPropKey : PropKey<Int, AnimationVector1D>
abstract class AnimationBuilder<T>
abstract class DurationBasedAnimationBuilder<T> : AnimationBuilder<T>()
class TweenBuilder<T> : DurationBasedAnimationBuilder<T>()
class TransitionSpec<S> {
fun <T> tween(init: TweenBuilder<T>.() -> Unit): DurationBasedAnimationBuilder<T> = TweenBuilder<T>().apply(init)
infix fun <T, V : AnimationVector> PropKey<T, V>.using(builder: AnimationBuilder<T>) {}
}
class TransitionDefinition<T> {
fun transition(fromState: T? = null, toState: T? = null, init: TransitionSpec<T>.() -> Unit) {}
}
@OptIn(ExperimentalTypeInference::class)
fun <T> transitionDefinition(@BuilderInference init: TransitionDefinition<T>.() -> Unit) = TransitionDefinition<T>().apply(init)
fun main() {
val intProp = IntPropKey()
val defn = transitionDefinition {
transition(1, 2) {
intProp using tween {
}
}
}
<!DEBUG_INFO_EXPRESSION_TYPE("TransitionDefinition<kotlin.Any?>")!>defn<!>
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION
@@ -1,20 +0,0 @@
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_PARAMETER
import kotlin.experimental.ExperimentalTypeInference
fun test() {
flow {
<!INAPPLICABLE_CANDIDATE!>emit<!>(42)
kotlin.coroutines.coroutineContext
}
}
@OptIn(ExperimentalTypeInference::class)
fun <T> flow(@BuilderInference block: suspend FlowCollector<T>.() -> Unit): Flow<T> = TODO()
interface Flow<out T>
interface FlowCollector<in T> {
suspend fun emit(value: T)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_PARAMETER
@@ -1,22 +0,0 @@
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
@file:OptIn(ExperimentalTypeInference::class)
import kotlin.experimental.ExperimentalTypeInference
class GenericController<T> {
suspend fun yield(t: T) {}
}
fun <S> generate(@BuilderInference g: suspend GenericController<S>.() -> Unit): List<S> = TODO()
val test1 = generate {
<!INAPPLICABLE_CANDIDATE!>yield<!>(generate {
yield(generate {
yield(generate {
yield(3)
})
})
})
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
@@ -18,7 +18,7 @@ suspend fun <S> GenericController<List<S>>.yieldGenerate(g: suspend GenericContr
val test1 = generate {
// TODO: KT-15185
<!INAPPLICABLE_CANDIDATE!>yieldGenerate<!> {
<!INAPPLICABLE_CANDIDATE!>yield<!>(4)
yieldGenerate {
yield(4)
}
}
@@ -21,7 +21,7 @@ fun <S> Builder<S>.extensionAdd(s: S) {}
fun <S> Builder<S>.safeExtensionAdd(s: S) {}
val member = build {
<!INAPPLICABLE_CANDIDATE!>add<!>(42)
add(42)
}
val memberWithoutAnn = wrongBuild {
@@ -29,9 +29,9 @@ val memberWithoutAnn = wrongBuild {
}
val extension = build {
<!INAPPLICABLE_CANDIDATE!>extensionAdd<!>("foo")
extensionAdd("foo")
}
val safeExtension = build {
<!INAPPLICABLE_CANDIDATE!>safeExtensionAdd<!>("foo")
safeExtensionAdd("foo")
}
@@ -1,34 +0,0 @@
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
@file:OptIn(ExperimentalTypeInference::class)
import kotlin.experimental.ExperimentalTypeInference
class GenericController<T> {
suspend fun yield(t: T) {}
suspend fun yieldSet(t: Set<T>) {}
suspend fun yieldVararg(vararg t: T) {}
}
fun <S> generate(@BuilderInference g: suspend GenericController<S>.() -> Unit): S = TODO()
val test1 = generate {
<!INAPPLICABLE_CANDIDATE!>yield<!>(4)
}
val test2 = generate {
<!INAPPLICABLE_CANDIDATE!>yieldSet<!>(setOf(1, 2, 3))
}
val test3 = generate {
<!INAPPLICABLE_CANDIDATE!>yieldVararg<!>(1, 2, 3)
}
val test4 = generate {
<!INAPPLICABLE_CANDIDATE!>yieldVararg<!>(1, 2, "")
}
// Util function
fun <X> setOf(vararg x: X): Set<X> = TODO()
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
@@ -16,9 +16,9 @@ fun <S> generate(@BuilderInference g: suspend Controller<S>.() -> Unit): S = TOD
class A
val test1 = generate {
<!INAPPLICABLE_CANDIDATE!>yield<!>(A)
yield(A)
}
val test2: Int = generate {
<!INAPPLICABLE_CANDIDATE!>yield<!>(A())
yield(A())
}
@@ -1,17 +0,0 @@
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
@file:OptIn(ExperimentalTypeInference::class)
import kotlin.experimental.ExperimentalTypeInference
class GenericController<T>
fun <S> generate(@BuilderInference g: suspend GenericController<S>.() -> Unit): List<S> = TODO()
@BuilderInference
suspend fun GenericController<List<String>>.test() {}
val test1 = generate {
<!INAPPLICABLE_CANDIDATE!>test<!>()
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
@@ -21,13 +21,13 @@ suspend fun <S> GenericController<S>.safeExtensionYield(s: S) {}
fun <S> generate(@BuilderInference g: suspend GenericController<S>.() -> Unit): List<S> = TODO()
val normal = generate {
<!INAPPLICABLE_CANDIDATE!>yield<!>(42)
yield(42)
}
val extension = generate {
<!INAPPLICABLE_CANDIDATE!>extensionYield<!>("foo")
extensionYield("foo")
}
val safeExtension = generate {
<!INAPPLICABLE_CANDIDATE!>safeExtensionYield<!>("foo")
safeExtensionYield("foo")
}
@@ -84,10 +84,10 @@ fun test() {
with(this) {
yield("")
this@with.yield("")
this@with.<!UNRESOLVED_REFERENCE!>yield<!>("")
yield2("")
this@with.yield2("")
this@with.<!INAPPLICABLE_CANDIDATE!>yield2<!>("")
}
}
}