61 lines
1.7 KiB
Plaintext
61 lines
1.7 KiB
Plaintext
== Why is this an issue?
|
|
|
|
The Kotlin collections API has methods that allow developers to overcome type-safety restriction of the parameter, such as `Iterable.contains`. When the actual type of the object provided to these methods is not consistent with the target collection's actual type, those methods will always return `false` or `null`. This is most likely unintended and hides a design problem.
|
|
|
|
|
|
This rule raises an issue when the type of the argument of the following APIs is unrelated to the type used for the collection declaration:
|
|
|
|
* `MutableCollection.remove`
|
|
* `MutableCollection.removeAll`
|
|
* `MutableCollection.retainAll`
|
|
* `Array.contains`
|
|
* `Array.indexOf`
|
|
* `Array.lastIndexOf`
|
|
* `Collection.containsAll`
|
|
* `Iterable.contains`
|
|
* `Iterable.indexOf`
|
|
* `Iterable.lastIndexOf`
|
|
* `List.indexOf`
|
|
* `List.lastIndexOf`
|
|
* `Map.contains`
|
|
* `Map.containsKey`
|
|
* `Map.containsValue`
|
|
* `Map.get`
|
|
* `MutableMap.remove`
|
|
|
|
|
|
|
|
=== Noncompliant code example
|
|
|
|
[source,kotlin]
|
|
----
|
|
fun main(args: Array<String>) {
|
|
val map: MutableMap<Int, Any> = mutableMapOf()
|
|
map.remove<Any, Any>("42") // Noncompliant; will return 'null' for sure because 'map' is handling only Integer keys
|
|
|
|
// ...
|
|
val list: MutableList<String> = mutableListOf()
|
|
val integer = Integer.valueOf(1)
|
|
if (list.contains<Any>(integer)) { // Noncompliant; always false.
|
|
list.remove<Any>(integer) // Noncompliant; list.add(integer) doesn't compile, so this will always return 'false'
|
|
}
|
|
}
|
|
----
|
|
|
|
=== Compliant solution
|
|
|
|
[source,kotlin]
|
|
----
|
|
fun main(args: Array<String>) {
|
|
val map: MutableMap<Int, Any> = mutableMapOf()
|
|
map.remove(42)
|
|
|
|
// ...
|
|
val list: MutableList<String> = mutableListOf()
|
|
val str = ""
|
|
if (list.contains(str)) {
|
|
list.remove(str)
|
|
}
|
|
}
|
|
----
|