Create rule S6518: Element access should use indexed access operators (#1629)
This commit is contained in:
parent
7d9da451e0
commit
1436cf13b1
17
rules/S6518/kotlin/metadata.json
Normal file
17
rules/S6518/kotlin/metadata.json
Normal 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"
|
||||
}
|
70
rules/S6518/kotlin/rule.adoc
Normal file
70
rules/S6518/kotlin/rule.adoc
Normal 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]
|
2
rules/S6518/metadata.json
Normal file
2
rules/S6518/metadata.json
Normal file
@ -0,0 +1,2 @@
|
||||
{
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user