> ## Documentation Index
> Fetch the complete documentation index at: https://docs.codeant.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Kotlin

> [accordion] Intermediate Sequence and Stream functions should not be left unused
>
> There are two types of sequence and stream operations:
>
> <ul>
>   <li>
>     Intermediate operations, which return another sequence or stream
>   </li>
>
>   <li>
>     Terminal operations, which return something else
>   </li>
> </ul>
>
> Intermediate operations are lazy, meaning they aren’t actually executed until and unless a terminal sequence operation
> is performed on their results. Consequently, if the result of an intermediate sequence operation is not fed to a
> terminal operation, it serves no purpose, which is almost certainly an error.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val sequence = sequenceOf("Hello", " ", "World")
> var totalLength = 0
> sequence.map { totalLength += it.length } // Noncompliant, do nothing, "map" is not a terminal operation
> // here totalLength == 0
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> val stream = listOf("Hello", " ", "World").stream()
> stream.filter { it.isNotBlank() }  // Noncompliant, do nothing, "filter" is not a terminal operation
> // the following "forEach" throws an exception, only one method can operate on a stream instance
> // here "filter" has already operated on it.
> stream.forEach { println(it) }
> ```

> [accordion] Kotlin coroutines API for timeouts should be used
>
> Sometimes there is the need to cancel the execution of a coroutine after a given period of time. You can do this manually by combining the delay() and cancel() functions. However, this technique is verbose and error-prone. An easier way to manage timeouts is using the function withTimeout() or withTimeoutOrNull().
>
> The withTimeout function will throw a TimeoutCancellationException when the timeout is reached, while withTimeoutOrNull will simply return null instead.
>
> This rule raises an issue if timeout mechanisms are implemented manually instead of using appropriate built-in functions.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> suspend fun main() {
> coroutineScope {
>     val job = launch {
>         delay(2000L)
>         println("Finished")
>     }
>     delay(500L)
>     job.cancel()
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> suspend fun main() {
> coroutineScope {
>     withTimeoutOrNull(1000L){
>         delay(2000L)
>         println("Finished")
>     }
> }
> }
> ```

> [accordion] Delegator pattern should use by clause
>
> Kotlin features language support for the delegator pattern using by clauses.
> Because this is a built-in language feature, it should be used
> as an idiom instead of resorting to custom idioms.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> interface Network { fun connect() }
>
> class PoorNetwork : Network {
> override fun connect() { println("cannot connect") }
> }
>
> class GoodNetwork : Network {
> override fun connect() { println("connected") }
> }
>
> interface Graphics { fun render() }
>
> class Nvidia : Graphics {
> override fun render() { println("Neat 3D world") }
> }
>
> class AsusCardFrom2010 : Graphics {
> override fun render() { println("~8 fps") }
> }
>
> abstract class OS : Network, Graphics
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> class Linux : OS() {
> private val network = GoodNetwork()
> override fun connect() = network.connect() // Noncompliant, explicit function delegation
> private val graphics= Nvidia()
> override fun render() = graphics.render() // Noncompliant, explicit function delegation
> // ...
> }
>
> class Windows : OS() {
> private val network = PoorNetwork()
> override fun connect() = network.connect() // Noncompliant, explicit function delegation
> private val graphics = AsusCardFrom2010()
> override fun render() = graphics.render() // Noncompliant, explicit function delegation
> // ...
> }
> ```

> [accordion] Check for preconditions should be simplified
>
> It is a common pattern to validate required preconditions at the beginning of a function or block. There are two different kinds of preconditions:
>
> <ul>
>   <li>
>     Preconditions about argument values. An example is the assertion that a function argument lies within a specific range. An IllegalArgumentException should be thrown if these preconditions are violated.
>   </li>
>
>   <li>
>     Preconditions about the state of the owner or the execution context of the function. An example is when a specific method, such as open, init or prepare, must be called before the current method can be executed. An IllegalStateException should be thrown if these preconditions are violated.
>   </li>
> </ul>
>
> The Kotlin standard library provides the functions check(), require(), checkNotNull() and requireNotNull() for this purpose.
> They should be used instead of directly throwing an IllegalArgumentException or an IllegalStateException.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun argumentPreconditions(argument: Int?, limit: Int?) {
> if (argument == null) throw IllegalArgumentException() // Noncompliant, replace with requireNotNull
> require(limit != null)  // Noncompliant, replace with requireNotNull
> if (argument < 0) throw IllegalArgumentException()  // Noncompliant, replace with require
> if (argument >= 0) throw IllegalArgumentException("Argument < $limit") // Noncompliant, replace with require
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun argumentPreconditions(argument: Int?, limit: Int?) {
> requireNotNull(argument) // Compliant
> requireNotNull(limit) // Compliant
> require(argument >= 0) // Compliant
> require(argument < limit) {"Argument < $limit"} // Compliant
> }
> ```

> [accordion] Logic in configuration phase should be minimized
>
> The logic of a task’s actions, like doFirst and doLast, is only executed when the task is executed.
> Configuration logic (everything outside the action blocks) is executed in the configuration phase for every build,
> whether the task will be executed or not.
>
> Code that could also be moved into the action blocks but resides in the configuration logic can
> inflict a performance penalty.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> tasks.register("printArtifactNames") {
> val libraryNames = configurations.compileClasspath.get().map { it.name } // Non-compliant: "map" is always executed, but the result used in actions only
> doLast {
>     logger.quiet(libraryNames.joinToString())
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> tasks.register("printArtifactNames") {
> val compileClasspath: FileCollection = configurations.compileClasspath.get()
> doLast {
>     val libraryNames = compileClasspath.map { it.name } // Compliant: defined in  action where it is used
>     logger.quiet(libraryNames.joinToString())
> }
> }
> ```

> [accordion] Tasks should define description and group
>
> The actions performed by a task are often too complex or specific,
> and the task name cannot describe the task’s action sufficiently well.
> Moreover, build scripts usually consist of many tasks - whether explicitly defined or implicitly by the applied plugins -
> so a structure is required to help the user navigate through existing tasks.
>
> Therefore, tasks should define a description and group to provide documentation and categorization for the user.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> tasks.register<DocsGenerate>("generateHtmlDocs") { // Noncompliant, does neither define "description" and "group"
> title.set("Project docs")
> outputDir.set(layout.buildDirectory.dir("docs"))
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> tasks.register<DocsGenerate>("generateHtmlDocs") { // Compliant, defines "description" and "group"
> description = "Generates the HTML documentation for this project."
> group = JavaBasePlugin.DOCUMENTATION_GROUP
> title.set("Project docs")
> outputDir.set(layout.buildDirectory.dir("docs"))
> }
> ```

> [accordion] equals(Any?) and hashCode() should be overridden in pairs
>
> In Kotlin, you must override either both or neither of the equals(Any?) and hashCode() methods in order to keep the contract between the two:
>
> <ul>
>   <li>
>     Whenever the hashCode method is invoked on the same object more than once, it must consistently return the same integer, provided no information used in equals comparisons on the object is modified.
>   </li>
>
>   <li>
>     If two objects are equal according to the equals method, then calling the hashCode method on each of the two objects must produce the same integer result.
>   </li>
> </ul>
>
> By overriding only one of the two methods with a non-trivial implementation, this contract is almost certainly broken.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> class MyClass {    // Noncompliant - should also override "hashCode()"
>
> override fun equals(other: Any?): Boolean {
> /* ... */
> }
>
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> class MyClass {    // Compliant
>
> override fun equals(other: Any?): Boolean {
> /* ... */
> }
>
> override fun hashCode(): Int {
> /* ... */
> }
>
> }
> ```

> [accordion] Expression should be simplified with isEmpty, isNotEmpty or isNullOrEmpty
>
> The expression can be simplified using one of the functions isEmpty, isNotEmpty or isNullOrEmpty.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val list = listOf(5,2,9,6,8,2,5,7,3)
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> val hasElemenents = !list.isEmpty() // Noncompliant, use isNotEmpty()
> val hasNoElemenents = list.count() == 0 // Noncomplient, use isEmpty()
>
> fun isNullOrEmpty(list: List<Int>?): Boolean = list == null || list.size == 0 // Noncompliant, use isNullOrEmpty
> ```

> [accordion] Getter and setter pattern should use property getters and setters
>
> Kotlin supports getters and setters for properties.
> Because this is a built-in language feature, it should be the idiom used
> to implement the getter and setter pattern instead of using custom idioms.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> internal class GettersSetters {
> private val length = 100
> private var index: Int = 0
> private var finished: Boolean = false
>
> fun getIndex(): Int { // Noncomplient, use property getter
>     return min(max(0 ,index), length)
> }
>
> fun setIndex(value: Int) { // Noncompliant, use property setter
>     seek(value)
>     index = value
>     finished = value >= length
> }
>
> fun isFinished(): Boolean { // Noncomplient, use property getter
>     return finished
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> internal class GettersSetters {
> private val length = 100
> private var _index: Int = 0
> private var _finished: Boolean = false
>
> var index: Int // Compliant
>     get() = min(max(0 ,index), length)
>     set(value: Int) {
>         seek(value)
>         _index = value
>         _finished = value >= length
>     }
>
> val finished: Boolean // Compliant
>     get() = _finished
> }
> ```

> [accordion] Files opened in append mode should not be used with ObjectOutputStream
>
> An ObjectOutputStream writes primitive data types and graphs of Java objects to an OutputStream.
> The objects can be read (reconstituted) using an ObjectInputStream.
>
> When ObjectOutputStream is used with files opened in append mode, it can cause data corruption and unexpected behavior.
> This is because when ObjectOutputStream is created, it writes metadata to the output stream, which can conflict with the existing
> metadata when the file is opened in append mode. This can lead to errors and data loss.
>
> When used with serialization, an ObjectOutputStream first writes the serialization stream header. This header should appear
> once per file at the beginning.
> When you’re trying to read your object(s) back from the file, only the first one will be read successfully, and a StreamCorruptedException
> will be thrown after that.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val fos = FileOutputStream(fileName, true) // fos opened in append mode
> val out = ObjectOutputStream(fos) // Noncompliant
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> val fos = FileOutputStream(fileName)
> val out = ObjectOutputStream(fos)
> ```

> [accordion] Redundant type casts and type checks should be removed
>
> Kotlin provides the operators as and as? to cast an expression to a specific type,
> and is to check the assignment compatibility with a type.
> These operators are used for downcasts, smart casts, and run-time type checking.
>
> In case the as or as? operator is used for upcasting from a subtype to a supertype,
> the cast is redundant as it has no effect and can never fail.
> If a specific type is expected, an expression of a subtype can always be inserted
> without casting (Substitution Principle and Assignment Compatibility).
>
> Likewise, the is operator is redundant and will always return true if the type of the expression on the left
> side is assignment compatible with the type on the right.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun types(value: Int, elements: List<Number>) {
> val a: Number = value as Number // Noncompliant, Int instance is always a Number
> val b: Number = value as? Number // Noncompliant, Int instance is always a Number
>
> val text = if (value is Number) { // Noncomplient, else-branch is dead code
>     "happens always"
> } else {
>     "impossible"
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun types(value: Number, elements: List<Number>) {
> val a: Int = value as Int // Compliant, Number instance could be an Int
> val b: Int = value as? Int // Compliant, Number instance could be an Int
>
> val text = if (value is Int) { // Compliant, both branches reachable
>     "impossible"
> } else {
>     "happens always"
> }
> }
> ```

> [accordion] find should be replaced with any, none or contains
>
> The functions find(predicate), findLast(predicate), firstOrNull(predicate) and "lastOrNull(predicate)
> can be improperly used to check the presence of an element that matches the given predicate.
> In such cases the code is more difficult to read and understand than it would be with the functions any(predicate), none(predicate) or contains(element).
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun example(list: List<Int>) {
> list.find { it > 5 } != null // Noncompliant
> list.findLast { it > 5 } == null // Noncompliant
> list.firstOrNull { it == 5 } != null // Noncompliant
> list.lastOrNull { x -> x == 5 } != null // Noncompliant
> list.find { x -> 5 == 4 } != null // Noncompliant, note that this case cannot be fixed using contains
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun example(list: List<Int>) {
> list.any { it > 5 } // Compliant
> list.none { it > 5 } // Compliant
> list.contains(5) // Compliant
> !list.contains(5) // Compliant
> list.any { x -> 5 == 4 } // Compliant, note that this case cannot be fixed using contains
> }
> ```

> [accordion] Dependencies should be grouped by destination
>
> Dependencies should be grouped by their destination, otherwise,
> it becomes hard for the reader to see which destination has what dependencies.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> dependencies {
> implementation("org.jetbrains.kotlin:kotlin-stdlib")
> implementation("com.google.guava:guava:30.1.1-jre")
> implementation("org.apache.commons:commons-lang3:3.9")
>
> testImplementation(testLibs.junit.api)
> testRuntimeOnly(testLibs.junit.engine)
>
> testImplementation(testLibs.assertj.core)
> testImplementation(libs.sonar.plugin.api)
>
> implementation("log4j:log4j:1.2.17")
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> dependencies {
> implementation("org.jetbrains.kotlin:kotlin-stdlib")
> implementation("com.google.guava:guava:30.1.1-jre")
> implementation("org.apache.commons:commons-lang3:3.9")
> implementation("log4j:log4j:1.2.17")
>
> testImplementation(testLibs.junit.api)
> testImplementation(testLibs.assertj.core)
> testImplementation(libs.sonar.plugin.api)
>
> testRuntimeOnly(testLibs.junit.engine)
> }
> ```

> [accordion] Map values should be accessed safely
>
> When accessing Map elements by key, you should keep in mind that value might not be present. If value is not present, null will be returned. To make it possible, the type of returned value is nullable. In Kotlin, it’s not usually convenient to operate with nullable types, so developers usually try to avoid them or convert them to non-nullable types. One of the possible solutions is to use !! (non-null assertion operator). If during the runtime the actual value applied to non-null asserrion operator was null, then NullPointerException will be thrown. While in some cases it could still be legitimate to use !!, accesing Map values is not one of them. Usage of a !! when accesing Map values is a bad practice and can lead to NullPointerException in Kotlin and potential crashes, if Java interop was involved.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val l = mapOf(1 to "one", 2 to "two", 3 to "five")
> l.get(123)!! // Noncompliant
> l[123]!! // Noncompliant
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> val l = mapOf(1 to "one", 2 to "two", 3 to "five")
> l.get(123) // Compliant, returns nullable
> l[123] // Compliant, returns nullable
> l.getValue(123) // Compliant, throws NoSuchElementException
> l.getOrElse(123 ) { "empty" } // Compliant, has default
> l.getOrDefault(123, "empty") // Compliant, has default
> l[123] ?: "empty" // Compliant, has default
> ```

> [accordion] when statements should be used instead of chained if statements
>
> The Kotlin when statement can not only be used to compare a selector against a list of values,
> but also to select from a list of conditions.
>
> This is a more readable and elegant alternative to a chain of if statements and should be used instead.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun dispatchFunction(instance: Any) {
> if (instance is Foo) {
>     instance.fooFunction()
> } else if (instance is Bar) {
>     instance.barFunction()
> } else if (instance is Boo) {
>     instance.booFunction()
> } else {
>     throw IllegalArgumentException()
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun dispatchFunction(instance: Any) {
> when (instance) {
>     is Foo -> instance.fooFunction()
>     is Bar -> instance.barFunction()
>     is Boo -> instance.booFunction()
>     else -> throw IllegalArgumentException()
> }
> }
> ```

> [accordion] Variables assigned values should be read
>
> It is common for code to have unnecessary variable assignments. Unnecessary variable assignments make code harder to read and maintain. By avoiding these redundant assignments, your code will be more efficient and understandable.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> var i = 0 // Noncompliant, useless initializer, will be overwritten in the next line
> i = 1 // Noncompliant, the value will be overwritten in the next line
> i = 2
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> var i = 2
> ```

> [accordion] Core plugins IDs should be replaced by their shortcuts
>
> In order to extend the functionalities of your Gradle build you can add plugins with id("plugin-id"). Gradle maintains some plugins that are known as [core plugins](https://docs.gradle.org/current/userguide/plugin_reference.html). These core plugins can be identified by a short name.
>
> When adding core plugins, it is a good practice to use their short name because it is more concise, readable, and less prone to typing mistakes.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> plugins {
> id("org.gradle.java")
> id("org.gradle.jacoco")
> id("org.gradle.maven-publish")
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> plugins {
> java
> jacoco
> `maven-publish`
> }
> ```

> [accordion] Flow intermediate operation results should not be left unused
>
> In Kotlin, Flow represents a cold stream concept. Similar to Stream in Java or Sequence in Kotlin, we can manipulate the data inside the flow (filter, transform, collect, etc). The Flow API, just like Stream and Sequence, offers two types of operations: intermediate and terminal. Intermediate operations again return a Flow instance, all other operations are considered terminal. As flows are naturally lazy, no operations will actually be started until a terminal operation is called.
>
> This rule reports an issue when the result of an intermediate operation on Flow is left unused.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> suspend fun main() {
> val flow = flow {
>     emit(1)
>     emit(2)
>     emit(3)
> }
>
> flow.take(2) // Noncompliant, the result of this operation is never used
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> suspend fun main() {
> val flow = flow {
>     emit(1)
>     emit(2)
>     emit(3)
> }
>
> flow.take(2).collect { println(it) } // Compliant, collect is a terminal operation
> }
> ```

> [accordion] Function chain using filter should be simplified
>
> 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.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> 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
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> 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
> ```

> [accordion] Coroutine usage should adhere to structured concurrency principles
>
> Kotlin coroutines follow the principle of structured concurrency. This helps in preventing resource leaks and ensures that scopes are only exited once all child coroutines have exited. Hence, structured concurrency enables developers to build concurrent applications while having to worry less about cleaning up concurrent tasks manually.
>
> It is possible to break this concept of structured concurrency in various ways. Generally, this is not advised, as it can open the door to coroutines being leaked or lost. Ask yourself if breaking structured concurrency here is really necessary for the application’s business logic, or if it could be avoided by refactoring parts of the code.
>
> This rule raises an issue when it detects that the structured concurrency principles are violated. It avoids reporting on valid use cases and in situations where developers have consciously opted into using delicate APIs (e.g. by using the @OptIn annotation) and hence should be aware of the possible pitfalls.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun main() {
> GlobalScope.launch { // Noncompliant: no explicit opt-in to DelicateCoroutinesApi
> // Do some work
> }.join()
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun startLongRunningBackgroundJob(job: Job) {
> val coroutineScope = CoroutineScope(job)
> coroutineScope.launch(Job()) { // Noncompliant: new job instance passed to launch()
>     // Do some work
> }
> }
> ```

> [accordion] hashCode and toString should not be called on array instances
>
> While \`hashCode and toString are available on arrays, they are largely useless. hashCode returns
> the array’s "identity hash code", and toString returns nearly the same value. Neither method’s output actually
> reflects the array’s contents. Furthermore, contentHashCode() and contentToString() are also useless on
> arrays of array.
>
> Instead, you should use:
>
> <ul>
>   <li>
>     On array of objects or arrays: contentDeepHashCode() and contentDeepToString()
>   </li>
>
>   <li>
>     On array of primitives: contentHashCode() and contentToString()\`
>   </li>
> </ul>
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun main() {
> val primitiveArray = intArrayOf(1, 2, 3)
> val objectArray = arrayOf("A", "B", "C")
> val arrayOfArray = arrayOf(arrayOf("A", "B"), arrayOf("C", "D"))
>
> println(primitiveArray.toString())       // Noncompliant, output: [I@2acf57e3
> println(primitiveArray.hashCode())       // Noncompliant, output: 718231523
> println(objectArray.toString())          // Noncompliant, output: [Ljava.lang.String;@506e6d5e
> println(objectArray.hashCode())          // Noncompliant, output: 1349414238
> println(arrayOfArray.toString())         // Noncompliant, output: [[Ljava.lang.String;@96532d6
> println(arrayOfArray.contentToString())  // Noncompliant, output: [[Ljava.lang.String;@3796751b, [Ljava.lang.String;@67b64c45]
> println(arrayOfArray.hashCode())         // Noncompliant, output: 157627094
> println(arrayOfArray.contentHashCode())  // Noncompliant, output: 586055243
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun main() {
> val primitiveArray = intArrayOf(1, 2, 3)
> val objectArray = arrayOf("A", "B", "C")
> val arrayOfArray = arrayOf(arrayOf("A", "B"), arrayOf("C", "D"))
>
> println(primitiveArray.contentToString())   // Compliant, output: [1, 2, 3]
> println(primitiveArray.contentHashCode())   // Compliant, output: 30817
> println(objectArray.contentDeepToString())  // Compliant, output: [A, B, C]
> println(objectArray.contentDeepHashCode())  // Compliant, output: 94369
> println(arrayOfArray.contentDeepToString()) // Compliant, output: [[A, B], [C, D]]
> println(arrayOfArray.contentDeepHashCode()) // Compliant, output: 98369
> }
> ```

> [accordion] suspend modifier should not be redundant
>
> The suspend function modifier is used to mark a function which might take some time to execute and could suspend the caller coroutine. The location where such function is called is a "suspension point". Functions marked as suspend ("suspending functions") should themselves contain at least one suspension point, otherwise it makes no sense to mark it as suspend
>
> This rule reports an issue if a function with suspend modifier has no calls to other suspend functions inside its body.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> suspend fun function() { // Noncompliant, redundant 'suspend' modifier
> println("Hello!")
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun function() {
> println("Hello!")
> }
> ```

> [accordion] Collection should be immutable if contents is not changed
>
> If a mutable collection type is used but no mutating functions such as add or remove are ever called,
> and the collection instance does not leave the scope of the function,
> it can be replaced with the corresponding immutable collection type.
>
> This is similar to why val should be used instead of var for local variables that are never re-assigned.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun sum123(): Int {
> val list = mutableListOf(1,2,3) // Noncompliant, can be immutable
> return list.reduce { acc, it -> acc + it}
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun sum123(): Int {
> val list = listOf(1,2,3) // Compliant
> return list.reduce { acc, it -> acc + it}
> }
> ```

> [accordion] Singleton pattern should use object declarations or expressions
>
> In Kotlin, object declarations and object expressions are the designed way to implement
> the singleton pattern.
> Because this is a built-in language feature, it should be used
> as an idiom instead of resorting to custom idioms.
>
> An alternative is to declare private constructors
> and to provide a single class instance within a companion object.
> However, this idiom is adopted from other languages like Java which do not feature
> the direct declaration of objects. It should not be used in Kotlin.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> class DeviceManager private constructor() {
> fun instanceMethod() {
>     // ...
> }
>
> companion object { // Noncompliant, explicit class instance provided
>     val instance = DeviceManager()
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> object DeviceManager { // Compliant, object declaration used
> fun instanceMethod() {
>     // ...
> }
> }
> ```

> [accordion] Gradle settings file should always be present
>
> settings.gradle.kts or settings.gradle are used to define general project properties; see the following sample file:
>
> ```kotlin Bad theme={"theme":"css-variables"}
> rootProject.name = "myProject"
>
> include("foo", "bar")
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> rootProject.name = "myProject"
>
> include("module1", "module2")
> ```

> [accordion] Multi-line string literals should not be used in complex expressions
>
> Multi-line string literals representing a big chunk of text should not be used directly in complex expressions, as it decreases the code’s readability. It is preferred to extract the string literal and store it in a variable or a field that can be accessed in the context of the complex expression.
>
> This rule reports an issue when a multi-line string literal consists of more lines than specified in the rule’s parameter and is directly used within a lambda literal.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> listOfString
> .map { str ->
>     str != """
>     <project>
>       <modelVersion>4.0.0</modelVersion>
>       <parent>
>         <groupId>com.mycompany.app</groupId>
>         <artifactId>my-app</artifactId>
>         <version>1</version>
>       </parent>
>
>       <groupId>com.mycompany.app</groupId>
>       <artifactId>my-module</artifactId>
>       <version>1</version>
>     </project>
>     """
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> val myTextBlock = """
> <project>
>   <modelVersion>4.0.0</modelVersion>
>   <parent>
>     <groupId>com.mycompany.app</groupId>
>     <artifactId>my-app</artifactId>
>     <version>1</version>
>   </parent>
>
>   <groupId>com.mycompany.app</groupId>
>   <artifactId>my-module</artifactId>
>   <version>1</version>
> </project>
> """
>
> listOfString.map { str -> str != myTextBlock }
> ```

> [accordion] All code should be reachable
>
> Jump statements (`return, break and continue`) move control flow out of the current code block. So any statements that come after a jump are dead code.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun foo(a: Int): Int {
> var i = 10;
> return a + i;       // Noncompliant 
> i++;                // dead code
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun foo(a: Int): Int {
> var i = 10;
> return a + i;
> }
> ```

> [accordion] PreparedStatement and ResultSet methods should be called with valid indices
>
> PreparedStatement is an object that represents a precompiled SQL statement,
> that can be used to execute the statement multiple times efficiently.
>
> ResultSet is the Java representation of the result set of a database query obtained from a Statement object.
> A default ResultSet object is not updatable and has a cursor that moves forward only.
>
> The parameters in PreparedStatement and ResultSet are indexed beginning at 1, not 0.
> When an invalid index is passed to the PreparedStatement or ResultSet methods, an IndexOutOfBoundsException is thrown.
> This can cause the program to crash or behave unexpectedly, leading to a poor user experience.
>
> This rule raises an issue for the get methods in PreparedStatement and the set methods in ResultSet.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val ps: PreparedStatement = con.prepareStatement("SELECT fname, lname FROM employees where hireDate > ? and salary < ?")
> ps.setDate(0, date) // Noncompliant
> ps.setDouble(3, salary) // Noncompliant
>
> val rs: ResultSet = ps.executeQuery()
> while (rs.next()) {
> val fname: String = rs.getString(0) // Noncompliant
> // ...
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> val ps: PreparedStatement = con.prepareStatement("SELECT fname, lname FROM employees where hireDate > ? and salary < ?")
> ps.setDate(1, date)
> ps.setDouble(2, salary)
>
> val rs: ResultSet = ps.executeQuery()
> while (rs.next()) {
> val fname: String = rs.getString(1)
> // ...
> }
> ```

> [accordion] Collection and array sizes comparisons should make sense
>
> The size of a collection or an array is always greater than or equal to zero. Testing it doesn’t make sense, since the result is always true.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> if (myList.size >= 0) {...} // Noncompliant: always true
>
> boolean result = myArray.size >= 0; // Noncompliant: always true
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> if (myList.size < 0) {...} // Noncompliant: always false
> ```

> [accordion] equals(other: Any?) should test the arguments type
>
> The Any#equals(other: Any?) method is used to compare two objects to see if they are equal.
>
> The other parameter’s type is Any?, this means that an object of any type, as well as null, can be passed as an argument to this method.
>
> Any class overriding Any#equals(other: Any?) should respect this contract, accept any object as an argument, and return false when the
> argument’s type differs from the expected type. The other parameter’s type can be checked using the is operator or by comparing the javaClass field:
>
> ```kotlin Bad theme={"theme":"css-variables"}
> override fun equals(other: Any?): Boolean {
> // ...
> if (other?.javaClass != this.javaClass) {
> return false
> }
> // ...
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> class MyClass {
> override fun equals(other: Any?): Boolean {
> val that = other as MyClass // may throw a ClassCastException
> // ...
> }
> // ...
> }
> ```

> [accordion] Function names should comply with a naming convention
>
> For example, with the default provided regular expression `^[a-zA-Z][a-zA-Z0-9]*$`, the function:
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun _DoSomething() {...} // Noncompliant
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun DoSomething() {...}
> ```

> [accordion] Functional interface implementations should use lambda expressions
>
> Functional interfaces can be instantiated from lambda expressions directly.
> If the only purpose of a class or a singleton object is to implement a functional interface,
> that class or object is redundant and should be replaced with a lambda expression.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun interface ProgressCallback {
> fun progressChanged(percent: Double)
> }
>
> fun loadResource(callback: ProgressCallback) {
> // ...
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> val resource = loadResource(object: ProgressCallback { // Noncompliant
> override fun progressChanged(percent: Double) {
>     // ...
> }
> })
>
> val callback = object: ProgressCallback {
> override fun progressChanged(percent: Double) { // Noncompliant
>     // ...
> }
> }
> ```

> [accordion] MutableStateFlow and MutableSharedFlow should not be exposed
>
> MutableStateFlow and MutableSharedFlow are very convenient for storing and adding updates of some data structures in event-driven paradigm. This is widely used in Android Views for handling updates. While it’s extremely useful to manage such objects inside some class, it’s not recommended to expose them outside of the class.
>
> When properties of the types MutableStateFlow or MutableSharedFlow are accessible from outside of a class, data updates cannot be verified properly anymore. It is generally recommended to have only one class responsible for updating these flows, otherwise inconsistency issues and problems with maintainability, as well as increased error-proneness may be introduced.
>
> To restrict write access, StateFlow or SharedFlow should be used together with private MutableStateFlow or MutableSharedFlow fields.
>
> This rule raises an issue when encountering a public or internal property of the type MutableStateFlow or MutableSharedFlow.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> class MyView : ViewModel() {
>
> val state = MutableStateFlow(State.New)
>
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> class MyView : ViewModel() {
>
> private val _state = MutableStateFlow(State.New)
> val state: StateFlow<LatestNewsUiState> = _uiState
>
> }
> ```

> [accordion] Unicode-aware versions of character classes should be preferred
>
> When using POSIX classes like \p\{Alpha} without the (?U) to include Unicode characters or when using hard-coded character classes like "\[a-zA-Z]", letters outside of the ASCII range, such as umlauts, accented letters or letter from non-Latin languages, won’t be matched. This may cause code to incorrectly handle input containing such letters.
>
> To correctly handle non-ASCII input, it is recommended to use Unicode classes like \p\{IsAlphabetic}. When using POSIX classes, Unicode support should be enabled by using (?U) inside the regex.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> Regex("[a-zA-Z]")
> Regex("\\p{Alpha}")
> Regex("""\p{Alpha}""")
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> Regex("""\p{IsAlphabetic}""") // matches all letters from all languages
> Regex("""\p{IsLatin}""") // matches latin letters, including umlauts and other non-ASCII variations
> Regex("""(?U)\p{Alpha}""")
> Regex("(?U)\\p{Alpha}")
> ```

> [accordion] Suspending functions should be main-safe
>
> Generally speaking, main threads should be available to allow user-facing parts of an application to remain responsive. Long-running blocking operations can significantly reduce threads' availability and are best executed on a designated thread pool.
>
> As a consequence, suspending functions should not block main threads and instead move any long-running blocking tasks off the main thread. This can be done conveniently by using withContext with an appropriate dispatcher. Alternatively, coroutine builders such as launch and async accept an optional CoroutineContext. An appropriate dispatcher could be Dispatchers.IO for long-running blocking IO operations, which can create and shutdown threads on demand.
>
> For some blocking tasks and APIs there may already be suspending alternatives available. When available, these alternatives should be used instead of their blocking counterparts.
>
> This rule raises an issue when the call of a long-running blocking function is detected within a suspending function without the use of an appropriate dispatcher. If non-blocking alternatives to the called function are known, they may be suggested (e.g. use delay(…​) instead of Thread.sleep(…​)).
>
> ```kotlin Bad theme={"theme":"css-variables"}
> class workerClass {
> suspend fun worker(): String {
>     val client = HttpClient.newHttpClient()
>     val request = HttpRequest.newBuilder(URI("https://example.com")).build()
>     return coroutineScope {
>         client.send(request, HttpResponse.BodyHandlers.ofString()).body() // Noncompliant
>     }
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> suspend fun example() {
> ...
> Thread.sleep(1000) // Noncompliant
> ...
> }
> ```

> [accordion] Structural equality tests should use == or !=
>
> In Kotlin, == means structural equality and != structural inequality and both map to the left-side term’s equals() function.
> It is, therefore, redundant to call equals() as a function.
> Also, == and != are more general than equals() and !equals() because it allows either of both operands to be null.
>
> Developers using equals() instead of == or != is often the result of adapting
> styles from other languages like Java, where == means reference equality and != means reference inequality.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> data class Person(
> val name: String,
> val firstName: String,
> val age: Int,
> val address: String
> )
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun checkEquality() {
> val personA = Person("Claus", "Santa", 200, "North Pole")
> val personB = Person("Nicholas", "Saint", 1700, "Myra")
> if (personA.name.equals(personB.name)) { // Noncompliant, should use `==` instead
>     // ...
> }
> if (!personA.equals(personB)) { // Noncompliant, should use `!=` instead
>     // ...
> }
> }
> ```

> [accordion] var should be val if local variable is never re-assigned
>
> If a local variable is never reassigned, it should be declared val to make it a constant within its scope.
> This makes the code easier to read and protects the variable from accidental re-assignments in future code changes.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun resize(): Int {
> var newLength = max(16, 2*bufferLength) // Noncompliant, `newLength` is assigned only once
> allocBuffer(newLength)
> return resize
> }
>
> class MyClass {
> @inject
> private var myVar: Int = 0 // Noncompliant, `myVar` is late initialized and should be declared as such
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun resize(): Int {
> val newLength = max(16, 2*bufferLength) // Compliant
> allocBuffer(newLength)
> return resize
> }
>
> class MyClass {
> @inject
> private lateinit var myVar: Int // Compliant
> }
> ```

> [accordion] Users should not use internal APIs
>
> The public API of a framework, plugin, or library is the way its provider intended it to be used.
> API stability and compatibility (within the same major version number) of a library are guaranteed only for its public API.
>
> Internal APIs are mere implementation details and are prone to breaking changes as the implementation of the library changes.
> No guarantees are being made about them. Therefore, users should not use internal APIs, even when visible.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> if (org.gradle.internal.os.OperatingSystem.current().isWindows) { // Noncompliant, OperatingSystem is part of Gradle internal API
> // ...
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> if (System.getProperty("os.name").toLowerCase().contains("windows")) { // Compliant
> // ...
> }
> ```

> [accordion] Unit should be used instead of Void
>
> Kotlin uses the data type Unit to represent the absence of a value in a function or an expression.
> It corresponds to the type void in Java or unknown in JavaScript.
> While Void is available in Kotlin, it is a Java platform type and not equivalent to Java void but java.lang.Void.
>
> Use Unit instead of Void because it represents the absence of a value in Kotlin.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> typealias NoValueFunction = () -> Void // Noncompliant, `Void` used
>
> interface NoValueFunctions {
> fun voidFunction1(): Void // Noncompliant, `Void` used
> fun voidFunction2(): Void // Noncompliant, `Void` used
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> typealias NoValueFunction = () -> Unit // Compliant, `Unit` used
>
> interface NoValueFunctions {
> fun unitFunction1(): Unit // Compliant, `Unit` used
> fun unitFunction2() // Compliant, `Unit` used implicitly
> }
> ```

> [accordion] Null checks should be useful
>
> In Kotlin, nullability is a part of the type system.
> By default, any given type T is non-nullable.
> If you append a "?" to the type, it becomes nullable: T?.
>
> When accessing properties or functions of a nullable type, you need to handle the case when the target is null.
> However, while accessing a non-nullable type, it is redundant to test for null, as the compiler statically ensures that the value can never be null.
> So all the nullability checks on the non-nullable types are considered code smells.
>
> On the other hand, performing a null-check on a value that is always null is equally as redundant.
>
> Here is an example of a non-nullable variable.
> s is of a type String and cannot be null.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val s: String = ""
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> val s: String? = null
> ```

> [accordion] rootProject.name should always be present in Gradle settings
>
> settings.gradle.kts or settings.gradle are used to define general project properties.
>
> It is a good practice to specify the rootProject.name property to set your project name and avoid inconsistencies. By default, Gradle uses the project directory name as the project name and this is not guaranteed to always be the desired behavior.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> include("module1", "module2")
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> rootProject.name = "myProject"
> include("module1", "module2")
> ```

> [accordion] Collections should not be passed as arguments to their own methods
>
> Passing a collection as an argument to the collection’s own method is either an error - some other argument was intended - or simply nonsensical code.
>
> Further, because some methods require that the argument remain unmodified during the execution, passing a collection to itself can result in undefined behavior.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val objs = mutableListOf<Any>()
> objs.add("Hello")
>
> objs.add(objs) // Noncompliant; StackOverflowException if objs.hashCode() called
> objs.addAll(objs) // Noncompliant; behavior undefined
> objs.containsAll(objs) // Noncompliant; always true
> objs.removeAll(objs) // Noncompliant; confusing. Use clear() instead
> objs.retainAll(objs) // Noncompliant; NOOP
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> val newList = mutableListOf<Any>()
> val objs = mutableListOf<Any>()
> objs.add("Hello")
>
> objs.containsAll(newList) // Compliant
> objs.addAll(newList) // Compliant
> objs.removeAll(newList) // Compliant
> objs.retainAll(newList) // Compliant
> ```

> [accordion] when clauses should not have too many lines of code
>
> The `when` statement should be used only to clearly define some new branches in the control flow. As soon as a case clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of the case clause should be extracted into a dedicated function.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> when (myVariable) {
> 0 -> {// Noncompliant: 6 lines till next case
> methodCall1("");
> methodCall2("");
> methodCall3("");
> methodCall4("");
> }
> 1 -> {
> ...
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> when (myVariable) {
> 0 -> doSomething()
> 1 -> {
> ...
> }
> }
> ...
> fun doSomething() {
> methodCall1("");
> methodCall2("");
> methodCall3("");
> methodCall4("");
> }
> ```

> [accordion] Dispatchers should be injectable
>
> Dispatchers should not be hardcoded when using withContext or creating new coroutines using launch or async. Injectable dispatchers ease testing by allowing tests to inject more deterministic dispatchers.
>
> You can use default values for the dispatcher constructor arguments to eliminate the need to specify them explicitly in the production caller contexts.
>
> This rule raises an issue when it finds a hard-coded dispatcher being used in withContext or when starting new coroutines.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> class ExampleClass {
> suspend fun doSomething() {
>     withContext(Dispatchers.Default) { // Noncompliant: hard-coded dispatcher
>         ...
>     }
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> class ExampleClass(
> private val dispatcher: CoroutineDispatcher = Dispatchers.Default
> ) {
> suspend fun doSomething() {
>     withContext(dispatcher) {
>         ...
>     }
> }
> }
> ```

> [accordion] Type casts and type checks that can never succeed should be removed
>
> Kotlin provides the operators as and as? to cast an expression to a specific type,
> and is to check the assignment compatibility with a type.
> These operators are used for downcasts, smart casts, and run-time type checking.
>
> In case the as or as? operator is used for casting between incompatible types,
> that is, distinct types and neither being a subtype of the other,
> the cast will never succeed but always throw a ClassCastException.
> This results in dead code and is likely a symptom of wrong program logic.
>
> Likewise, the is operator is redundant and will never return true if the type of the expression on the left
> side is incompatible with the type on the right.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun types(value: String, elements: List<String>) {
> val a: Int = value as Int // Noncompliant, throws ClassCastException
> val b: Int = value as? Int // Noncompliant, will always be null
>
> val text = if (value is Int) { // Noncomplient, then-branch is dead code
>     "impossible"
> } else {
>     "happens always"
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun types(value: Number, elements: List<Number>) {
> val a: Int = value as Int // Compliant, a Number instance could be an Int
> val b: Int = value as? Int // Compliant, a Number instance could be an Int
>
> val text = if (value is Int) { // Compliant, both branches reachable
>     "impossible"
> } else {
>     "happens always"
> }
> }
> ```

> [accordion] All branches in a conditional structure should not have exactly the same implementation
>
> Having all branches of a when or if chain with the same implementation indicates a problem.
>
> In the following code:
>
> ```kotlin Bad theme={"theme":"css-variables"}
> if (b == 0) {  // Noncompliant
>  doOneMoreThing()
> } else {
>  doOneMoreThing()
> }
>
> when (i) {  // Noncompliant
> 1 -> doSomething()
> 2 -> doSomething()
> 3 -> doSomething()
> else -> doSomething()
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> if (b == 0) {
> doOneMoreThing()
> } else if (b == 1) {
> doOneMoreThing()
> }
> ```

> [accordion] Operator is should be used instead of isInstance()
>
> The is construction is a preferred way to check whether a variable can be cast to some type statically because a compile-time error will occur in case of incompatible types. The isInstance() functions from [kotlin.reflect.KClass](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-class/is-instance.html) and [java.lang.Class](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#isInstance-java.lang.Object-) work differently and type check at runtime only. Incompatible types will therefore not be detected as early during development, potentially resulting in dead code. isInstance() function calls should only be used in dynamic cases when the is operator can’t be used.
>
> This rule raises an issue when isInstance() is used and could be replaced with an is check.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun f(o: Any): Int {
> if (String::class.isInstance(o)) {  // Noncompliant
>     return 42
> }
> return 0
> }
>
> fun f(n: Number): Int {
> if (String::class.isInstance(n)) {  // Noncompliant
>     return 42
> }
> return 0
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun f(o: Any): Int {
> if (o is String) {  // Compliant
>     return 42
> }
> return 0
> }
>
> fun f(n: Number): Int {
> if (n is String) {  // Compile-time error
>     return 42
> }
> return 0
> }
>
> fun f(o: Any, c: String): Boolean {
> return Class.forName(c).isInstance(o) // Compliant, can't use "is" operator here
> }
> ```

> [accordion] Extension functions on CoroutineScopes should not be declared as suspend
>
> There are two ways to define asynchronous functions in Kotlin:
>
> <ul>
>   <li>
>     using the modifier suspend in the function declaration
>   </li>
>
>   <li>
>     creating an extension function on CoroutineScope (or passing it as a parameter)
>   </li>
> </ul>
>
> The suspend modifier is generally used for functions that might take some time to complete. The caller coroutine might be potentially suspended.
>
> Functions that return results immediately but start a coroutine in the background should be written as extension functions on CoroutineScope. At the same time, these functions should not be declared suspend, as suspending functions should not leave running background tasks behind.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> suspend fun CoroutineScope.f(): Int {
> val resource1 = loadResource1()
> val resource2 = loadResource2()
> return resource1.size + resource2.size
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> suspend fun f(): Int {
> val resource1 = loadResource1()
> val resource2 = loadResource2()
> return resource1.size + resource2.size
> }
> ```

> [accordion] Element access should use indexed access operators
>
> 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.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> interface Grid {
> operator fun get(row: Int, column: Int): Int
> operator fun set(row: Int, column: Int, value: Int)
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> 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
> }
> ```

> [accordion] Redundant methods should be avoided in data classes
>
> Data classes have autogenerated implementations of equals, hashcode, toString, copy and componentN. Although the former three methods can still be overridden, there is no use to do so if no special logic is required. The latter two methods cannot be overridden and cause a compile-time error if attempted.
>
> This rule reports an issue on simple equals and hashCode implementations with no additional logic beyond the default behaviour.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> data class Person(val name: String, val age: Int) {
> override fun equals(other: Any?): Boolean { // Noncompliant
>     return other is Person && other.name == name && other.age == age
> }
>
> override fun hashCode() = Objects.hash(name, age) // Noncompliant
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> data class Person(String name, int age) // Compliant
>
> data class Person(val name: String, val age: Int) {
> override fun equals(other: Any?): Boolean { // Compliant
>     return other is Person && other.name.lowercase() == name.lowercase() && other.age == age
> }
>
> override fun hashCode() = Objects.hash(name.lowercase(), age) // Compliant
> }
> ```

> [accordion] Dependency versions shouldnt be hard-coded
>
> In general hard-coded values is a well known bad practice that affects maintainability.
> In dependency management, this issue is even more critical because there is the risk of accidentally having different versions for the same dependency in your configuration.
>
> Keeping hard-coded dependency versions increases the cost of maintainability and complicates the update process.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> dependencies {
> testImplementation("org.mockito:mockito-core:4.5.1")
> testImplementation("org.mockito:mockito-inline:4.5.1")
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> const val mockitoVersion = "4.5.1"
>
> dependencies {
> testImplementation("org.mockito:mockito-core:$mockitoVersion")
> testImplementation("org.mockito:mockito-inline:$mockitoVersion")
> }
> ```

> [accordion] Custom tasks and plugins should be placed in buildSrc directory
>
> Custom tasks and plugins should be moved from the build script to the buildSrc directory
> to encapsulate custom build logic and separate it against its application in the build script.
>
> This helps to keep the build script clean and easy to understand.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> open class MyCustomTask : DefaultTask() {
> // ...
> }
>
> tasks.register<MyCustomTask>("myCustom")
>
> open class MyCustomExtension {
> var flag: Boolean = false
> }
>
> extensions.create<MyCustomExtension>("myCustomExtension")
>
> val myCustomExtension: MyCustomExtension by project
>
> myCustomExtension.flag = true
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> package mypackage
>
> import org.gradle.api.DefaultTask
>
> open class MyCustomTask : DefaultTask() {
> // ...
> }
> ```

> [accordion] return statements should be lifted before if or when statement
>
> In Kotlin, if and when statements are expressions that return a value.
> This allows for a more concise and functional programming style with less cognitive complexity,
> because it results in fewer return points and fewer variable assignments in a function.
>
> If both branches of an if statement end with a return statement,
> the if statement should be used instead as an expression for a return statement.
>
> If all branches of an exhaustive when statement end with a return statement,
> the when statement should be used instead as an expression for a return statement.
> A when statement is exhaustive when it covers all elements of an enum or features an else clause.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun returnIfElse(value: Int): String {
> // ...
> if (value >= 0) { // Noncompliant, every branch contains a return statement
>     return "positive"
> } else {
>     return "negative"
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun returnIfElse(value: Int): String {
> // ...
> return if (value >= 0) { // Compliant
>     "positive"
> } else {
>     "negative"
> }
> }
> ```

> [accordion] Loops should not be infinite
>
> An infinite loop is one that will never end while the program is running, i.e., you have to kill the program to get out of the loop. Whether it is by meeting the loop’s end condition or via a `break`, every loop should have an end condition.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> var j: Int
> while (true) { // Noncompliant; end condition omitted
> j++
> }
>
> var k: Int
> val b = true
> while (b) { // Noncompliant; b never written to in loop
> k++
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> var j: Int = 0
> while (true) { // reachable end condition added
> j++
> if (j == Int.MIN_VALUE) {  // true at Integer.MAX_VALUE +1
>     break
> }
> }
>
> var k: Int = 0
> var b = true
> while (b) {
> k++
> b = k < Int.MAX_VALUE
> }
> ```

> [accordion] Suspending functions should not be called on a different dispatcher
>
> By convention, calls to suspending functions should not block the thread, eliminating the requirement of calling suspending functions on background threads. Any long-running blocking operations should be moved to background threads within the suspending function that performs these operations. If suspending functions do block, this is breaking the Kotlin coroutines conventions (also see [S6307](https://github.com/SonarSource/rspec/pull/173)).
>
> As suspending functions can generally be called directly within other suspending functions, there is no need to move such a call to a background thread. This does not bring much benefit while adding complexity and making the code harder to understand.
>
> In fact, various libraries explicitly provide suspending APIs for otherwise long-running blocking operations. The complexity of moving the appropriate tasks to background threads is already taken care of within the library and does not have to be considered when calling the library’s suspending API.
>
> Note also, however, that suspending functions do not block by convention. This behavior is not enforced on a technical level, leaving it to the developer to ensure the conventions are actually followed. If a suspending library function not under the control of a developer is actually blocking, then calling it in a different thread can work around the issues caused by the poorly written suspending function. It should be preferred to fix the callee, however, and not make such workarounds common practice.
>
> This rule raises an issue when a suspending function is called in a way that executes the call in a new thread.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> suspend fun caller() = coroutineScope {
> async(Dispatchers.IO) {
>     callee()
> }
> }
>
> suspend fun callee() {
> // Do some work
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> suspend fun caller() = coroutineScope {
> async {
>     callee()
> }
> }
>
> suspend fun callee() {
> // Do some work
> }
> ```

> [accordion] ViewModel classes should create coroutines
>
> Views should not be responsible for directly triggering coroutines. Hence, ViewModel classes should prefer creating coroutines instead of exposing suspending functions to perform some piece of business logic. This allows for easier testing of your application, as ViewModel classes can be unit tested, whereas views require instrumentation tests.
>
> Please refer to the [Android docs](https://developer.android.com/kotlin/coroutines/coroutines-best-practices#viewmodel-coroutines) for more advanced examples and mechanisms of updating the views with data generated asynchronously.
>
> This rule raises an issue when suspending functions are exposed by classes inheriting from ViewModel.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> class MyViewModel : ViewModel() {
> suspend fun performAction() = suspendingWorker()
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> class MyViewModel : ViewModel() {
> fun performAction() =
>     viewModelScope.launch {
>         suspendingWorker()
>     }
> }
> ```

> [accordion] The return value of functions returning Deferred should be used
>
> Some functions return kotlinx.coroutines.Deferred to eventually communicate the result of an asynchronous operation. This is necessary, as callers do not wait for the result of an operation when it is launched asynchronously. Even if the result may be relevant later on, other tasks can be completed while waiting for the asynchronous operation’s result to become available. Hence, to avoid blocking the caller, functions can trigger a task to be run and then immediately return a Deferred instance, which will contain the result once the background task is complete.
>
> Deferred (aka Future, Promise, etc) provides an await() function, which suspends the caller coroutine until the asynchronous task is complete and returns the result of the execution. By not using the Deferred return value, the result of the corresponding asynchronously launched task is lost. This could point to an issue in the code, where data is not passed along as intended.
>
> For instance, the Kotlin coroutines API provides both the functions async and launch as ways to launch asynchronous work. The key difference here is their return type. launch starts a new coroutine without blocking the current thread and returns a reference to the coroutine as a Job. This function is not designed to return a result, i.e. follows the idea of "fire and forget". async creates a coroutine and returns its future result as an implementation of Deferred.
>
> Ask yourself whether:
>
> <ul>
>   <li>
>     You really need whatever result is calculated by the asynchronous operation. If not, you may be better off using a function that does not return Deferred.
>   </li>
>
>   <li>
>     You should be using the Deferred return value and fetching some data from it later on, for instance by calling await() on it.
>   </li>
> </ul>
>
> This rule raises an issue when a function returning the type kotlinx.coroutines.Deferred is used without the result of the operation being retrieved.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> suspend fun doSomething() {
> coroutineScope { // Noncompliant
>     async {
>         // Do some work
>         "result"
>     }
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> suspend fun doSomething() {
> coroutineScope {
>     launch {
>         // Do some work
>     }
> }
> }
> ```

> [accordion] Functions returning Flow/Channel should not be suspending
>
> There are two ways to define asynchronous functions in Kotlin:
>
> <ul>
>   <li>
>     using the modifier suspend in the function declaration
>   </li>
>
>   <li>
>     creating an extension function on CoroutineScope
>   </li>
> </ul>
>
> The suspend modifier is generally used for functions that might take some time to complete. The caller coroutine might potentially be suspended.
>
> Functions that start a coroutine in the background and return before said coroutine has completed running should be extension functions on CoroutineScope. This helps to clarify the intention of such a function. Further, such functions should not be suspending, as suspending functions should only return once all the work they are designed to perform is complete.
>
> Functions returning Flow or Channel should return the result immediately and may start a new coroutine in the background. As a consequence, such functions should not be suspending and if they launch a coroutine in the background, they should be declared as extension functions on CoroutineScope.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> suspend fun f(): Flow<Int> {
> val flow = flow {
>     emit(1)
> }
> delay(500L)
> return flow
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> suspend fun f(): Channel<Int> {
> val ch = Channel<Int>()
> ch.send(1)
> return ch
> }
> ```

> [accordion] Equals method should be overridden in data classes containing array fields
>
> In data classes, the default behavior of the equals() method is to check the equality by field values. This works well for primitive fields or fields, whose type overrides equals(), but this behavior doesn’t work as expected for array fields.
>
> By default, array fields are compared by their reference, so overriding equals() is highly recommended to ensure a deep equality check. The same applies to the hashcode() method.
>
> This rule reports an issue if a record class has an array field and is not overriding equals() or hashcode() methods.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> data class Person(val names: Array<String>, val age: Int) {} // Noncompliant
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> data class Person(val names: Array<String>, val age: Int) {
> override fun equals(other: Any?): Boolean {
>     if (this === other) return true
>     if (javaClass != other?.javaClass) return false
>
>     other as Person
>
>     if (!names.contentEquals(other.names)) return false
>     if (age != other.age) return false
>
>     return true
> }
>
> override fun hashCode(): Int {
>     var result = names.contentHashCode()
>     result = 31 * result + age
>     return result
> }
> }
> ```

> [accordion] when statements should not be nested
>
> Nested \`when structures are difficult to understand because you can easily confuse the cases of an inner when as belonging to an outer statement. Therefore nested when statements should be avoided.
>
> Specifically, you should structure your code to avoid the need for nested when statements, but if you cannot, then consider moving the inner when\` to another function.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun foo(n: Int, m: Int) {
> when (n) { 
> 0 ->
>   when (m) {  // Noncompliant; nested when
>     // ...
>   }
> 1 -> print("1")
> else -> print("2")
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun foo(n: Int, m: Int) {
> when (n) { 
> 0 -> bar(m)
> 1 -> print("1")
> else -> print("2")
> }
> }
>
> fun bar(m: Int){
> when(m) {
> // ...
> }
> }
> ```

> [accordion] Inappropriate collection calls should not be made
>
> 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:
>
> <ul>
>   <li>
>     MutableCollection.remove
>   </li>
>
>   <li>
>     MutableCollection.removeAll
>   </li>
>
>   <li>
>     MutableCollection.retainAll
>   </li>
>
>   <li>
>     Array.contains
>   </li>
>
>   <li>
>     Array.indexOf
>   </li>
>
>   <li>
>     Array.lastIndexOf
>   </li>
>
>   <li>
>     Collection.containsAll
>   </li>
>
>   <li>
>     Iterable.contains
>   </li>
>
>   <li>
>     Iterable.indexOf
>   </li>
>
>   <li>
>     Iterable.lastIndexOf
>   </li>
>
>   <li>
>     List.indexOf
>   </li>
>
>   <li>
>     List.lastIndexOf
>   </li>
>
>   <li>
>     Map.contains
>   </li>
>
>   <li>
>     Map.containsKey
>   </li>
>
>   <li>
>     Map.containsValue
>   </li>
>
>   <li>
>     Map.get
>   </li>
>
>   <li>
>     MutableMap.remove
>   </li>
> </ul>
>
> ```kotlin Bad theme={"theme":"css-variables"}
> 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'
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> 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)
> }
> }
> ```

> [accordion] Jump statements should not occur in finally blocks
>
> Using break, continue, return and throw inside of a finally block suppresses the propagation of any unhandled Throwable thrown in the try or catch block.
>
> This rule raises an issue when a jump statement (break, continue, return, throw) would force control flow to leave a finally block.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun main() {
> try {
>     doSomethingWhichThrowsException(5)
>     println("OK") // incorrect "OK" message is printed
> } catch (e: RuntimeException) {
>     println("ERROR") // this message is not shown
> }
> try {
>     doSomethingThatAlsoThrowsException(5)
>     println("OK") // incorrect "OK" message is printed
> } catch (e: RuntimeException) {
>     println("ERROR") // this message is not shown
> }
> }
>
> fun doSomethingWhichThrowsException(q: Int) {
> try {
>     throw RuntimeException()
> } finally {
>     //...
>     if (someOtherCondition) {
>         return  // Noncompliant - prevents the RuntimeException from being propagated
>     }
>     if (aLastConditionIsVerified) {
>         throw IllegalStateException()  // Noncompliant - prevents the RuntimeException from being propagated
>     }
> }
> }
>
> fun doSomethingThatAlsoThrowsException(q: Int) {
> while (someConditionIsVerified) {
>     try {
>         throw RuntimeException()
>     } finally {
>         //...
>         if (someOtherCondition) {
>             continue  // Noncompliant - prevents the RuntimeException from being propagated
>         }
>         break  // Noncompliant - prevents the RuntimeException from being propagated
>     }
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun main() {
> try {
>     doSomethingWhichThrowsException()
>     println("OK")
> } catch (e: RuntimeException) {
>     println("ERROR") // prints "ERROR" as expected
> }
> }
>
> fun doSomethingWhichThrowsException(q: Int) {
> try {
>     throw RuntimeException()
> } finally {
>     while (someConditionIsVerified) {
>         //...
>         if (someOtherCondition) {
>             continue  // Compliant - does not prevent the RuntimeException from being propagated
>
>         }
>         break  // compliant - does not prevent the RuntimeException from being propagated
>     }
> }
> }
> ```

> [accordion] Single function interfaces should be functional interfaces
>
> An interface that declares only a single function should be marked as function interface.
> Function interfaces can be instantiated from lambda expressions directly and are, therefore, more comfortable to use.
>
> Also, consider using a function type instead of a function interface.
> In many situations, a function type is sufficient.
> A function interface is only required when the function must not be anonymous
> or when an object should implement multiple function interfaces at once.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> interface IntMapper<T> { // Noncompliant
> fun map(value: Int): T
> }
>
> interface StringMapper<T> { // Noncompliant
> fun map(value: String): T
> }
>
> @FunctionalInterface  // Noncompliant
> interface ProgressCallback {
> fun progressChanged(percent: Double)
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun interface IntMapper<T> { // Compliant, function interface used
> fun map(value: Int): T
> }
>
> typealias StringMapper<T> = (value: String) -> T // Compliant, functional type used
>
> fun interface ProgressCallback { // Compliant, function interface used
> fun progressChanged(percent: Double)
> }
> ```

> [accordion] tasks.register() should be preferred over tasks.create()
>
> Using the Kotlin Gradle DSL, a task can be defined in several ways:
>
> <ul>
>   <li>
>     tasks.create(…​) will eagerly configure the task, regardless of whether it is required.
>   </li>
>
>   <li>
>     tasks.register(…​) lazily configures the task only when it is required. This happens when it is located using query methods such as TaskCollection.getByName(java.lang.String), when it is added to the task graph for execution, or when Provider.get() is called on the return value of this method.
>   </li>
> </ul>
>
> It is generally more efficient to use tasks.register(…​) instead of tasks.create(…​) as the task will not be configured if it is not needed.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> tasks.create("myTask") {
> group = JavaBasePlugin.DOCUMENTATION_GROUP
> description = "My task."
> // other configuration logic
>
> doLast {
>   // ...
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> tasks.register("myTask") {
> group = JavaBasePlugin.DOCUMENTATION_GROUP
> description = "My task."
> // other configuration logic
>
> doLast {
>   // ...
> }
> }
> ```

> [accordion] Regular expressions should not be too complicated
>
> Overly complicated regular expressions are hard to read and to maintain and can easily cause hard-to-find bugs. If a regex is too complicated, you should consider replacing it or parts of it with regular code or splitting it apart into multiple patterns at least.
>
> The complexity of a regular expression is determined as follows:
>
> Each of the following operators increases the complexity by an amount equal to the current nesting level and also increases the current nesting level by one for its arguments:
>
> <ul>
>   <li>
>     \`| - when multiple | operators are used together, the subsequent ones only increase the complexity by 1
>   </li>
>
>   <li>
>     && (inside character classes) - when multiple && operators are used together, the subsequent ones only increase the complexity by 1
>   </li>
>
>   <li>
>     Quantifiers (\*, +, ?, \{n,m}, \{n,} or \{n})
>   </li>
>
>   <li>
>     Non-capturing groups that set flags (such as (?i:some\_pattern) or (?i)some\_pattern\`)
>   </li>
>
>   <li>
>     Lookahead and lookbehind assertions
>   </li>
> </ul>
>
> Additionally, each use of the following features increase the complexity by 1 regardless of nesting:
>
> <ul>
>   <li>
>     character classes
>   </li>
>
>   <li>
>     back references
>   </li>
> </ul>
>
> If a regular expression is split among multiple variables, the complexity is calculated for each variable individually, not for the whole regular expression. If a regular expression is split over multiple lines, each line is treated individually if it is accompanied by a comment (either a Java comment or a comment within the regular expression), otherwise the regular expression is analyzed as a whole.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> if (dateString.matches(Regex("^(?:(?:31(\\/|-|\\.)(?:0?[13578]|1[02]))\\1|(?:(?:29|30)(\\/|-|\\.)(?:0?[13-9]|1[0-2])\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:29(\\/|-|\\.)0?2\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\\d|2[0-8])(\\/|-|\\.)(?:(?:0?[1-9])|(?:1[0-2]))\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$"))) {
> handleDate(dateString)
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> if (dateString.matches(Regex("^\\d{1,2}([-/.])\\d{1,2}\\1\\d{1,4}$"))) {
> val dateParts = dateString.split("[-/.]").toTypedArray()
> val day = dateParts[0].toInt()
> val month = dateParts[1].toInt()
> val year = dateParts[2].toInt()
> // Put logic to validate and process the date based on its integer parts here
> }
> ```

> [accordion] Using unencrypted databases in mobile applications is security-sensitive
>
> Storing data locally is a common task for mobile applications. Such data includes preferences or authentication tokens for external services, among other things. There are many convenient solutions that allow storing data persistently, for example SQLiteDatabase, SharedPreferences, and Realm. By default these systems store the data unencrypted, thus an attacker with physical access to the device can read them out easily. Access to sensitive data can be harmful for the user of the application, for example when the device gets stolen.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val db = SQLiteDatabase.openOrCreateDatabase("test.db", getKey(), null)
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
> EncryptedSharedPreferences.create(
> "secret",
> masterKeyAlias,
> context,
> EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
> EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
> )
> ```

> [accordion] Boolean checks should not be inverted
>
> It is needlessly complex to invert the result of a boolean comparison. The opposite comparison should be made instead.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> if (!(a == 2)) { ... }  // Noncompliant
> val b = !(i < 10)  // Noncompliant
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> if (a != 2) { ... } 
> val b = (i >= 10)
> ```

> [accordion] Regular expressions should be syntactically valid
>
> Regular expressions have their own syntax that is understood by regular expression engines. Those engines will throw an exception at runtime if they are given a regular expression that does not conform to that syntax.
>
> To avoid syntax errors, special characters should be escaped with backslashes when they are intended to be matched literally and references to capturing groups should use the correctly spelled name or number of the group.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> Regex("([")
> "([".toRegex()
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> Regex("\\(\\[")
> Regex("""\(\[""")
> "\\(\\[".toRegex()
> """\(\[""".toRegex()
>
> Regex("([", RegexOption.LITERAL)
> "([".toRegex(RegexOption.LITERAL)
> ```

> [accordion] Enabling file access for WebViews is security-sensitive
>
> WebViews can be used to display web content as part of a mobile application. A
> browser engine is used to render and display the content. Like a web
> application, a mobile application that uses WebViews can be vulnerable to
> Cross-Site Scripting if untrusted code is rendered.
>
> If malicious JavaScript code in a WebView is executed this can leak the contents
> of sensitive files when access to local files is enabled.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> import android.webkit.WebView
>
> val webView: WebView = findViewById(R.id.webview)
> webView.getSettings().setAllowContentAccess(true) // Sensitive
> webView.getSettings().setAllowFileAccess(true) // Sensitive
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> import android.webkit.WebView
>
> val webView: WebView = findViewById(R.id.webview)
> webView.getSettings().setAllowContentAccess(false)
> webView.getSettings().setAllowFileAccess(false)
> ```

> [accordion] Statements should be on separate lines
>
> Putting multiple statements on a single line lowers the code readability and makes debugging the code more complex.
>
> Unresolved directive in \<stdin> - include::\{noncompliant}\[]
>
> Write one statement per line to improve readability.
>
> Unresolved directive in \<stdin> - include::\{compliant}\[]
>
> ```kotlin Bad theme={"theme":"css-variables"}
> foo(); bar(); // Noncompliant
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> foo();
> bar();
> ```

> [accordion] Expressions should not be too complex
>
> The complexity of an expression is defined by the number of `&&, || and condition ? ifTrue : ifFalse` operators it contains.
>
> A single expression’s complexity should not become too high to keep the code readable.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> if (((condition1 && condition2) || (condition3 && condition4)) && condition5) { ... }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> if ((myFirstCondition() || mySecondCondition()) && myLastCondition()) { ... }
> ```

> [accordion] Delivering code in production with debug features activated is security-sensitive
>
> Development tools and frameworks usually have options to make debugging easier for developers. Although these features are useful during development, they should never be enabled for applications deployed in production. Debug instructions or error messages can leak detailed information about the system, like the application’s path or file names.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> import android.webkit.WebView
>
> WebView.setWebContentsDebuggingEnabled(true) // Sensitive
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> import android.webkit.WebView
>
> WebView.setWebContentsDebuggingEnabled(false)
> ```

> [accordion] Boolean literals should not be redundant
>
> A boolean literal can be represented in two different ways: \{true} or \{false}.
> They can be combined with logical operators (\{ops}) to produce logical expressions that represent truth values.
> However, comparing a boolean literal to a variable or expression that evaluates to a boolean value is unnecessary and can make the code harder to read and understand.
> The more complex a boolean expression is, the harder it will be for developers to understand its meaning and expected behavior, and it will favour the introduction of new bugs.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> if (booleanMethod() || false) { /* ... */ }
> doSomething(!false);
>
> booleanVariable = if (booleanMethod()) true else false;
> booleanVariable = if (booleanMethod()) true else exp;
> booleanVariable = if (booleanMethod()) false else exp;
> booleanVariable = if (booleanMethod()) exp else true;
> booleanVariable = if (booleanMethod()) exp else false;
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> if (booleanMethod()) { /* ... */ }
> doSomething(true);
>
> booleanVariable = booleanMethod();
> booleanVariable = booleanMethod() || exp;
> booleanVariable = !booleanMethod() && exp;
> booleanVariable = !booleanMethod() || exp;
> booleanVariable = booleanMethod() && exp;
> ```

> [accordion] Deprecated code should be removed
>
> This rule is meant to be used as a way to track code which is marked as being deprecated. Deprecated code should eventually be removed.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> @Deprecated("") // Noncompliant
> class Example
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> ```

> [accordion] Using pseudorandom number generators (PRNGs) is security-sensitive
>
> Using pseudorandom number generators (PRNGs) is security-sensitive. For example, it has led in the past to the following vulnerabilities:
>
> <ul>
>   <li>
>     [CVE-2013-6386](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-6386)
>   </li>
>
>   <li>
>     [CVE-2006-3419](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-3419)
>   </li>
>
>   <li>
>     [CVE-2008-4102](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-4102)
>   </li>
> </ul>
>
> When software generates predictable values in a context requiring unpredictability, it may be possible for an attacker to guess the next value that will be generated, and use this guess to impersonate another user or access sensitive information.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val random = SecureRandom() // Compliant
> val bytes = ByteArray(20)
> random.nextBytes(bytes)
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> ```

> [accordion] Mergeable if statements should be combined
>
> Nested code - blocks of code inside blocks of code - is eventually necessary, but increases complexity. This is why keeping the code as flat as possible, by avoiding unnecessary nesting, is considered a good practice.
>
> Merging if statements when possible will decrease the nesting of the code and improve its readability.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> if (condition1) {
> if (condition2) {             // Noncompliant
> /* ... */
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> if (condition1 && condition2) { // Compliant
> /* ... */
> }
> ```

> [accordion] Functions should not be empty
>
> An empty \{operationName} is generally considered bad practice and can lead to confusion, readability, and maintenance issues.
> Empty \{operationName}s bring no functionality and are misleading to others as they might think the \{operationName} implementation fulfills a specific and identified requirement.
>
> There are several reasons for a \{operationName} not to have a body:
>
> <ul>
>   <li>
>     It is an unintentional omission, and should be fixed to prevent an unexpected behavior in production.
>   </li>
>
>   <li>
>     It is not yet, or never will be, supported. In this case an exception should be thrown.
>   </li>
>
>   <li>
>     The method is an intentionally-blank override. In this case a nested comment should explain the reason for the blank override.
>   </li>
> </ul>
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun shouldNotBeEmpty() {  // Noncompliant - method is empty
> }
>
> fun notImplemented() {  // Noncompliant - method is empty
> }
>
> fun emptyOnPurpose() {  // Noncompliant - method is empty
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun shouldNotBeEmpty() {
> doSomething()
> }
>
> fun notImplemented() {
> throw UnsupportedOperationException("notImplemented() cannot be performed because ...")
> }
>
> fun emptyOnPurpose() {
> // comment explaining why the method is empty
> }
> ```

> [accordion] Empty lines should not be tested with regex MULTILINE flag
>
> One way to test for empty lines is to use the regex \`"^\$", which can be extremely handy when filtering out empty lines from collections of Strings, for instance. With regard to this, the Javadoc for [Pattern (Line Terminators)](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/regex/Pattern.html) states the following:
>
> > By default, the regular expressions ^ and $ignore line terminators and only match at the beginning and the end, respectively, of the entire input sequence. If MULTILINE mode is activated then ^ matches at the beginning of input and after any line terminator <strong>except at the end of input</strong>. When in MULTILINE mode$ matches just before a line terminator or the end of the input sequence.
>
> As emphasized, ^ is not going to match at the end of an input, and the end of the input is necessarily included in the empty string, which might lead to completely missing empty lines, while it would be the initial reason for using such regex.
>
> Therefore, when searching for empty lines using a multi-line regular expression, you should also check whether the string is empty.
>
> This rule is raising an issue every time a pattern that can match the empty string is used with MULTILINE flag and without calling isEmpty()\` on the string.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val p = Pattern.compile("^$", Pattern.MULTILINE) // Noncompliant
> val r = Regex("^$", RegexOption.MULTILINE) // Noncompliant
>
> // Alternatively
> val p = Pattern.compile("(?m)^$") // Noncompliant
> val r = Regex("(?m)^$") // Noncompliant
>
> fun containsEmptyLines(str: String) : Boolean {
> return p.matcher(str).find()
> }
>
> fun containsEmptyLinesKotlin(str: String) = r.find(str) != null
>
> // ...
> println(containsEmptyLines("a\n\nb")) // correctly prints 'true'
> println(containsEmptyLinesKotlin("a\n\nb")) // correctly prints 'true'
>
> println(containsEmptyLines("")) // incorrectly prints 'false'
> println(containsEmptyLinesKotlin("")) // incorrectly prints 'false'
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> val p = Pattern.compile("^$", Pattern.MULTILINE) // Noncompliant
> val r = Regex("^$", RegexOption.MULTILINE) // Noncompliant
>
> fun containsEmptyLines(str: String) : Boolean {
> return p.matcher(str).find() || str.isEmpty()
> }
>
> fun containsEmptyLinesKotlin(str: String) = r.find(str) != null || str.isEmpty()
>
> // ...
> println(containsEmptyLines("a\n\nb")) // correctly prints 'true'
> println(containsEmptyLinesKotlin("a\n\nb")) // correctly prints 'true'
>
> println(containsEmptyLines("")) // correctly prints 'true'
> println(containsEmptyLinesKotlin("")) // correctly prints 'true'
> ```

> [accordion] Using clear-text protocols is security-sensitive
>
> Clear-text protocols such as \`ftp, telnet, or http lack
> encryption of transported data, as well as the capability to build an
> authenticated connection. It means that an attacker able to sniff traffic from
> the network can read, modify, or corrupt the transported content. These
> protocols are not secure as they expose applications to an extensive range of
> risks:
>
> <ul>
>   <li>
>     sensitive data exposure
>   </li>
>
>   <li>
>     traffic redirected  to a malicious endpoint
>   </li>
>
>   <li>
>     malware-infected software update or installer
>   </li>
>
>   <li>
>     execution of client-side code
>   </li>
>
>   <li>
>     corruption of critical information
>   </li>
> </ul>
>
> Even in the context of isolated networks like offline environments or segmented
> cloud environments, the insider threat exists. Thus, attacks involving
> communications being sniffed or tampered with can still happen.
>
> For example, attackers could successfully compromise prior security layers by:
>
> <ul>
>   <li>
>     bypassing isolation mechanisms
>   </li>
>
>   <li>
>     compromising a component of the network
>   </li>
>
>   <li>
>     getting the credentials of an internal IAM account (either from a service
>     account or an actual person)
>   </li>
> </ul>
>
> In such cases, encrypting communications would decrease the chances of attackers
> to successfully leak data or steal credentials from other network components.
> By layering various security practices (segmentation and encryption, for
> example), the application will follow the *defense-in-depth* principle.
>
> Note that using the http\` protocol is being deprecated by
> [major web browsers](https://blog.mozilla.org/security/2015/04/30/deprecating-non-secure-http).
>
> In the past, it has led to the following vulnerabilities:
>
> <ul>
>   <li>
>     [CVE-2019-6169](https://nvd.nist.gov/vuln/detail/CVE-2019-6169)
>   </li>
>
>   <li>
>     [CVE-2019-12327](https://nvd.nist.gov/vuln/detail/CVE-2019-12327)
>   </li>
>
>   <li>
>     [CVE-2019-11065](https://nvd.nist.gov/vuln/detail/CVE-2019-11065)
>   </li>
> </ul>
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val telnet = TelnetClient(); // Sensitive
>
> val ftpClient = FTPClient(); // Sensitive
>
> val smtpClient = SMTPClient(); // Sensitive
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> val spec: ConnectionSpec = ConnectionSpec.Builder(ConnectionSpec.CLEARTEXT) // Sensitive
> .build()
> ```

> [accordion] Creating cookies without the HttpOnly flag is security-sensitive
>
> When a cookie is configured with the `HttpOnly attribute set to true, the browser guaranties that no client-side script will be able to read it. In most cases, when a cookie is created, the default value of HttpOnly is false and it’s up to the developer to decide whether or not the content of the cookie can be read by the client-side script. As a majority of Cross-Site Scripting (XSS) attacks target the theft of session-cookies, the HttpOnly` attribute can help to reduce their impact as it won’t be possible to exploit the XSS vulnerability to steal session-cookies.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val c3 = Cookie("admin", "secret")
> c3.setHttpOnly(true) // Compliant: this sensitive cookie is protected against theft (HttpOnly=true)
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> ```

> [accordion] Redundant pairs of parentheses should be removed
>
> The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. However, redundant pairs of parentheses could be misleading and should be removed.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val x = ((y / 2 + 1))  // Noncompliant
>
> if (a && ((x + y > 0))) {  // Noncompliant
> return ((x + 1))  // Noncompliant
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> val x = (y / 2 + 1)
>
> if (a && (x + y > 0)) {
> return (x + 1)
> }
> ```

> [accordion] Accessing Android external storage is security-sensitive
>
> Storing data locally is a common task for mobile applications. Such data includes files among other things. One convenient way to store files is to use the external file storage which usually offers a larger amount of disc space compared to internal storage.
>
> Files created on the external storage are globally readable and writable. Therefore, a malicious application having the permissions WRITE\_EXTERNAL\_STORAGE or READ\_EXTERNAL\_STORAGE could try to read sensitive information from the files that other applications have stored on the external storage.
>
> External storage can also be removed by the user (e.g when based on SD card) making the files unavailable to the application.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> import android.content.Context
> import android.os.Environment
>
> class AccessExternalFiles {
>
> fun accessFiles(Context context) {
>     context.getFilesDir()
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> ```

> [accordion] Unicode Grapheme Clusters should be avoided inside regex character classes
>
> When placing Unicode [Grapheme Clusters](https://unicode.org/glossary/#grapheme_cluster) (characters which require to be encoded in multiple [Code Points](https://unicode.org/glossary/#code_point)) inside a character class of a regular expression, this will likely lead to unintended behavior.
>
> For instance, the grapheme cluster `c̈ requires two code points: one for 'c', followed by one for the umlaut modifier '\u{0308}'. If placed within a character class, such as [c̈], the regex will consider the character class being the enumeration [c\u{0308}] instead. It will, therefore, match every 'c'` and every *umlaut* that isn’t expressed as a single codepoint, which is extremely unlikely to be the intended behavior.
>
> This rule raises an issue every time Unicode Grapheme Clusters are used within a character class of a regular expression.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> "cc̈d̈d".replace(Regex("[c̈d̈]"), "X") // Noncompliant, print "XXXXXX" instead of expected "cXXd".
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> "cc̈d̈d".replace(Regex("c̈|d̈"), "X") // print "cXXd"
> ```

> [accordion] Variables should not be self-assigned
>
> There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun doSomething() {
> var name = ""
> // ...
> name = name
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun doSomething() {
> var name = ""
> // ...
> this.name = name
> }
> ```

> [accordion] if ... else if constructs should end with else clauses
>
> This rule applies whenever an \`if statement is followed by one or more else if statements; the final else if should be followed by an else statement.
>
> The requirement for a final else statement is defensive programming.
>
> The else statement should either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final default clause in a switch\` statement.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> if (x == 0) {
> doSomething()
> } else if (x == 1) {
> doSomethingElse()
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> if (x == 0) {
> doSomething()
> } else if (x == 1) {
> doSomethingElse()
> } else {
> throw IllegalStateException()
> }
> ```

> [accordion] Receiving intents is security-sensitive
>
> Android applications can receive broadcasts from the system or other applications. Receiving intents is security-sensitive. For example, it has led in the past to the following vulnerabilities:
>
> <ul>
>   <li>
>     [CVE-2019-1677](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1677)
>   </li>
>
>   <li>
>     [CVE-2015-1275](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1275)
>   </li>
> </ul>
>
> Receivers can be declared in the manifest or in the code to make them context-specific. If the receiver is declared in the manifest Android will start the application if it is not already running once a matching broadcast is received. The receiver is an entry point into the application.
>
> Other applications can send potentially malicious broadcasts, so it is important to consider broadcasts as untrusted and to limit the applications that can send broadcasts to the receiver.
>
> Permissions can be specified to restrict broadcasts to authorized applications. Restrictions can be enforced by both the sender and receiver of a broadcast. If permissions are specified when registering a broadcast receiver, then only broadcasters who were granted this permission can send a message to the receiver.
>
> This rule raises an issue when a receiver is registered without specifying any broadcast permission.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> import android.content.BroadcastReceiver
> import android.content.Context
> import android.content.IntentFilter
> import android.os.Build
> import android.os.Handler
> import androidx.annotation.RequiresApi
>
> class MyIntentReceiver {
> @RequiresApi(api = Build.VERSION_CODES.O)
> fun register(
>     context: Context, receiver: BroadcastReceiver?,
>     filter: IntentFilter?,
>     broadcastPermission: String?,
>     scheduler: Handler?,
>     flags: Int
> ) {
>     context.registerReceiver(receiver, filter, broadcastPermission, scheduler)
>     context.registerReceiver(receiver, filter, broadcastPermission, scheduler, flags)
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> ```

> [accordion] Creating cookies without the secure flag is security-sensitive
>
> When a cookie is protected with the `secure` attribute set to *true* it will not be send by the browser over an unencrypted HTTP request and thus cannot be observed by an unauthorized person during a man-in-the-middle attack.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val c6 = Cookie("admin", "secret")
> c6.setSecure(true) // Compliant: the sensitive cookie will not be send during an unencrypted HTTP request thanks to the secure flag set to true
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> ```

> [accordion] Using biometric authentication without a cryptographic solution is security-sensitive
>
> Android comes with Android KeyStore, a secure container for storing key materials. It’s possible to define certain keys to be unlocked when users authenticate using biometric credentials. This way, even if the application process is compromised, the attacker cannot access keys, as presence of the authorized user is required.
>
> These keys can be used, to encrypt, sign or create a message authentication code (MAC) as proof that the authentication result has not been tampered with. This protection defeats the scenario where an attacker with physical access to the device would try to hook into the application process and call the \`onAuthenticationSucceeded method directly. Therefore he would be unable to extract the sensitive data or to perform the critical operations protected by the biometric authentication.
>
> ## Ask Yourself Whether
>
> The application contains:
>
> <ul>
>   <li>
>     Cryptographic keys / sensitive information that need to be protected using biometric authentication.
>   </li>
> </ul>
>
> There is a risk if you answered yes to this question.
>
> ## Recommended Secure Coding Practices
>
> It’s recommended to tie the biometric authentication to a cryptographic operation by using a CryptoObject\` during authentication.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> // ...
> val biometricPrompt: BiometricPrompt = BiometricPrompt(activity, executor, callback)
> // ...
> biometricPrompt.authenticate(promptInfo) // Noncompliant
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> // ...
> val biometricPrompt: BiometricPrompt = BiometricPrompt(activity, executor, callback)
> // ...
> biometricPrompt.authenticate(promptInfo, BiometricPrompt.CryptoObject(cipher)) // Compliant
> ```

> [accordion] ScheduledThreadPoolExecutor should not have 0 core threads
>
> \`java.util.concurrent.ScheduledThreadPoolExecutor's pool is sized with corePoolSize, so setting corePoolSize to zero means the executor will have no threads and run nothing.
>
> This rule detects instances where corePoolSize\` is set to zero, via either its setter or the object constructor.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun do() {
>
> val stpe1 = ScheduledThreadPoolExecutor(0) // Noncompliant
>
> val stpe2 = ScheduledThreadPoolExecutor(POOL_SIZE)
> stpe2.corePoolSize = 0 // Noncompliant
>
> ...
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> ```

> [accordion] String literals should not be duplicated
>
> Duplicated string literals make the process of refactoring complex and error-prone, as any change would need to be propagated on all occurrences.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> class A {
> fun run() {
>     prepare("string literal")    // Noncompliant - "string literal" is duplicated 3 times
>     execute("string literal")
>     release("string literal")
> }
>
> fun method() {
>     println("'")                 // Compliant - literal "'" has less than 5 characters and is excluded
>     println("'")
>     println("'")
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> class A {
> companion object {
>     const val CONSTANT = "string literal"
> }
>
> fun run() {
>     prepare(CONSTANT)    // Compliant
>     execute(CONSTANT)
>     release(CONSTANT)
> }
> }
> ```

> [accordion] Values should not be uselessly incremented
>
> A value that is incremented or decremented and then not stored is at best wasted code and at worst a bug.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun pickNumber() : Int {
> var i = 0
> var j = 0
>
> i = i++ // Noncompliant; i is still zero
>
> return j++ // Noncompliant; 0 returned
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun pickNumber() : Int {
> var i = 0
> var j = 0
>
> i++ 
> return ++j 
> }
> ```

> [accordion] Code annotated as deprecated should not be used
>
> Code is sometimes annotated as deprecated by developers maintaining libraries or APIs to indicate that the method, class, or other programming element is no longer recommended for use. This is typically due to the introduction of a newer or more effective alternative. For example, when a better solution has been identified, or when the existing code presents potential errors or security risks.
>
> Deprecation is a good practice because it helps to phase out obsolete code in a controlled manner, without breaking existing software that may still depend on it. It is a way to warn other developers not to use the deprecated element in new code, and to replace it in existing code when possible.
>
> Deprecated classes, interfaces, and their members should not be used, inherited or extended because they will eventually be removed. The deprecation period allows you to make a smooth transition away from the aging, soon-to-be-retired technology.
>
> Check the documentation or the deprecation message to understand why the code was deprecated and what the recommended alternative is.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> @Deprecated("This function is deprecated, use newFunction instead", ReplaceWith("newFunction()"))
> fun oldFunction() {
> println("This is the old function.")
> }
>
> fun newFunction() {
> println("This is the new function.")
> }
>
> oldFunction() // Noncompliant: "oldFunction is deprecated"
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> ```

> [accordion] Enabling JavaScript support for WebViews is security-sensitive
>
> WebViews can be used to display web content as part of a mobile application. A
> browser engine is used to render and display the content. Like a web
> application, a mobile application that uses WebViews can be vulnerable to
> Cross-Site Scripting if untrusted code is rendered. In the context of a WebView,
> JavaScript code can exfiltrate local files that might be sensitive or even
> worse, access exposed functions of the application that can result in more
> severe vulnerabilities such as code injection. Thus JavaScript support should
> not be enabled for WebViews unless it is absolutely necessary and the
> authenticity of the web resources can be guaranteed.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> import android.webkit.WebView
>
> val webView: WebView = findViewById(R.id.webview)
> webView.getSettings().setJavaScriptEnabled(true) // Sensitive
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> import android.webkit.WebView
>
> val webView: WebView = findViewById(R.id.webview)
> webView.getSettings().setJavaScriptEnabled(false)
> ```

> [accordion] Functions should not have identical implementations
>
> Two \{func\_name}s having the same implementation are suspicious.
> It might be that something else was intended. Or the duplication is intentional, which becomes a maintenance burden.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> class MyClass {
> fun calculateCode(): String {
> doTheThing()
> doOtherThing()
> return "done"
> }
>
> fun getStatus(): String {  // Noncompliant: duplicates calculateCode
> doTheThing()
> doOtherThing()
> return "done"
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> class MyClass {
> fun calculateCode(): String {
> doTheThing()
> doOtherThing()
> return "done"
> }
>
> fun getStatus(): String = calculateCode() // Intent is clear
> }
> ```

> [accordion] Using hardcoded IP addresses is security-sensitive
>
> Hardcoding IP addresses is security-sensitive. It has led in the past to the following vulnerabilities:
>
> <ul>
>   <li>
>     [CVE-2006-5901](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-5901)
>   </li>
>
>   <li>
>     [CVE-2005-3725](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2005-3725)
>   </li>
> </ul>
>
> Today’s services have an ever-changing architecture due to their scaling and redundancy needs. It is a mistake to think that a service will always have the same IP address. When it does change, the hardcoded IP will have to be modified too. This will have an impact on the product development, delivery, and deployment:
>
> <ul>
>   <li>
>     The developers will have to do a rapid fix every time this happens, instead of having an operation team change a configuration file.
>   </li>
>
>   <li>
>     It misleads to use the same address in every environment (dev, sys, qa, prod).
>   </li>
> </ul>
>
> Last but not least it has an effect on application security. Attackers might be able to decompile the code and thereby discover a potentially sensitive address. They can perform a Denial of Service attack on the service, try to get access to the system, or try to spoof the IP address to bypass security checks. Such attacks can always be possible, but in the case of a hardcoded IP address solving the issue will take more time, which will increase an attack’s impact.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val ip = System.getenv("myapplication.ip")
> val socket = ServerSocket(ip, 6667)
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> ```

> [accordion] Track uses of TODO tags
>
> Developers often use TODO tags to mark areas in the code where additional work or improvements are needed but are not implemented immediately.
> However, these TODO tags sometimes get overlooked or forgotten, leading to incomplete or unfinished code.
> This rule aims to identify and address unattended TODO tags to ensure a clean and maintainable codebase.
> This description explores why this is a problem and how it can be fixed to improve the overall code quality.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun doSomething() {
> // TODO
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> ```

> [accordion] Using unencrypted files in mobile applications is security-sensitive
>
> Storing files locally is a common task for mobile applications. Files that are stored unencrypted can be read out and modified by an attacker with physical access to the device. Access to sensitive data can be harmful for the user of the application, for example when the device gets stolen.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val mainKey = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
>
> val encryptedFile = EncryptedFile.Builder(
> File(activity.filesDir, "data.txt"),
> activity,
> mainKey,
> EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
> ).build()
>
> encryptedFile.openFileOutput().apply {
> write(fileContent)
> flush()
> close()
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> ```

> [accordion] Character classes in regular expressions should not contain the same character twice
>
> Character classes in regular expressions are a convenient way to match one of several possible characters by listing the allowed characters or ranges of characters. If the same character is listed twice in the same character class or if the character class contains overlapping ranges, this has no effect.
>
> Thus duplicate characters in a character class are either a simple oversight or a sign that a range in the character class matches more than is intended or that the author misunderstood how character classes work and wanted to match more than one character. A common example of the latter mistake is trying to use a range like \[0-99] to match numbers of up to two digits, when in fact it is equivalent to \[0-9]. Another common cause is forgetting to escape the - character, creating an unintended range that overlaps with other characters in the character class.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> Regex("[0-99]") // Noncompliant, this won't actually match strings with two digits
> Regex("[0-9.-_]") // Noncompliant, .-_ is a range that already contains 0-9 (as well as various other characters such as capital letters)
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> Regex("[0-9]{1,2}")
> Regex("[0-9.\\-_]")
> ```

> [accordion] Unused private methods should be removed
>
> This rule raises an issue when a \{visibility} \{operationName} is never referenced in the code.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> class Foo: Serializable {
> private fun unusedMethod() {...}
> private fun writeObject(s: ObjectOutputStream) {...}  // Compliant, relates to the serialization mechanism
> private fun readObject(s: ObjectOutputStream) {...}  // Compliant, relates to the serialization mechanism
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> class Foo: Serializable {
> private fun writeObject(s: ObjectOutputStream) {...}  // Compliant, relates to the serialization mechanism
> private fun readObject(s: ObjectOutputStream) {...}  // Compliant, relates to the serialization mechanism
> }
> ```

> [accordion] Useless if(true) \{...} and if(false)\{...} blocks should be removed
>
> \`if statements with conditions that are always false have the effect of making blocks of code non-functional. if statements with conditions that are always true are completely redundant, and make the code less readable.
>
> There are three possible causes for the presence of such code:
>
> <ul>
>   <li>
>     An if statement was changed during debugging and that debug code has been committed.
>   </li>
>
>   <li>
>     Some value was left unset.
>   </li>
>
>   <li>
>     Some logic is not doing what the programmer thought it did.
>   </li>
> </ul>
>
> In any of these cases, unconditional if\` statements should be removed.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> if (true) {  
> doSomething()
> }
> ...
> if (false) {  
> doSomethingElse()
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> doSomething()
> ...
> ```

> [accordion] Nested blocks of code should not be left empty
>
> An empty code block is confusing. It will require some effort from maintainers to determine if it is intentional or indicates the implementation is incomplete.
>
> Unresolved directive in \<stdin> - include::\{example}\[]
>
> Removing or filling the empty code blocks takes away ambiguity and generally results in a more straightforward and less surprising code.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> while (order.processNext());  // Compliant by exception
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> ```

> [accordion] runFinalizersOnExit should not be called
>
> Enabling runFinalizersOnExit is unsafe as it might result in erratic behavior and deadlocks on application exit.
>
> Indeed, finalizers might be force-called on live objects while other threads are concurrently manipulating them.
>
> Instead, if you want to execute something when the virtual machine begins its shutdown sequence, you should attach a shutdown hook.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun main() {
> System.runFinalizersOnExit(true)  // Noncompliant
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun main() {
> Runtime.getRuntime().addShutdownHook(object : Thread() {
>     override fun run() {
>         doSomething()
>     }
> })
> }
> ```

> [accordion] Unnecessary imports should be removed
>
> Although they don’t affect the runtime behavior of the application after compilation, removing them will:
>
> <ul>
>   <li>
>     Improve the readability and maintainability of the code.
>   </li>
>
>   <li>
>     Help avoid potential naming conflicts.
>   </li>
>
>   <li>
>     Improve the build time, as the compiler has fewer lines to read and fewer types to resolve.
>   </li>
>
>   <li>
>     Reduce the number of items the code editor will show for auto-completion, thereby showing fewer irrelevant suggestions.
>   </li>
> </ul>
>
> ```kotlin Bad theme={"theme":"css-variables"}
> package myapp.helpers
>
> import java.io.IOException
> import java.nio.file.*
> import java.nio.file.*     // Noncompliant - package is imported twice
> import java.nio.*          // Noncompliant - nothing is used from that package
>
> object FileHelper {
> fun readFirstLine(filePath: String)
>     = Files.readAllLines(Paths.get(filePath)).first()
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> package myapp.helpers
>
> import java.io.IOException
> import java.nio.file.*
>
> object FileHelper {
> fun readFirstLine(filePath: String)
>     = Files.readAllLines(Paths.get(filePath)).first()
> }
> ```

> [accordion] Using weak hashing algorithms is security-sensitive
>
> Cryptographic hash algorithms such as `MD2, MD4, MD5, MD6, HAVAL-128, HMAC-MD5, DSA (which uses SHA-1), RIPEMD, RIPEMD-128, RIPEMD-160, HMACRIPEMD160 and SHA-1 are no longer considered secure, because it is possible to have collisions` (little computational effort is enough to find two or more different inputs that produce the same hash).
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val md1: MessageDigest = MessageDigest.getInstance("SHA-512"); // Compliant
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> ```

> [accordion] when statements should have else clauses
>
> The requirement for a final `default` clause is defensive programming. The clause should either take appropriate action, or contain a suitable comment as to why no action is taken.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> when(param) { // missing else
> 1 -> doSomething()
> 2 -> doSomethingElse()
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> when(param) {
> 1 -> doSomething()
> 2 -> doSomethingElse()
> else -> error("myMessage")
> }
> ```

> [accordion] Hard-coded credentials are security-sensitive
>
> Because it is easy to extract strings from an application source code or binary, credentials should not be hard-coded. This is particularly true for applications that are distributed or that are open-source.
>
> In the past, it has led to the following vulnerabilities:
>
> <ul>
>   <li>
>     [CVE-2019-13466](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-13466)
>   </li>
>
>   <li>
>     [CVE-2018-15389](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-15389)
>   </li>
> </ul>
>
> Credentials should be stored outside of the code in a configuration file, a database, or a management service for secrets.
>
> This rule flags instances of hard-coded credentials used in database and LDAP connections. It looks for hard-coded credentials in connection strings, and for variable names that match any of the patterns from the provided list.
>
> It’s recommended to customize the configuration of this rule with additional credential words such as "oauthToken", "secret", …​
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val params = "password=${retrievePassword()}"
> val writer = OutputStreamWriter(getOutputStream())
> writer.write(params)
> writer.flush()
> ...
> val password = retrievePassword()
> ...
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> ```

> [accordion] Broadcasting intents is security-sensitive
>
> In Android applications, broadcasting intents is security-sensitive. For example, it has led in the past to the following vulnerability:
>
> <ul>
>   <li>
>     [CVE-2018-9489](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-9489)
>   </li>
> </ul>
>
> By default, broadcasted intents are visible to every application, exposing all sensitive information they contain.
>
> This rule raises an issue when an intent is broadcasted without specifying any "receiver permission".
>
> ```kotlin Bad theme={"theme":"css-variables"}
> import android.content.BroadcastReceiver
> import android.content.Context
> import android.content.Intent
> import android.os.Bundle
> import android.os.Handler
> import android.os.UserHandle
>
> public class MyIntentBroadcast {
> fun broadcast(intent: Intent,
>               context: Context,
>               user: UserHandle,
>               resultReceiver: BroadcastReceiver,
>               scheduler: Handler,
>               initialCode: Int,
>               initialData: String,
>               initialExtras: Bundle,
>               broadcastPermission: String) {
>
>     context.sendBroadcast(intent, broadcastPermission)
>     context.sendBroadcastAsUser(intent, user, broadcastPermission)
>     context.sendOrderedBroadcast(intent, broadcastPermission)
>     context.sendOrderedBroadcastAsUser(intent, user,broadcastPermission, resultReceiver,
>         scheduler, initialCode, initialData, initialExtras)
> }
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> ```

> [accordion] Authorizing non-authenticated users to use keys in the Android KeyStore is security-sensitive
>
> Android KeyStore is a secure container for storing key materials, in particular it prevents key materials extraction, i.e. when the application process is compromised, the attacker cannot extract keys but may still be able to use them. It’s possible to enable an Android security feature, user authentication, to restrict usage of keys to only authenticated users. The lock screen has to be unlocked with defined credentials (pattern/PIN/password, biometric).
>
> ```kotlin Bad theme={"theme":"css-variables"}
> val keyGenerator: KeyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
>
> var builder: KeyGenParameterSpec = KeyGenParameterSpec.Builder("test_secret_key", KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT) // Noncompliant 
> .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
> .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
> .build()
>
> keyGenerator.init(builder)
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> val keyGenerator: KeyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
>
> var builder: KeyGenParameterSpec = KeyGenParameterSpec.Builder("test_secret_key", KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
> .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
> .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
> .setUserAuthenticationRequired(true) // Compliant
> .setUserAuthenticationParameters (60, KeyProperties.AUTH_DEVICE_CREDENTIAL)
> .build()
>
> keyGenerator.init(builder)
> ```

> [accordion] Unused local variables should be removed
>
> An unused local variable is a variable that has been declared but is not used anywhere in the block of code where it is defined. It is dead code, contributing to unnecessary complexity and leading to confusion when reading the code. Therefore, it should be removed from your code to maintain clarity and efficiency.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun numberOfMinutes(hours: Int): Int {
> val seconds: Int = 0 // Noncompliant - seconds is unused
> val result: Int = hours * 60
> return result
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun numberOfMinutes(hours: Int): Int {
> val result: Int = hours * 60
> return result
> }
> ```

> [accordion] Local variable and function parameter names should comply with a naming convention
>
> A naming convention in software development is a set of guidelines for naming code elements like variables, functions, and classes.
> \{identifier\_capital\_plural} hold the meaning of the written code. Their names should be meaningful and follow a consistent and easily recognizable pattern.
> Adhering to a consistent naming convention helps to make the code more readable and understandable, which makes it easier to maintain and debug.
> It also ensures consistency in the code, especially when multiple developers are working on the same project.
>
> This rule checks that \{identifier} names match a provided regular expression.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> fun printSomething(
> IMPORTANT_PARAM: String // Noncompliant
> ) {
> val LOCAL = "" // Noncompliant
> println(IMPORTANT_PARAM + LOCAL)
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> fun printSomething(
> importantParam: String
> ) {
> val local = ""
> println(importantParam + local)
> }
> ```

> [accordion] Two branches in a conditional structure should not have exactly the same implementation
>
> Having two clauses in a when statement or two branches in an if chain with the same implementation is at best duplicate code, and at worst a coding error.
>
> ```kotlin Bad theme={"theme":"css-variables"}
> if (a >= 0 && a < 10) {
> doFirstThing()
> doTheThing()
> }
> else if (a >= 10 && a < 20) {
> doTheOtherThing()
> }
> else if (a >= 20 && a < 50) { // Noncompliant; duplicates first condition
> doFirstThing()
> doTheThing()
> }
> else {
> doTheRest()
> }
> ```
>
> ```kotlin Fix theme={"theme":"css-variables"}
> if ((a >= 0 && a < 10) || (a >= 20 && a < 50)) {
> doFirstThing()
> doTheThing()
> }
> else if (a >= 10 && a < 20) {
> doTheOtherThing()
> }
> else {
> doTheRest()
> }
> ```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.