Create rule S6518: Element access should use indexed access operators (#1629)

This commit is contained in:
github-actions[bot] 2023-04-06 17:29:17 +02:00 committed by GitHub
parent 7d9da451e0
commit 1436cf13b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 89 additions and 0 deletions

View File

@ -0,0 +1,17 @@
{
"title": "Element access should use indexed access operators",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
],
"defaultSeverity": "Major",
"ruleSpecification": "RSPEC-6518",
"sqKey": "S6518",
"scope": "All",
"defaultQualityProfiles": ["Sonar way"],
"quickfix": "unknown"
}

View File

@ -0,0 +1,70 @@
== Why is this an issue?
The primary purpose of classes that implement indexed access operators is that of element access,
like this is the case for arrays, lists, maps, or sets.
When a class implements indexed access operators, they should be used as operators instead of calling them as functions,
because this is the intention of the designer of the API.
=== What is the potential impact?
==== Readability and Understanding
This change makes it easier to understand what a function does,
because the semantics of indexed access operators is evident to the reader,
while for a function call, the reader would need to know what the called function does.
== How to fix it
Replace `instance.get(index)` with `instance[index]`.
Replace `instance.set(index, value)` with `instance[index] = value`.
This also works with multi-index access operators.
=== Code examples
==== Noncompliant code example
[source,kotlin]
----
interface Grid {
operator fun get(row: Int, column: Int): Int
operator fun set(row: Int, column: Int, value: Int)
}
----
[source,kotlin,diff-id=1,diff-type=noncompliant]
----
fun indexedAccess(list: MutableList<Int>, map: MutableMap<String, Int>, grid: Grid) {
list.get(1) // Noncompliant
list.set(1, 42) // Noncompliant
map.get("b") // Noncompliant
map.set("b", 42) // Noncompliant
grid.get(1, 2) // Noncompliant
grid.set(1, 2, 42) // Noncompliant
}
----
==== Compliant solution
[source,kotlin,diff-id=1,diff-type=compliant]
----
fun indexedAccess(list: MutableList<Int>, map: MutableMap<String, Int>, grid: Grid) {
list[1] // Compliant
list[1] = 42 // Compliant
map["b"] // Compliant
map["b"] = 42 // Compliant
grid[1, 2] // Compliant
grid[1, 2] = 42 // Compliant
list.getOrNull(2) // Compliant, because function is not an operator
list.getOrElse(3) {42} // Compliant, because function is not an operator
map.getValue("a") // Compliant, because function is not an operator
map.getOrElse("c") {42} // Compliant, because function is not an operator
}
----
== Resources
=== Documentation
* https://kotlinlang.org/docs/operator-overloading.html#indexed-access-operator[Kotlin Docs, Indexed access operator]

View File

@ -0,0 +1,2 @@
{
}