== 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.

==== Java interop

The issue is also raised when Java API is used as a Kotlin compiler treats all `get(.)` methods as possible index access operators. Use `CompletableFuture[timeout, unit]` instead of `CompletableFuture.get(timeout, unit)` when accessing Java's `CompletableFuture`.


== 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]
