This README file contains descriptions of all adapted inspections in the config file.
Note
This file, as well as the config file, contains only the most common inspections, that have been adapted for better learning experience. For a complete list of inspections available in the IntelliJ platform, see the Kotlin Inspections tab (Settings -> Editor -> Inspections -> Kotlin).
The Severity
field (level
in the config file) indicates how the inspections will be displayed in the upper right corner of the editor and in the Problems tab. Some of the possible values are:
Name | Config name | Example |
---|---|---|
Error | ERROR | |
Warning | WARNING | |
Weak Warning | WEAK WARNING |
The Highlighting
field (editorAttributes
in the config file) indicates how the inspection will be highlighted in the IDE. Some of the possible values are:
Name | Config name | Example |
---|---|---|
Error | ERRORS_ATTRIBUTES | |
Warning | WARNING_ATTRIBUTES | |
Weak Warning | INFO_ATTRIBUTES | |
Strikethrough | MARKED_FOR_REMOVAL_ATTRIBUTES |
Note
To alter the config file please use the Kotlin Inspections tab where you could turn on/off inspections and choose theirs severity and/or highlighting.
Below are detailed descriptions of all the inspections in the current configuration file.
Severity: Weak Warning
Highlighting: Weak Warning
Function should have 'operator' modifier
Reports a function that matches one of the operator conventions but lacks the operator
keyword.
By adding the operator
modifier, you might allow function consumers to write idiomatic Kotlin code.
Example:
class Complex(val real: Double, val imaginary: Double) {
fun plus(other: Complex) =
Complex(real + other.real, imaginary + other.imaginary)
}
fun usage(a: Complex, b: Complex) {
a.plus(b)
}
The quick-fix adds the operator
modifier keyword:
class Complex(val real: Double, val imaginary: Double) {
operator fun plus(other: Complex) =
Complex(real + other.real, imaginary + other.imaginary)
}
fun usage(a: Complex, b: Complex) {
a + b
}
Severity: Weak Warning
Highlighting: Weak Warning
Type parameter can have 'in' or 'out' variance
Reports type parameters that can have in
or out
variance.
Using in
and out
variance provides more precise type inference in Kotlin and clearer code semantics.
Example:
class Box<T>(val obj: T)
fun consumeString(box: Box<String>) {}
fun consumeCharSequence(box: Box<CharSequence>) {}
fun usage(box: Box<String>) {
consumeString(box)
consumeCharSequence(box) // Compilation error
}
The quick-fix adds the matching variance modifier:
class Box<out T>(val obj: T)
fun consumeString(box: Box<String>) {}
fun consumeCharSequence(box: Box<CharSequence>) {}
fun usage(box: Box<String>) ++{
consumeString(box)
consumeCharSequence(box) // OK
}
Severity: Warning
Highlighting: Strikethrough
Constructor parameter is never used as a property
Reports primary constructor parameters that can have val
or var
removed.
Class properties declared in the constructor increase memory consumption. If the parameter value is only used in the constructor, you can omit them.
Note that the referenced object might be garbage-collected earlier.
Example:
class Task(val name: String) {
init {
print("Task created: $name")
}
}
The quick-fix removes the extra val
or var
keyword:
class Task(name: String) {
init {
print("Task created: $name")
}
}
Severity: Warning
Highlighting: Strikethrough
Property is explicitly assigned to constructor parameter
Reports properties that are explicitly assigned to primary constructor parameters. Properties can be declared directly in the primary constructor, reducing the amount of code and increasing code readability.
Example:
class User(name: String) {
val name = name
}
The quick-fix joins the parameter and property declaration into a primary constructor parameter:
class User(val name: String) {
}
Severity: Error
Highlighting: Error
Local 'var' is never modified and can be declared as 'val'
Reports local variables declared with the var
keyword that are never modified.
Kotlin encourages to declare practically immutable variables using the val
keyword, ensuring that their value will never change.
Example:
fun example() {
var primeNumbers = listOf(1, 2, 3, 5, 7, 11, 13)
var fibonacciNumbers = listOf(1, 1, 2, 3, 5, 8, 13)
print("Same numbers: " + primeNumbers.intersect(fibonacciNumbers))
}
The quick-fix replaces the var
keyword with val
:
fun example() {
val primeNumbers = listOf(1, 2, 3, 5, 7, 11, 13)
val fibonacciNumbers = listOf(1, 1, 2, 3, 5, 8, 13)
print("Same numbers: " + primeNumbers.intersect(fibonacciNumbers))
}
Severity: Warning
Highlighting: Warning
Cascade 'if' can be replaced with 'when'
Reports if
statements with three or more branches that can be replaced with the when
expression.
Example:
fun checkIdentifier(id: String) {
fun Char.isIdentifierStart() = this in 'A'..'z'
fun Char.isIdentifierPart() = isIdentifierStart() || this in '0'..'9'
if (id.isEmpty()) {
print("Identifier is empty")
} else if (!id.first().isIdentifierStart()) {
print("Identifier should start with a letter")
} else if (!id.subSequence(1, id.length).all(Char::isIdentifierPart)) {
print("Identifier should contain only letters and numbers")
}
}
The quick-fix converts the if
expression to when
:
fun checkIdentifier(id: String) {
fun Char.isIdentifierStart() = this in 'A'..'z'
fun Char.isIdentifierPart() = isIdentifierStart() || this in '0'..'9'
when {
id.isEmpty() -> {
print("Identifier is empty")
}
!id.first().isIdentifierStart() -> {
print("Identifier should start with a letter")
}
!id.subSequence(1, id.length).all(Char::isIdentifierPart) -> {
print("Identifier should contain only letters and numbers")
}
}
}
Severity: Error
Highlighting: Error
Class naming convention
Reports class names that do not follow the recommended naming conventions.
Consistent naming allows for easier code reading and understanding. According to the Kotlin official style guide, class names should start with an uppercase letter and use camel case.
It is possible to introduce other naming rules by changing the "Pattern" regular expression.
Example:
class user(val name: String)
The quick-fix renames the class according to the Kotlin naming conventions:
class User(val name: String)
Severity: Warning
Highlighting: Strikethrough
Control flow with empty body
Reports if
, while
, do
or for
statements with empty bodies.
While occasionally intended, this construction is confusing and often the result of a typo.
The quick-fix removes a statement.
Example:
if (a > b) {}
Severity: Information
Highlighting: None
Can be replaced with function reference
Reports function literal expressions that can be replaced with function references. Replacing lambdas with function references often makes code look more concise and understandable.
Example:
fun Int.isEven() = this % 2 == 0
fun example() {
val numbers = listOf(1, 2, 4, 7, 9, 10)
val evenNumbers = numbers.filter { it.isEven() }
}
After the quick-fix is applied:
fun Int.isEven() = this % 2 == 0
fun example() {
val numbers = listOf(1, 2, 4, 7, 9, 10)
val evenNumbers = numbers.filter(Int::isEven)
}
Severity: Warning
Highlighting: Warning
Convert Pair constructor to 'to' function
Reports a Pair
constructor invocation that can be replaced with a to()
infix function call.
Explicit constructor invocations may add verbosity, especially if they are used multiple times.
Replacing constructor calls with to()
makes code easier to read and maintain.
Example:
val countries = mapOf(
Pair("France", "Paris"),
Pair("Spain", "Madrid"),
Pair("Germany", "Berlin")
)
After the quick-fix is applied:
val countries = mapOf(
"France" to "Paris",
"Spain" to "Madrid",
"Germany" to "Berlin"
)
Severity: Warning
Highlighting: Warning
Can be replaced with lambda
Reports a function reference expression that can be replaced with a function literal (lambda).
Sometimes, passing a lambda looks more straightforward and more consistent with the rest of the code. Also, the fix might be handy if you need to replace a simple call with something more complex.
Example:
fun Int.isEven() = this % 2 == 0
fun example() {
val numbers = listOf(1, 2, 4, 7, 9, 10)
val evenNumbers = numbers.filter(Int::isEven)
}
After the quick-fix is applied:
fun Int.isEven() = this % 2 == 0
fun example() {
val numbers = listOf(1, 2, 4, 7, 9, 10)
val evenNumbers = numbers.filter { it.isEven() }
}
Severity: Warning
Highlighting: Warning
Two comparisons should be converted to a range check
Reports two consecutive comparisons that can be converted to a range check. Checking against a range makes code simpler by removing test subject duplication.
Example:
fun checkMonth(month: Int): Boolean {
return month >= 1 && month <= 12
}
The quick-fix replaces the comparison-based check with a range one:
fun checkMonth(month: Int): Boolean {
return month in 1..12
}
Severity: Weak Warning
Highlighting: Weak Warning
Use destructuring declaration
Reports declarations that can be destructured. Example:
data class My(val first: String, val second: Int, val third: Boolean)
fun foo(list: List<My>) {
list.forEach { my ->
println(my.second)
println(my.third)
}
}
The quick-fix destructures the declaration and introduces new variables with names from the corresponding class:
data class My(val first: String, val second: Int, val third: Boolean)
fun foo(list: List<My>) {
list.forEach { (_, second, third) ->
println(second)
println(third)
}
}
Severity: Error
Highlighting: Strikethrough
Redundant explicit 'this'
Reports an explicit this
when it can be omitted.
Example:
class C {
private val i = 1
fun f() = this.i
}
The quick-fix removes the redundant this
:
class C {
private val i = 1
fun f() = i
}
Severity: Warning
Highlighting: Warning
Iterated elements are not used in forEach
Reports forEach
loops that do not use iterable values.
Example:
listOf(1, 2, 3).forEach { }
The quick fix introduces anonymous parameter in the forEach
section:
listOf(1, 2, 3).forEach { _ -> }
Severity: Warning
Highlighting: Warning
Function naming convention
Reports function names that do not follow the recommended naming conventions. Example:
fun Foo() {}
To fix the problem change the name of the function to match the recommended naming conventions.
Severity: Warning
Highlighting: Warning
Function or property has platform type
Reports functions and properties that have a platform type. To prevent unexpected errors, the type should be declared explicitly.
Example:
fun foo() = java.lang.String.valueOf(1)
The quick fix allows you to specify the return type:
fun foo(): String = java.lang.String.valueOf(1)
Severity: Weak Warning
Highlighting: Weak Warning
Implicit 'this'
Reports usages of implicit this. Example:
class Foo {
fun s() = ""
fun test() {
s()
}
}
The quick fix specifies this explicitly:
class Foo {
fun s() = ""
fun test() {
this.s()
}
}
Severity: Error
Highlighting: Error
Incomplete destructuring declaration
Reports incomplete destructuring declaration. Example:
data class Person(val name: String, val age: Int)
val person = Person("", 0)
val (name) = person
The quick fix completes destructuring declaration with new variables:
data class Person(val name: String, val age: Int)
val person = Person("", 0)
val (name, age) = person
Severity: Warning
Highlighting: Warning
when' that can be simplified by introducing an argument
Reports a when
expression that can be simplified by introducing a subject argument.
Example:
fun test(obj: Any): String {
return when {
obj is String -> "string"
obj is Int -> "int"
else -> "unknown"
}
}
The quick fix introduces a subject argument:
fun test(obj: Any): String {
return when (obj) {
is String -> "string"
is Int -> "int"
else -> "unknown"
}
}
Severity: Warning
Highlighting: Warning
Join declaration and assignment
Reports property declarations that can be joined with the following assignment. Example:
val x: String
x = System.getProperty("")
The quick fix joins the declaration with the assignment:
val x = System.getProperty("")
Configure the inspection:
You can disable the option Report with complex initialization of member properties to skip properties with complex initialization. This covers two cases:
- The property initializer is complex (it is a multiline or a compound/control-flow expression)
- The property is first initialized and then immediately used in subsequent code (for example, to call additional initialization methods)
Severity: Warning
Highlighting: Warning
Unresolved reference in KDoc
Reports unresolved references in KDoc comments. Example:
/**
* [unresolvedLink]
*/
fun foo() {}
To fix the problem make the link valid.
Severity: Error
Highlighting: Error
Constant conditions
Reports non-trivial conditions and values that are statically known to be always true, false, null or zero.
While sometimes intended, often this is a sign of logical error in the program. Additionally,
reports never reachable when
branches and some expressions that are statically known to fail always.
Examples:
fun process(x: Int?) {
val isNull = x == null
if (!isNull) {
if (x != null) {} // condition is always true
require(x!! < 0 && x > 10) // condition is always false
} else {
println(x!!) // !! operator will always fail
}
}
fun process(v: Any) {
when(v) {
is CharSequence -> println(v as Int) // cast will always fail
is String -> println(v) // branch is unreachable
}
}
Uncheck the "Warn when constant is stored in variable" option to avoid reporting of variables having constant values not in conditions.
New in 2021.3
Severity: Warning
Highlighting: Warning
Usage of redundant or deprecated syntax or deprecated symbols
Reports obsolete language features and unnecessarily verbose code constructs during the code cleanup operation (Code | Code Cleanup).
The quick-fix automatically replaces usages of obsolete language features or unnecessarily verbose code constructs with compact and up-to-date syntax.
It also replaces deprecated symbols with their proposed substitutions.
Severity: Error
Highlighting: Error
equals()' between objects of inconvertible types
Reports calls to equals()
where the receiver and the argument are
of incompatible primitive, enum, or string types.
While such a call might theoretically be useful, most likely it represents a bug.
Example:
5.equals("");
Severity: Warning
Highlighting: Strikethrough
Unused import directive
Reports redundant import
statements.
Default and unused imports can be safely removed.
Example:
import kotlin.*
import kotlin.collections.*
import kotlin.comparisons.*
import kotlin.io.*
import kotlin.ranges.*
import kotlin.sequences.*
import kotlin.text.*
// jvm specific
import java.lang.*
import kotlin.jvm.*
// js specific
import kotlin.js.*
import java.io.* // this import is unused and could be removed
import java.util.*
fun foo(list: ArrayList<String>) {
list.add("")
}
Severity: Error
Highlighting: Error
Return or assignment can be lifted out
Reports if
, when
, and try
statements that can be converted to expressions
by lifting the return
statement or an assignment out.
Example:
fun foo(arg: Int): String {
when (arg) {
0 -> return "Zero"
1 -> return "One"
else -> return "Multiple"
}
}
After the quick-fix is applied:
fun foo(arg: Int): String {
return when (arg) {
0 -> "Zero"
1 -> "One"
else -> "Multiple"
}
}
If you would like this inspection to highlight more complex code with multi-statement branches, uncheck the option "Report only if each branch is a single statement".
Severity: Warning
Highlighting: Warning
Local variable naming convention
Reports local variables that do not follow the naming conventions. You can specify the required pattern in the inspection options.
Recommended naming conventions: it has to start with a lowercase letter, use camel case and no underscores.
Example:
fun fibonacciNumber(index: Int): Long = when(index) {
0 -> 0
else -> {
// does not follow naming conventions: contains underscore symbol (`_`)
var number_one: Long = 0
// does not follow naming conventions: starts with an uppercase letter
var NUMBER_TWO: Long = 1
// follow naming conventions: starts with a lowercase letter, use camel case and no underscores.
var numberThree: Long = number_one + NUMBER_TWO
for(currentIndex in 2..index) {
numberThree = number_one + NUMBER_TWO
number_one = NUMBER_TWO
NUMBER_TWO = numberThree
}
numberThree
}
}
Severity: Warning
Highlighting: Warning
Loop can be replaced with stdlib operations
Reports for
loops that can be replaced with a sequence of stdlib operations (like map
, filter
, and so on).
Example:
fun foo(list: List<String>): List<Int> {
val result = ArrayList<Int>()
for (s in list) {
if (s.length > 0)
result.add(s.hashCode())
}
return result
}
After the quick-fix is applied:
fun foo(list: List<String>): List<Int> {
val result = list
.filter { it.length > 0 }
.map { it.hashCode() }
return result
}
Severity: Warning
Highlighting: Warning
Might be 'const'
Reports top-level val
properties in objects that might be declared as const
for better performance and Java interoperability.
Example:
object A {
val foo = 1
}
After the quick-fix is applied:
object A {
const val foo = 1
}
Severity: Warning
Highlighting: Warning
Class member can have 'private' visibility
Reports declarations that can be made private
to follow the encapsulation principle.
Example:
class Service(val url: String) {
fun connect(): URLConnection = URL(url).openConnection()
}
After the quick-fix is applied (considering there are no usages of url
outside of Service
class):
class Service(private val url: String) {
fun connect(): URLConnection = URL(url).openConnection()
}
Severity: Warning
Highlighting: Warning
Variable declaration could be moved inside 'when'
Reports variable declarations that can be moved inside a when
expression.
Example:
fun someCalc(x: Int) = x * 42
fun foo(x: Int): Int {
val a = someCalc(x)
return when (a) {
1 -> a
2 -> 2 * a
else -> 24
}
}
After the quick-fix is applied:
fun foo(x: Int): Int {
return when (val a = someCalc(x)) {
1 -> a
2 -> 2 * a
else -> 24
}
}
Severity: Warning
Highlighting: Warning
Nested lambda has shadowed implicit parameter
Reports nested lambdas with shadowed implicit parameters. Example:
fun foo(listOfLists: List<List<String>>) {
listOfLists.forEach {
it.forEach {
println(it)
}
}
}
After the quick-fix is applied:
fun foo(listOfLists: List<List<String>>) {
listOfLists.forEach {
it.forEach { it1 ->
println(it1)
}
}
}
Severity: Warning
Highlighting: Warning
Private property naming convention
Reports private property names that do not follow the recommended naming conventions.
Consistent naming allows for easier code reading and understanding. According to the Kotlin official style guide, private property names should start with a lowercase letter and use camel case. Optionally, underscore prefix is allowed but only for private properties.
It is possible to introduce other naming rules by changing the "Pattern" regular expression.
Example:
val _My_Cool_Property = ""
The quick-fix renames the class according to the Kotlin naming conventions:
val _myCoolProperty = ""
Severity: Warning
Highlighting: Warning
Public API declaration with implicit return type
Reports public
and protected
functions and properties that have an implicit return type.
For API stability reasons, it's recommended to specify such types explicitly.
Example:
fun publicFunctionWhichAbusesTypeInference() =
otherFunctionWithNotObviousReturnType() ?: yetAnotherFunctionWithNotObviousReturnType()
After the quick-fix is applied:
fun publicFunctionWhichAbusesTypeInference(): **Api** =
otherFunctionWithNotObviousReturnType() ?: yetAnotherFunctionWithNotObviousReturnType()
Severity: Error
Highlighting: Strikethrough
Redundant 'else' in 'if'
Reports redundant else
in if
with return
Example:
fun foo(arg: Boolean): Int {
if (arg) return 0
else { // This else is redundant, code in braces could be just shifted left
someCode()
}
}
After the quick-fix is applied:
fun foo(arg: Boolean): Int {
if (arg) return 0
someCode()
}
Severity: Warning
Highlighting: Strikethrough
Obvious explicit type
Reports local variables' explicitly given types which are obvious and thus redundant, like val f: Foo = Foo()
.
Example:
class Point(val x: Int, val y: Int)
fun foo() {
val t: **Boolean** = true
val p: **Point** = Point(1, 2)
val i: **Int** = 42
}
After the quick-fix is applied:
class Point(val x: Int, val y: Int)
fun foo() {
val t = true
val p = Point(1, 2)
val i = 42
}
Severity: Weak Warning
Highlighting: Strikethrough
Redundant 'if' statement
Reports if
statements which can be simplified to a single statement.
Example:
fun test(): Boolean {
if (foo()) {
return true
} else {
return false
}
}
After the quick-fix is applied:
fun test(): Boolean {
return foo()
}
Severity: Warning
Highlighting: Strikethrough
Redundant nullable return type
Reports functions and variables with nullable return type which never return or become null
.
Example:
fun greeting(user: String): String? = "Hello, $user!"
After the quick-fix is applied:
fun greeting(user: String): String = "Hello, $user!"
Severity: Warning
Highlighting: Strikethrough
Redundant semicolon
Reports redundant semicolons (;
) that can be safely removed.
Kotlin does not require a semicolon at the end of each statement or expression. The quick-fix is suggested to remove redundant semicolons.
Example:
val myMap = mapOf("one" to 1, "two" to 2);
myMap.forEach { (key, value) -> print("$key -> $value")};
After the quick-fix is applied:
val myMap = mapOf("one" to 1, "two" to 2)
myMap.forEach { (key, value) -> print("$key -> $value")}
There are two cases though where a semicolon is required:
- Several statements placed on a single line need to be separated with semicolons:
map.forEach { val (key, value) = it; println("$key -> $value") }
enum
classes that also declare properties or functions, require a semicolon after the list of enum constants:
enum class Mode {
SILENT, VERBOSE;
fun isSilent(): Boolean = this == SILENT
}
Severity: Warning
Highlighting: Strikethrough
Redundant visibility modifier
Reports visibility modifiers that match the default visibility of an element
(public
for most elements, protected
for members that override a protected member).
Severity: Warning
Highlighting: Warning
Redundant curly braces in string template
Reports usages of curly braces in string templates around simple identifiers. Use the 'Remove curly braces' quick-fix to remove the redundant braces.
Examples:
fun redundant() {
val x = 4
val y = "${x}" // <== redundant
}
fun correctUsage() {
val x = "x"
val y = "${x.length}" // <== Ok
}
After the quick-fix is applied:
fun redundant() {
val x = 4
val y = "$x"
}
fun correctUsage() {
val x = "x" <== Updated
val y = "${x.length}"
}
Severity: Weak Warning
Highlighting: Strikethrough
Unnecessary parentheses in function call with lambda
Reports redundant empty parentheses of function calls where the only parameter is a lambda that's outside the parentheses. Use the 'Remove unnecessary parentheses from function call with lambda' quick-fix to clean up the code.
Examples:
fun foo() {
listOf(1).forEach() { }
}
After the quick-fix is applied:
fun foo() {
listOf(1).forEach { }
}
Severity: Weak Warning
Highlighting: Strikethrough
Redundant empty primary constructor
Reports empty primary constructors when they are implicitly available anyway.
A primary constructor is redundant and can be safely omitted when it does not have any annotations or visibility modifiers. Use the 'Remove empty primary constructor' quick-fix to clean up the code.
Examples:
class MyClassA constructor() // redundant, can be replaced with 'class MyClassA'
annotation class MyAnnotation
class MyClassB @MyAnnotation constructor() // required because of annotation
class MyClassC private constructor() // required because of visibility modifier
Severity: Weak Warning
Highlighting: Strikethrough
Unnecessary type argument
Reports function calls with type arguments that can be automatically inferred. Such type arguments are redundant and can be safely omitted. Use the 'Remove explicit type arguments' quick-fix to clean up the code.
Examples:
// 'String' type can be inferred here
fun foo(): MutableList<String> = mutableListOf<String>()
// Here 'String' cannot be inferred, type argument is required.
fun bar() = mutableListOf<String>()
After the quick-fix is applied:
fun foo(): MutableList<String> = mutableListOf() <== Updated
fun bar() = mutableListOf<String>()
Severity: Warning
Highlighting: Strikethrough
Unused loop index
Reports for
loops iterating over a collection using the withIndex()
function and not using the index variable.
Use the "Remove indices in 'for' loop" quick-fix to clean up the code.
Examples:
fun foo(bar: List<String>) {
for ((index : Int, value: String) in bar.withIndex()) { // <== 'index' is unused
println(value)
}
}
After the quick-fix is applied:
fun foo(bar: List<String>) {
for (value: String in bar) { // <== '.withIndex()' and 'index' are removed
println(value)
}
}
Severity: Warning
Highlighting: Strikethrough
Redundant call of conversion method
Reports redundant calls to conversion methods (for example, toString()
on a String
or toDouble()
on a Double
).
Use the 'Remove redundant calls of the conversion method' quick-fix to clean up the code.
Severity: Warning
Highlighting: Strikethrough
Redundant qualifier name
Reports redundant qualifiers (or their parts) on class names, functions, and properties.
A fully qualified name is an unambiguous identifier that specifies which object, function, or property a call refers to. In the contexts where the name can be shortened, the inspection informs on the opportunity and the associated 'Remove redundant qualifier name' quick-fix allows amending the code.
Examples:
package my.simple.name
import kotlin.Int.Companion.MAX_VALUE
class Foo
fun main() {
val a = my.simple.name.Foo() // 'Foo' resides in the declared 'my.simple.name' package, qualifier is redundant
val b = kotlin.Int.MAX_VALUE // Can be replaced with 'MAX_VALUE' since it's imported
val c = kotlin.Double.MAX_VALUE // Can be replaced with 'Double.MAX_VALUE' since built-in types are imported automatically
}
After the quick-fix is applied:
package my.simple.name
import kotlin.Int.Companion.MAX_VALUE
class Foo
fun main() {
val a = Foo()
val b = MAX_VALUE
val c = Double.MAX_VALUE
}
Severity: Error
Highlighting: Error
Redundant string template
Reports single-expression string templates that can be safely removed. Example:
val x = "Hello"
val y = "$x"
After the quick-fix is applied:
val x = "Hello"
val y = x // <== Updated
Severity: Weak Warning
Highlighting: Strikethrough
Redundant call to 'toString()' in string template
Reports calls to toString()
in string templates that can be safely removed.
Example:
fun foo(a: Int, b: Int) = a + b
fun test(): String {
return "Foo: ${foo(0, 4).toString()}" // 'toString()' is redundant
}
After the quick-fix is applied:
fun foo(a: Int, b: Int) = a + b
fun test(): String {
return "Foo: ${foo(0, 4)}"
}
Severity: Warning
Highlighting: Warning
Can be replaced with binary operator
Reports function calls that can be replaced with binary operators, in particular comparison-related ones. Example:
fun test(): Boolean {
return 2.compareTo(1) > 0 // replaceable 'compareTo()'
}
After the quick-fix is applied:
fun test(): Boolean {
return 2 > 1
}
Severity: Weak Warning
Highlighting: Strikethrough
Collection count can be converted to size
Reports calls to Collection<T>.count()
.
This function call can be replaced with .size
.
.size
form ensures that the operation is O(1) and won't allocate extra objects, whereas
count()
could be confused with Iterable<T>.count()
, which is O(n) and allocating.
Example:
fun foo() {
var list = listOf(1,2,3)
list.count() // replaceable 'count()'
}
After the quick-fix is applied:
fun foo() {
var list = listOf(1,2,3)
list.size
}
Severity: Weak Warning
Highlighting: Strikethrough
Explicit 'get' or 'set' call
Reports explicit calls to get
or set
functions which can be replaced by an indexing operator []
.
Kotlin allows custom implementations for the predefined set of operators on types.
To overload an operator, you can mark the corresponding function with the operator
modifier:
operator fun get(index: Int) {}
operator fun set(index: Int, value: Int) {}
The functions above correspond to the indexing operator.
Example:
class Test {
operator fun get(i: Int): Int = 0
}
fun test() {
Test().get(0) // replaceable 'get()'
}
After the quick-fix is applied:
class Test {
operator fun get(i: Int): Int = 0
}
fun test() {
Test()[0]
}
Severity: Error
Highlighting: Strikethrough
Guard clause can be replaced with Kotlin's function call
Reports guard clauses that can be replaced with a function call. Example:
fun test(foo: Int?) {
if (foo == null) throw IllegalArgumentException("foo") // replaceable clause
}
After the quick-fix is applied:
fun test(foo: Int?) {
checkNotNull(foo)
}
Severity: Warning
Highlighting: Warning
Range can be converted to indices or iteration
Reports until
and rangeTo
operators that can be replaced with Collection.indices
or iteration over collection inside for
loop.
Using syntactic sugar makes your code simpler.
The quick-fix replaces the manual range with the corresponding construction.
Example:
fun main(args: Array<String>) {
for (index in 0..args.size - 1) {
println(args[index])
}
}
After the quick-fix is applied:
fun main(args: Array<String>) {
for (element in args) {
println(element)
}
}
Severity: Warning
Highlighting: Warning
rangeTo' or the '..' call should be replaced with 'until'
Reports calls to rangeTo
or the ..
operator instead of calls to until
.
Using corresponding functions makes your code simpler.
The quick-fix replaces rangeTo
or the ..
call with until
.
Example:
fun foo(a: Int) {
for (i in 0..a - 1) {
}
}
After the quick-fix is applied:
fun foo(a: Int) {
for (i in 0 until a) {
}
}
Severity: Weak Warning
Highlighting: Strikethrough
readLine' can be replaced with 'readln' or 'readlnOrNull'
Reports calls to readLine()
that can be replaced with readln()
or readlnOrNull()
.
Using corresponding functions makes your code simpler.
The quick-fix replaces readLine()!!
with readln()
and readLine()
with readlnOrNull()
.
Examples:
val x = readLine()!!
val y = readLine()?.length
After the quick-fix is applied:
val x = readln()
val y = readlnOrNull()?.length
Severity: Error
Highlighting: Error
Size check can be replaced with 'isNotEmpty()'
Reports size checks of Collections/Array/String
that should be replaced with isNotEmpty()
.
Using isNotEmpty()
makes your code simpler.
The quick-fix replaces the size check with isNotEmpty()
.
Example:
fun foo() {
val arrayOf = arrayOf(1, 2, 3)
arrayOf.size > 0
}
After the quick-fix is applied:
fun foo() {
val arrayOf = arrayOf(1, 2, 3)
arrayOf.isNotEmpty()
}
Severity: Error
Highlighting: Error
Size zero check can be replaced with 'isEmpty()'
Reports size == 0
checks on Collections/Array/String
that should be replaced with isEmpty()
.
Using isEmpty()
makes your code simpler.
The quick-fix replaces the size check with isEmpty()
.
Example:
fun foo() {
val arrayOf = arrayOf(1, 2, 3)
arrayOf.size == 0
}
After the quick-fix is applied:
fun foo() {
val arrayOf = arrayOf(1, 2, 3)
arrayOf.isEmpty()
}
Severity: Error
Highlighting: Strikethrough
substring' call should be replaced with 'take' call
Reports calls like s.substring(0, x)
that can be replaced with s.take(x)
.
Using take()
makes your code simpler.
The quick-fix replaces the substring
call with take()
.
Example:
fun foo(s: String) {
s.substring(0, 10)
}
After the quick-fix is applied:
fun foo(s: String) {
s.take(10)
}
Severity: Information
Highlighting: None
Call of 'toString' could be replaced with string template
Reports toString
function calls that can be replaced with a string template.
Using string templates makes your code simpler.
The quick-fix replaces toString
with a string template.
Example:
fun test(): String {
val x = 1
return x.toString()
}
After the quick-fix is applied:
fun test(): String {
val x = 1
return "$x"
}
Severity: Error
Highlighting: Error
Assignment can be replaced with operator assignment
Reports modifications of variables with a simple assignment (such as y = y + x
) that can be replaced with an operator assignment.
The quick-fix replaces the assignment with an assignment operator.
Example:
fun foo() {
val list = mutableListOf(1, 2, 3)
list = list + 4
}
After the quick-fix is applied:
fun foo() {
val list = mutableListOf(1, 2, 3)
list += 4
}
Severity: Information
Highlighting: None
Scope function can be converted to another one
Reports scope functions (let
, run
, apply
, also
) that can be converted between each other.
Using corresponding functions makes your code simpler.
The quick-fix replaces the scope function to another one.
Example:
val x = "".let {
it.length
}
After the quick-fix is applied:
val x = "".run {
length
}
Severity: Error
Highlighting: Error
Redundant assignment
Reports assignments of a variable to itself. The quick-fix removes the redundant assignment.
Example:
fun test() {
var bar = 1
bar = bar
}
After the quick-fix is applied:
fun test() {
var bar = 1
}
Severity: Weak Warning
Highlighting: Strikethrough
Call chain on collection type can be simplified
Reports two-call chains replaceable by a single call. It can help you to avoid redundant code execution.
The quick-fix replaces the call chain with a single call.
Example:
fun main() {
listOf(1, 2, 3).filter { it > 1 }.count()
}
After the quick-fix is applied:
fun main() {
listOf(1, 2, 3).count { it > 1 }
}
Severity: Error
Highlighting: Error
Boolean expression can be simplified
Reports boolean expression parts that can be reduced to constants. The quick-fix simplifies the condition.
Example:
fun use(arg: Boolean) {
if (false == arg) {
}
}
After the quick-fix is applied:
fun use(arg: Boolean) {
if (!arg) {
}
}
Severity: Error
Highlighting: Error
Trailing comma recommendations
Reports trailing commas that do not follow the recommended style guide.
Severity: Error
Highlighting: Error
Unlabeled return inside lambda
Reports unlabeled return
expressions inside inline lambda.
Such expressions can be confusing because it might be unclear which scope belongs to return
.
Change to return@… quick-fix can be used to amend the code automatically.
Example:
fun test(list: List<Int>) {
list.forEach {
// This return expression returns from the function test
// One can change it to return@forEach to change the scope
if (it == 10) return
}
}
After the quick-fix is applied:
fun test(list: List<Int>) {
list.forEach {
if (it == 10) return@test
}
}
Severity: Weak Warning
Highlighting: Strikethrough
Unnecessary local variable
Reports local variables that are used only in the very next return
statement or are exact copies of other variables.
Such variables can be safely inlined to make the code more clear.
Example:
fun sum(a: Int, b: Int): Int {
val c = a + b
return c
}
After the quick-fix is applied:
fun sum(a: Int, b: Int): Int {
return a + b
}
Configure the inspection:
Use the Report immediately returned variables option to report immediately returned variables. When given descriptive names, such variables may improve the code readability in some cases, that's why this option is disabled by default.
Severity: Error
Highlighting: Error
Unused equals expression
Reports unused equals
(==
) expressions.
Severity: Warning
Highlighting: Strikethrough
Unused receiver parameter
Reports receiver parameter of extension functions and properties that is not used. Remove redundant receiver parameter can be used to amend the code automatically.
Severity: Warning
Highlighting: Warning
Expression body syntax is preferable here
Reports return
expressions (one-liners or when
) that can be replaced with expression body syntax.
Expression body syntax is recommended by the style guide.
Convert to expression body quick-fix can be used to amend the code automatically.
Example:
fun sign(x: Int): Int {
return when { // <== can be simplified
x < 0 -> -1
x > 0 -> 1
else -> 0
}
}
After the quick-fix is applied:
fun sign(x: Int): Int = when {
x < 0 -> -1
x > 0 -> 1
else -> 0
}
Severity: Weak Warning
Highlighting: Weak Warning
Unused 'args' on 'main' since 1.4
Reports main
function with an unused single parameter.
Since Kotlin 1.4, it is possible to use the main
function without parameter as the entry point to the Kotlin program.
The compiler reports a warning for the main
function with an unused parameter.