Create rule S6527: Function chain using "filter" should be simplified (#1645)
Co-authored-by: Marco Kaufmann <marco.kaufmann@sonarsource.com> Co-authored-by: Angelo Buono <angelo.buono@sonarsource.com>
This commit is contained in:
parent
743cf27c9c
commit
ad5fe749c8
25
rules/S6527/kotlin/metadata.json
Normal file
25
rules/S6527/kotlin/metadata.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"title": "Function chain using \"filter\" should be simplified",
|
||||
"type": "CODE_SMELL",
|
||||
"code": {
|
||||
"impacts": {
|
||||
"MAINTAINABILITY": "LOW"
|
||||
},
|
||||
"attribute": "EFFICIENT"
|
||||
},
|
||||
"status": "ready",
|
||||
"remediation": {
|
||||
"func": "Constant\/Issue",
|
||||
"constantCost": "5min"
|
||||
},
|
||||
"tags": [
|
||||
],
|
||||
"defaultSeverity": "Major",
|
||||
"ruleSpecification": "RSPEC-6527",
|
||||
"sqKey": "S6527",
|
||||
"scope": "All",
|
||||
"defaultQualityProfiles": [
|
||||
"Sonar way"
|
||||
],
|
||||
"quickfix": "unknown"
|
||||
}
|
52
rules/S6527/kotlin/rule.adoc
Normal file
52
rules/S6527/kotlin/rule.adoc
Normal file
@ -0,0 +1,52 @@
|
||||
== Why is this an issue?
|
||||
|
||||
The `filter(predicate)` function is used to extract a subset of elements from a collection that match a given predicate.
|
||||
Many collection functions such as `any()`, `count()`, `first()`, and more, come with an optional condition predicate.
|
||||
|
||||
It is not recommended to invoke the `filter(predicate)` function prior to these terminal operations.
|
||||
Instead, the predicate variant of the terminal operation should be used as a replacement.
|
||||
|
||||
=== What is the potential impact?
|
||||
|
||||
Using `filter(predicate)` before terminal operations can result in unnecessary iterations over the collection, which could negatively impact the performance of the code, especially with large collections. By directly using the predicate variant of the function, you can streamline the code and improve its efficiency and readability.
|
||||
|
||||
== How to fix it
|
||||
|
||||
Replace the `filter(predicate)` call with the predicate variant of the terminal operation.
|
||||
As of Kotlin API version 1.8, the list of terminal operations supporting a predicate is:
|
||||
|
||||
* `any()`
|
||||
* `none()`
|
||||
* `count()`
|
||||
* `first()`, `firstOrNull()`
|
||||
* `last()`, `lastOrNull()`
|
||||
* `single()`, `singleOrNull()`
|
||||
|
||||
=== Code examples
|
||||
|
||||
==== Noncompliant code example
|
||||
|
||||
[source,kotlin,diff-id=1,diff-type=noncompliant]
|
||||
----
|
||||
val list = listOf(5,2,9,6,8,2,5,7,3)
|
||||
val hasElementsGreater5 = list.filter { it > 5 }.any() // Noncompliant
|
||||
val countElementsGreater5 = list.filter { it > 5 }.count() // Noncompliant
|
||||
val lastElementGreater5 = list.filter { it > 5 }.lastOrNull() // Noncompliant
|
||||
----
|
||||
|
||||
==== Compliant solution
|
||||
|
||||
[source,kotlin,diff-id=1,diff-type=compliant]
|
||||
----
|
||||
val list = listOf(5,2,9,6,8,2,5,7,3)
|
||||
val hasElementsGreater5 = list.any { it > 5 } // Compliant
|
||||
val countElementsGreater5 = list.count { it > 5 } // Compliant
|
||||
val lastElementGreater5 = list.lastOrNull { it > 5 } // Compliant
|
||||
----
|
||||
|
||||
== Resources
|
||||
|
||||
=== Documentation
|
||||
|
||||
* https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/[Kotlin API Docs, Package kotlin.collections]
|
||||
|
2
rules/S6527/metadata.json
Normal file
2
rules/S6527/metadata.json
Normal file
@ -0,0 +1,2 @@
|
||||
{
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user