Add "Ambiguous context due to scope receiver in suspend fun" inspection

#KT-28696 Fixed
This commit is contained in:
Mikhail Glukhikh
2018-12-04 16:16:22 +03:00
parent 44da3c89b7
commit a15b47c93c
43 changed files with 883 additions and 26 deletions
@@ -0,0 +1 @@
org.jetbrains.kotlin.idea.inspections.coroutines.SuspendFunctionOnCoroutineScopeInspection
@@ -0,0 +1,12 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
fun doSomething() {}
fun foo() {
val scope = object : CoroutineScope {
suspend fun foo() {
<caret>async { doSomething() }
}
}
}
@@ -0,0 +1,13 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
fun doSomething() {}
fun foo() {
val scope = object : CoroutineScope {
suspend fun foo() {
coroutineScope { async { doSomething() } }
}
}
}
@@ -0,0 +1,8 @@
// FIX: Remove receiver & wrap with 'coroutineScope { ... }'
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
fun calcSomething() = 42
suspend fun <caret>CoroutineScope.foo() = async { calcSomething() }
@@ -0,0 +1,8 @@
// FIX: Remove receiver & wrap with 'coroutineScope { ... }'
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
fun calcSomething() = 42
suspend fun foo() = coroutineScope { async { calcSomething() } }
@@ -0,0 +1,15 @@
// FIX: Wrap call with 'coroutineScope { ... }'
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
fun calcSomething() {}
suspend fun CoroutineScope.foo() {
async {
calcSomething()
}
<caret>async {
calcSomething()
}
}
@@ -0,0 +1,18 @@
// FIX: Wrap call with 'coroutineScope { ... }'
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
fun calcSomething() {}
suspend fun CoroutineScope.foo() {
async {
calcSomething()
}
coroutineScope {
async {
calcSomething()
}
}
}
@@ -0,0 +1,10 @@
// FIX: Wrap call with 'coroutineScope { ... }'
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineContext
fun use(context: CoroutineContext) {}
suspend fun CoroutineScope.foo() {
use(<caret>coroutineContext)
}
@@ -0,0 +1,11 @@
// FIX: Wrap call with 'coroutineScope { ... }'
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineContext
import kotlinx.coroutines.coroutineScope
fun use(context: CoroutineContext) {}
suspend fun CoroutineScope.foo() {
use(coroutineScope { coroutineContext })
}
@@ -0,0 +1,10 @@
// FIX: Wrap call with 'coroutineScope { ... }'
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineContext
fun use(context: CoroutineContext) {}
suspend fun CoroutineScope.foo() {
use(this@foo.<caret>coroutineContext)
}
@@ -0,0 +1,11 @@
// FIX: Wrap call with 'coroutineScope { ... }'
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineContext
import kotlinx.coroutines.coroutineScope
fun use(context: CoroutineContext) {}
suspend fun CoroutineScope.foo() {
use(coroutineScope { coroutineContext })
}
@@ -0,0 +1,10 @@
// FIX: Wrap call with 'coroutineScope { ... }'
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineContext
fun use(context: CoroutineContext) {}
suspend fun CoroutineScope.foo() {
use(this.<caret>coroutineContext)
}
@@ -0,0 +1,11 @@
// FIX: Wrap call with 'coroutineScope { ... }'
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineContext
import kotlinx.coroutines.coroutineScope
fun use(context: CoroutineContext) {}
suspend fun CoroutineScope.foo() {
use(coroutineScope { this.coroutineContext })
}
@@ -0,0 +1,8 @@
// FIX: Convert receiver to parameter
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
fun calcSomething() = 42
suspend fun <caret>CoroutineScope.foo() = async { calcSomething() }
@@ -0,0 +1,8 @@
// FIX: Convert receiver to parameter
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
fun calcSomething() = 42
suspend fun foo(coroutineScope: CoroutineScope) = coroutineScope.async { calcSomething() }
@@ -0,0 +1,46 @@
package kotlinx.coroutines
interface Deferred<T> {
suspend fun await(): T
}
interface CoroutineContext
object Dispatchers {
object Default : CoroutineContext
}
enum class CoroutineStart {
DEFAULT,
LAZY,
ATOMIC,
UNDISPATCHED
}
interface CoroutineScope {
val coroutineContext: CoroutineContext get() = Dispatchers.Default
}
object GlobalScope : CoroutineScope
fun <T> CoroutineScope.async(
context: CoroutineContext = Dispatchers.Default,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
): Deferred<T> {
TODO()
}
suspend fun <T> withContext(
context: CoroutineContext,
block: suspend CoroutineScope.() -> T
): T {
TODO()
}
suspend fun <R> coroutineScope(block: suspend CoroutineScope.() -> R): R = GlobalScope.block()
operator fun CoroutineContext.plus(other: CoroutineContext): CoroutineContext {
TODO()
}
@@ -0,0 +1,10 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
fun calcSomething() = 42
suspend fun CoroutineScope.foo() {
val deferred = <caret>async {
calcSomething()
}
}
@@ -0,0 +1,13 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
fun calcSomething() = 42
suspend fun CoroutineScope.foo() {
val deferred = coroutineScope {
async {
calcSomething()
}
}
}
@@ -0,0 +1,15 @@
// PROBLEM: none
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineContext
fun use(context: CoroutineContext) {}
abstract class MyCoroutineScope : CoroutineScope {
inner class Inner {
suspend fun foo() {
// Does not work yet (could work)
use(<caret>coroutineContext)
}
}
}
@@ -0,0 +1,21 @@
// FIX: Remove receiver & wrap with 'coroutineScope { ... }'
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
fun calcSomething() {}
suspend fun <caret>CoroutineScope.foo() {
async {
calcSomething()
calcSomething() // ...
/* ... */
calcSomething() /* ... */
calcSomething()
if (true) // ...
calcSomething()
}
}
@@ -0,0 +1,23 @@
// FIX: Remove receiver & wrap with 'coroutineScope { ... }'
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
fun calcSomething() {}
suspend fun foo() {
coroutineScope {
async {
calcSomething()
calcSomething() // ...
/* ... */
calcSomething() /* ... */
calcSomething()
if (true) // ...
calcSomething()
}
}
}
@@ -0,0 +1,10 @@
// FIX: Move to companion object
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
fun calcSomething() = 42
abstract class MyCoroutineScope : CoroutineScope {
suspend fun <caret>foo() = async { calcSomething() }
}
@@ -0,0 +1,12 @@
// FIX: Move to companion object
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
fun calcSomething() = 42
abstract class MyCoroutineScope : CoroutineScope {
companion object {
suspend fun foo(myCoroutineScope: MyCoroutineScope) = myCoroutineScope.async { calcSomething() }
}
}
@@ -0,0 +1,8 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
fun calcSomething() = 42
object MyCoroutineScope : CoroutineScope {
suspend fun <caret>foo() = async { calcSomething() }
}
@@ -0,0 +1,9 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
fun calcSomething() = 42
object MyCoroutineScope : CoroutineScope {
suspend fun foo() = coroutineScope { async { calcSomething() } }
}
@@ -0,0 +1,12 @@
// FIX: Remove receiver & wrap with 'coroutineScope { ... }'
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
fun calcSomething() {}
suspend fun <caret>CoroutineScope.foo() {
async {
calcSomething()
}
}
@@ -0,0 +1,14 @@
// FIX: Remove receiver & wrap with 'coroutineScope { ... }'
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
fun calcSomething() {}
suspend fun foo() {
coroutineScope {
async {
calcSomething()
}
}
}
@@ -0,0 +1,12 @@
// FIX: Remove receiver & wrap with 'coroutineScope { ... }'
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
fun calcSomething() {}
suspend fun <caret>CoroutineScope.foo() {
this.async {
calcSomething()
}
}
@@ -0,0 +1,14 @@
// FIX: Remove receiver & wrap with 'coroutineScope { ... }'
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
fun calcSomething() {}
suspend fun foo() {
coroutineScope {
this.async {
calcSomething()
}
}
}
@@ -0,0 +1,10 @@
// FIX: Wrap function body with 'coroutineScope { ... }'
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
fun calcSomething() = 42
abstract class MyCoroutineScope : CoroutineScope {
suspend fun <caret>foo() = this.async { calcSomething() }
}
@@ -0,0 +1,11 @@
// FIX: Wrap function body with 'coroutineScope { ... }'
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
fun calcSomething() = 42
abstract class MyCoroutineScope : CoroutineScope {
suspend fun foo() = coroutineScope { this.async { calcSomething() } }
}
@@ -0,0 +1,14 @@
// FIX: Remove receiver & wrap with 'coroutineScope { ... }'
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
fun calcSomething() {}
class My {
suspend fun <caret>CoroutineScope.foo() {
this@foo.async {
calcSomething()
}
}
}
@@ -0,0 +1,16 @@
// FIX: Remove receiver & wrap with 'coroutineScope { ... }'
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
fun calcSomething() {}
class My {
suspend fun foo() {
coroutineScope {
async {
calcSomething()
}
}
}
}
@@ -0,0 +1,15 @@
// PROBLEM: none
// DISABLE-ERRORS
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
fun calcSomething() {}
class My {
suspend fun <caret>CoroutineScope.foo() {
this@My.async {
calcSomething()
}
}
}
@@ -0,0 +1,17 @@
// FIX: Remove receiver & wrap with 'coroutineScope { ... }'
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
fun calcSomething() {}
suspend fun <caret>CoroutineScope.foo() {
async {
calcSomething()
}
}
suspend fun test() {
GlobalScope.foo()
}
@@ -0,0 +1,18 @@
// FIX: Remove receiver & wrap with 'coroutineScope { ... }'
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
fun calcSomething() {}
suspend fun foo() {
coroutineScope {
async {
calcSomething()
}
}
}
suspend fun test() {
foo()
}
@@ -0,0 +1,12 @@
// FIX: Remove receiver & wrap with 'coroutineScope { ... }'
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
fun calcSomething() = 42
suspend fun <caret>CoroutineScope.foo() {
val deferred = async {
calcSomething()
}
}
@@ -0,0 +1,14 @@
// FIX: Remove receiver & wrap with 'coroutineScope { ... }'
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
fun calcSomething() = 42
suspend fun foo() {
coroutineScope {
val deferred = async {
calcSomething()
}
}
}