Repository: detekt/detekt (kotlin)

Issue:
[CouldBeSequence] Use of `asSequence` method should not be count against the `allowedOperations`
<!-- The bug you're experiencing might have already be reported! -->
<!-- Please search in the [issues](https://github.com/detekt/detekt/issues) before creating one. -->

## Expected Behavior
```kt
// allowed function call config is set to 2
private val subject = CouldBeSequence(TestConfig("allowedOperations" to 2))
@Test
fun `using asSequence after allowed number of operations should not trigger rule`() {
    val code = """
        fun foo() = listOf<String?>("bar")
            .mapIndexed { index, it ->  it?.let { it + "_" + index } }
            .filterNotNull()
            .asSequence()
    """.trimIndent()
    assertThat(subject.lintWithContext(env, code)).isEmpty()
}
```
above TC should pass

## Observed Behavior
Above mentioned TC is failing

## Steps to Reproduce
Run against the latest main branch

## Context
<!-- How has this issue affected you? What are you trying to accomplish? -->
<!-- Providing context helps us come up with a solution that is most useful in the real world -->

## Your Environment
<!-- Include as many relevant details about the environment you experienced the bug in -->
* Version of detekt used: Latest main branch(00ccb8c3691089c40529a2ac510c1ce3ffbc23f8) of the detekt

Pull request:
…Sequences.kt`

Fixes https://github.com/detekt/detekt/issues/8776

Patch:
diff --git a/detekt-rules-performance/src/main/kotlin/dev/detekt/rules/performance/CouldBeSequence.kt b/detekt-rules-performance/src/main/kotlin/dev/detekt/rules/performance/CouldBeSequence.kt
index b51662d15e4..f0c9166baf7 100644
--- a/detekt-rules-performance/src/main/kotlin/dev/detekt/rules/performance/CouldBeSequence.kt
+++ b/detekt-rules-performance/src/main/kotlin/dev/detekt/rules/performance/CouldBeSequence.kt
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.analysis.api.types.symbol
 import org.jetbrains.kotlin.name.StandardClassIds
 import org.jetbrains.kotlin.psi.KtCallExpression
 import org.jetbrains.kotlin.psi.KtExpression
+import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression
 import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForReceiver
 import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
 
@@ -68,14 +69,19 @@ class CouldBeSequence(config: Config) :
         }
     }
 
-    private fun KtExpression.isCallingCollectionFunPresentInSequenceReturningSequence(): Boolean = analyze(this) {
-        val callableId = resolveToCall()
-            ?.singleCallOrNull<KaCallableMemberCall<*, *>>()
-            ?.symbol
-            ?.callableId
-        callableId?.packageName == StandardClassIds.BASE_COLLECTIONS_PACKAGE &&
-            findTopLevelCallables(StandardClassIds.BASE_SEQUENCES_PACKAGE, callableId.callableName)
-                .any { it.returnType.symbol?.classId?.asFqNameString() == SEQUENCE_CLASS_STR }
+    private fun KtExpression.isCallingCollectionFunPresentInSequenceReturningSequence(): Boolean {
+        ((this as? KtCallExpression)?.getCallNameExpression()?.getReferencedName())?.let {
+            if (it in listOfAllowedFunFromCollections) return false
+        }
+        return analyze(this) {
+            val callableId = resolveToCall()
+                ?.singleCallOrNull<KaCallableMemberCall<*, *>>()
+                ?.symbol
+                ?.callableId
+            callableId?.packageName == StandardClassIds.BASE_COLLECTIONS_PACKAGE &&
+                findTopLevelCallables(StandardClassIds.BASE_SEQUENCES_PACKAGE, callableId.callableName)
+                    .any { it.returnType.symbol?.classId?.asFqNameString() == SEQUENCE_CLASS_STR }
+        }
     }
 
     private fun KtExpression.nextChainedCall(): KtExpression? {
@@ -85,5 +91,6 @@ class CouldBeSequence(config: Config) :
 
     companion object {
         private const val SEQUENCE_CLASS_STR = "kotlin.sequences.Sequence"
+        private val listOfAllowedFunFromCollections = listOf("asSequence")
     }
 }


Test patch:
diff --git a/detekt-rules-performance/src/test/kotlin/dev/detekt/rules/performance/CouldBeSequenceSpec.kt b/detekt-rules-performance/src/test/kotlin/dev/detekt/rules/performance/CouldBeSequenceSpec.kt
index f1a102dae80..da18b198149 100644
--- a/detekt-rules-performance/src/test/kotlin/dev/detekt/rules/performance/CouldBeSequenceSpec.kt
+++ b/detekt-rules-performance/src/test/kotlin/dev/detekt/rules/performance/CouldBeSequenceSpec.kt
@@ -214,4 +214,15 @@ class CouldBeSequenceSpec(val env: KotlinEnvironmentContainer) {
         """.trimIndent()
         assertThat(subject.lintWithContext(env, code)).hasSize(1)
     }
+
+    @Test
+    fun `using asSequence after allowed number of operations should not trigger rule - #8776`() {
+        val code = """
+            fun foo() = listOf<String?>("bar")
+                .mapIndexed { index, it ->  it?.let { it + "_" + index } }
+                .filterNotNull()
+                .asSequence()
+        """.trimIndent()
+        assertThat(subject.lintWithContext(env, code)).isEmpty()
+    }
 }