Repository: detekt/detekt (kotlin)

Issue:
Remove suspend lambda parameter with CoroutineScope receiver rule
> There is no clear answer yet which uses [of marking suspend CoroutineScope.() -> Unit] have to be prohibited and which shouldn't

https://youtrack.jetbrains.com/issue/KT-52042/Clarifying-suspend-lambda-and-function-with-coroutineScope-as-pa#focus=Comments-27-6029021.0-0
So I would revert marking the lambda parameter too and focus on `suspend fun CoroutineScope.foo` only.

_Originally posted by @hfhbd in https://github.com/detekt/detekt/issues/4616#issuecomment-1106242397_

Pull request description:
…fined behaviour https://youtrack.jetbrains.com/issue/KTIJ-21167

Fixes #4746

Patch:
diff --git a/detekt-rules-coroutines/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/coroutines/SuspendFunWithCoroutineScopeReceiver.kt b/detekt-rules-coroutines/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/coroutines/SuspendFunWithCoroutineScopeReceiver.kt
index fe5f878d9fc6..463b1b064e74 100644
--- a/detekt-rules-coroutines/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/coroutines/SuspendFunWithCoroutineScopeReceiver.kt
+++ b/detekt-rules-coroutines/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/coroutines/SuspendFunWithCoroutineScopeReceiver.kt
@@ -9,11 +9,8 @@ import io.gitlab.arturbosch.detekt.api.Rule
 import io.gitlab.arturbosch.detekt.api.Severity
 import io.gitlab.arturbosch.detekt.api.internal.RequiresTypeResolution
 import io.gitlab.arturbosch.detekt.rules.fqNameOrNull
-import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
-import org.jetbrains.kotlin.builtins.isSuspendFunctionType
 import org.jetbrains.kotlin.lexer.KtTokens
 import org.jetbrains.kotlin.psi.KtNamedFunction
-import org.jetbrains.kotlin.psi.KtParameter
 import org.jetbrains.kotlin.resolve.BindingContext
 import org.jetbrains.kotlin.types.KotlinType
 import org.jetbrains.kotlin.types.typeUtil.supertypes
@@ -65,23 +62,6 @@ class SuspendFunWithCoroutineScopeReceiver(config: Config) : Rule(config) {
     override fun visitNamedFunction(function: KtNamedFunction) {
         if (bindingContext == BindingContext.EMPTY) return
         checkReceiver(function)
-        checkLambdaParameters(function.valueParameters)
-    }
-
-    private fun checkLambdaParameters(parameters: List<KtParameter>) {
-        for (it in parameters) {
-            val type = bindingContext[BindingContext.VALUE_PARAMETER, it]
-                ?.type?.takeIf { it.isSuspendFunctionType } ?: continue
-            if (type.getReceiverTypeFromFunctionType()?.isCoroutineScope() == true) {
-                report(
-                    CodeSmell(
-                        issue = issue,
-                        entity = Entity.Companion.from(it),
-                        message = "`suspend` function uses CoroutineScope as receiver."
-                    )
-                )
-            }
-        }
     }
 
     private fun checkReceiver(function: KtNamedFunction) {


Test patch:
diff --git a/detekt-rules-coroutines/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/coroutines/SuspendFunWithCoroutineScopeReceiverSpec.kt b/detekt-rules-coroutines/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/coroutines/SuspendFunWithCoroutineScopeReceiverSpec.kt
index 94564ddc6389..80924a523a0c 100644
--- a/detekt-rules-coroutines/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/coroutines/SuspendFunWithCoroutineScopeReceiverSpec.kt
+++ b/detekt-rules-coroutines/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/coroutines/SuspendFunWithCoroutineScopeReceiverSpec.kt
@@ -126,88 +126,6 @@ class SuspendFunWithCoroutineScopeReceiverSpec(val env: KotlinCoreEnvironment) {
         }
     }
 
-    @Nested
-    inner class SuspendFunWithCoroutineScopeLambda {
-
-        @Test
-        fun `reports when lambda parameter has suspend and explicit CoroutineScope receiver type`() {
-            val code = """
-                import kotlinx.coroutines.CoroutineScope
-                import kotlinx.coroutines.launch
-                import kotlinx.coroutines.delay
-                import kotlinx.coroutines.coroutineScope
-
-                suspend fun foo(action: suspend CoroutineScope.() -> Unit) = coroutineScope {
-                    action()
-                }
-            """
-            assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
-        }
-
-        @Test
-        fun `reports when lambda parameter has suspend and inherited CoroutineScope receiver type`() {
-            val code = """
-                import kotlinx.coroutines.CoroutineScope
-                import kotlinx.coroutines.launch
-                import kotlinx.coroutines.delay
-                import kotlinx.coroutines.coroutineScope
-
-                interface TestScope: CoroutineScope
-
-                suspend fun foo(action: suspend TestScope.() -> Unit) = coroutineScope {
-                    val scope = object: TestScope, CoroutineScope by this { }
-                    scope.action()
-                }
-            """
-            assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
-        }
-
-        @Test
-        fun `no report when lambda parameter has only CoroutineScope receiver type`() {
-            val code = """
-                import kotlinx.coroutines.CoroutineScope
-                import kotlinx.coroutines.launch
-                import kotlinx.coroutines.delay
-                import kotlinx.coroutines.coroutineScope
-
-                suspend fun foo(action: CoroutineScope.() -> Unit) = coroutineScope {
-                    action()
-                }
-            """
-            assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
-        }
-
-        @Test
-        fun `no report when suspend lambda parameter has no CoroutineScope receiver type`() {
-            val code = """
-                import kotlinx.coroutines.CoroutineScope
-                import kotlinx.coroutines.launch
-                import kotlinx.coroutines.delay
-                import kotlinx.coroutines.coroutineScope
-
-                suspend fun foo(action: suspend Int.() -> Unit) {
-                    1.action()
-                }
-            """
-            assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
-        }
-
-        @Test
-        fun `no report when suspend lambda parameter has no receiver`() {
-            val code = """
-                import kotlinx.coroutines.CoroutineScope
-                import kotlinx.coroutines.launch
-                import kotlinx.coroutines.delay
-                import kotlinx.coroutines.coroutineScope
-
-                suspend fun foo(action: suspend () -> Unit) {
-                    action()
-                }
-            """
-            assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
-        }
-    }
-
     @Nested
     inner class SuspendCoroutineFunWithCoroutineScopeLambda {
 
@@ -223,7 +141,7 @@ class SuspendFunWithCoroutineScopeReceiverSpec(val env: KotlinCoreEnvironment) {
                     action()
                 }
             """
-            assertThat(subject.compileAndLintWithContext(env, code)).hasSize(2)
+            assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
         }
     }
 }