Repository: detekt/detekt (kotlin)

Issue:
ThrowsCount rule does not report violations in override functions
## Expected Behavior

Should report a violation of `ThrowsCount` (assuming a threshold of max 2 `throw` statements):

```kotlin
            override fun f3(x: Int) {
                when (x) {
                    1 -> throw IOException()
                    2 -> throw IOException()
                    3 -> throw IOException()
                }
            }
```
The use of the `override` keyword should not alter the outcome.

## Observed Behavior

Does not report a violation of `ThrowsCount`:

```kotlin
            override fun f3(x: Int) {
                when (x) {
                    1 -> throw IOException()
                    2 -> throw IOException()
                    3 -> throw IOException()
                }
            }
```

Does report a violation of `ThrowsCount`:

```kotlin
            fun f3(x: Int) {
                when (x) {
                    1 -> throw IOException()
                    2 -> throw IOException()
                    3 -> throw IOException()
                }
            }
```

## Steps to Reproduce

The above examples are taken from `ThrowsCountSpec.kt`.

## Context

When splitting code from ordinary classes into interfaces and implementing classes, detekt no longer provides value even though the function body is exactly the same.

In [this discussion](https://github.com/detekt/detekt/discussions/6723) we established that the rule should be changed to include override functions as well.

## Your Environment
* Version of detekt used: 1.23.4 and older

Pull request:
Fixes #6752.

Patch:
diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ThrowsCount.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ThrowsCount.kt
index 2be446876409..635eaa8b95c9 100644
--- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ThrowsCount.kt
+++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ThrowsCount.kt
@@ -8,7 +8,6 @@ import io.gitlab.arturbosch.detekt.api.Rule
 import io.gitlab.arturbosch.detekt.api.config
 import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault
 import io.gitlab.arturbosch.detekt.api.internal.Configuration
-import io.gitlab.arturbosch.detekt.rules.isOverride
 import io.gitlab.arturbosch.detekt.rules.yieldStatementsSkippingGuardClauses
 import org.jetbrains.kotlin.psi.KtNamedFunction
 import org.jetbrains.kotlin.psi.KtThrowExpression
@@ -53,31 +52,29 @@ class ThrowsCount(config: Config = Config.empty) : Rule(config) {
 
     override fun visitNamedFunction(function: KtNamedFunction) {
         super.visitNamedFunction(function)
-        if (!function.isOverride()) {
-            val statements = if (excludeGuardClauses) {
-                function.yieldStatementsSkippingGuardClauses<KtThrowExpression>()
-            } else {
-                function.bodyBlockExpression?.statements?.asSequence().orEmpty()
-            }
+        val statements = if (excludeGuardClauses) {
+            function.yieldStatementsSkippingGuardClauses<KtThrowExpression>()
+        } else {
+            function.bodyBlockExpression?.statements?.asSequence().orEmpty()
+        }
 
-            val countOfThrows = statements
-                .flatMap { statement ->
-                    statement.collectDescendantsOfType<KtThrowExpression> {
-                        it.getStrictParentOfType<KtNamedFunction>() == function
-                    }.asSequence()
-                }
-                .count()
+        val countOfThrows = statements
+            .flatMap { statement ->
+                statement.collectDescendantsOfType<KtThrowExpression> {
+                    it.getStrictParentOfType<KtNamedFunction>() == function
+                }.asSequence()
+            }
+            .count()
 
-            if (countOfThrows > max) {
-                report(
-                    CodeSmell(
-                        issue,
-                        Entity.atName(function),
-                        "Too many throw statements in the function" +
-                            " ${function.nameAsSafeName}. The maximum number of allowed throw statements is $max."
-                    )
+        if (countOfThrows > max) {
+            report(
+                CodeSmell(
+                    issue,
+                    Entity.atName(function),
+                    "Too many throw statements in the function" +
+                        " ${function.nameAsSafeName}. The maximum number of allowed throw statements is $max."
                 )
-            }
+            )
         }
     }
 }


Test patch:
diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ThrowsCountSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ThrowsCountSpec.kt
index 974a0aefc1b8..14a6e0269d50 100644
--- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ThrowsCountSpec.kt
+++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ThrowsCountSpec.kt
@@ -76,7 +76,7 @@ class ThrowsCountSpec {
     @Nested
     inner class `code with an override function with 3 throw expressions` {
         val code = """
-            override fun f3(x: Int) { // does not report overridden function
+            override fun f3(x: Int) {
                 when (x) {
                     1 -> throw IOException()
                     2 -> throw IOException()
@@ -88,7 +88,7 @@ class ThrowsCountSpec {
 
         @Test
         fun `reports violation by default`() {
-            assertThat(subject.lint(code)).isEmpty()
+            assertThat(subject.lint(code)).hasSize(1)
         }
     }