Experimental rules
Important
Up and until Ktlint version 0.47
, experimental were located in a separate experimental
rule set. As of Ktlint version 0.48
, each rule set can optionally define experimental rules.
All experimental rules described below are part of the standard
rule set of Ktlint. To enable all experimental rules (from all rule sets), set editorconfig
property below:
Binary expression wrapping¶
Wraps binary expression at the operator reference whenever the binary expression does not fit on the line. In case the binary expression is nested, the expression is evaluated from outside to inside. If the left and right hand sides of the binary expression, after wrapping, fit on a single line then the inner binary expressions will not be wrapped. If one or both inner binary expression still do not fit on a single after wrapping of the outer binary expression, then each of those inner binary expressions will be wrapped.
Rule id: binary-expression-wrapping
(standard
rule set)
Blank line before declarations¶
Requires a blank line before any class or function declaration. No blank line is required between the class signature and the first declaration in the class. In a similar way, a blank line is required before any list of top level or class properties. No blank line is required before local properties or between consecutive properties.
Rule id: blank-line-before-declaration
(standard
rule set)
Note
This rule is only run when ktlint_code_style
is set to ktlint_official
or when the rule is enabled explicitly.
Discouraged comment location¶
Detect discouraged comment locations (no autocorrect).
Note
Kotlin allows comments to be placed almost everywhere. As this can lead to code which is hard to read, most of them will never be used in practice. Ideally each rule takes comments at all possible locations into account. Sometimes this is really hard and not worth the effort. By explicitly forbidding such comment locations, the development of those rules becomes a bit easier.
Rule id: discouraged-comment-location
(standard
rule set)
Disallow empty lines at start of class body¶
Detect blank lines at start of a class body.
Rule id: no-empty-first-line-in-class-body
(standard
rule set)
Note
This rule is only run when ktlint_code_style
is set to ktlint_official
or when the rule is enabled explicitly.
Disallow consecutive comments¶
Consecutive comments are disallowed in following cases: - Any mix of a consecutive kdoc, a block comment or an EOL comment unless separated by a blank line in between - Consecutive KDocs (even when separated by a blank line) - Consecutive block comments (even when separated by a blank line)
Consecutive EOL comments are always allowed as they are often used instead of a block comment.
// An EOL comment
// may be followed by another EOL comment
val foo = "foo"
// Different comment types (including KDoc) may be consecutive ..
/*
* ... but do need to be separated by a blank line ...
*/
/**
* ... but a KDoc can not be followed by an EOL or a block comment or another KDoc
*/
fun bar() = "bar"
Rule id: no-consecutive-comments
(standard
rule set)
Note
This rule is only run when ktlint_code_style
is set to ktlint_official
or when the rule is enabled explicitly.
Function signature¶
Rewrites the function signature to a single line when possible (e.g. when not exceeding the max_line_length
property) or a multiline signature otherwise. In case of function with a body expression, the body expression is placed on the same line as the function signature when not exceeding the max_line_length
property. Optionally the function signature can be forced to be written as a multiline signature in case the function has more than a specified number of parameters (.editorconfig
property ktlint_function_signature_wrapping_rule_always_with_minimum_parameters
)
// Assume that the last allowed character is
// at the X character on the right X
fun foooooooo(
a: Any,
b: Any,
c: Any
): String {
// body
}
// Assume that the last allowed character is
// at the X character on the right X
fun bar(a: Any, b: Any, c: Any): String {
// body
}
// When wrapping of body is set to 'default'.
// Assume that the last allowed character is
// at the X character on the right X
fun f(a: Any, b: Any): String = "some-result"
.uppercase()
// When wrapping of body is set to 'multiline'
// or 'always'.
// Assume that the last allowed character is
// at the X character on the right X
fun f(a: Any, b: Any): String =
"some-result"
.uppercase()
// Assume that the last allowed character is
// at the X character on the right X
fun foooooooo(a: Any, b: Any, c: Any): String {
// body
}
// Assume that the last allowed character is
// at the X character on the right X
fun bar(
a: Any,
b: Any,
c: Any
): String {
// body
}
// When wrapping of body is set to 'default'.
// Assume that the last allowed character is
// at the X character on the right X
fun f(a: Any, b: Any): String =
"some-result"
.uppercase()
// When wrapping of body is set to 'multiline'
// or 'always'.
// Assume that the last allowed character is
// at the X character on the right X
fun f(a: Any, b: Any): String = "some-result"
.uppercase()
Rule id: function-signature
(standard
rule set)
If else bracing¶
If at least one branch of an if-else statement or an if-else-if statement is wrapped between curly braces then all branches should be wrapped between braces.
Rule id: if-else-bracing
(standard
rule set)
Note
This rule is only run when ktlint_code_style
is set to ktlint_official
or when the rule is enabled explicitly.
If else wrapping¶
A single line if-statement should be kept simple. It may contain no more than one else-branch. The branches may not be wrapped in a block.
Rule id: if-else-wrapping
(standard
rule set)
Note
This rule is only run when ktlint_code_style
is set to ktlint_official
or when the rule is enabled explicitly.
Naming¶
Function naming¶
Enforce naming of function.
Note
Functions in files which import a class from package org.junit
, org.testng
or kotlin.test
are considered to be test functions. Functions in such classes are allowed to have underscores in the name. Or function names can be specified between backticks and do not need to adhere to the normal naming convention.
This rule can also be suppressed with the IntelliJ IDEA inspection suppression FunctionName
.
Rule id: function-naming
(standard
rule set)
Package naming¶
Enforce naming of package.
This rule can also be suppressed with the IntelliJ IDEA inspection suppression PackageName
.
Rule id: package-naming
(standard
rule set)
Property naming¶
Enforce naming of property.
val FOO_1 = Foo()
val FOO_BAR_1 = "FOO-BAR"
var foo1: Foo = Foo()
class Bar {
const val FOO_2 = "foo"
const val FOO_BAR_2 = "FOO-BAR"
val foo2 = "foo"
val fooBar2 = "foo-bar"
// Backing property
private val _elementList = mutableListOf<Element>()
val elementList: List<Element>
get() = _elementList
}
val Foo1 = Foo()
val FooBar1 = "FOO-BAR"
var FOO_1: Foo = Foo()
class Bar {
const val foo2 = "foo"
const val fooBar2 = "FOO-BAR"
val FOO2 = "foo"
val FOO_BAR_2 = "foo-bar"
// Incomplete backing property as public property 'elementList1' is missing
private val _elementList1 = mutableListOf<Element>()
// Invalid backing property as '_elementList2' is not a private property
val _elementList2 = mutableListOf<Element>()
val elementList2: List<Element>
get() = _elementList2
}
Note
Top level val
properties and const val
properties have to be written in screaming snake notation. Local val
and const val
are written in lower camel case.
This rule can also be suppressed with the IntelliJ IDEA inspection suppression PropertyName
.
Rule id: property-naming
(standard
rule set)
No empty file¶
A kotlin (script) file should not be empty. It needs to contain at least one declaration. Files only contain a package and/or import statements are as of that disallowed.
Rule id: no-empty-file
No single line block comments¶
A single line block comment should be replaced with an EOL comment when possible.
Rule id: no-single-line-block-comment
(standard
rule set)
Spacing¶
No blank lines in list¶
Disallow blank lines to be used in lists before the first element, between elements, and after the last element.
Super type
Type argument list
Type constraint list
class BiAdapter<C : RecyclerView.ViewHolder, V1 : C, V2 : C, out A1, out A2>(
val adapter1: A1,
val adapter2: A2
) : RecyclerView.Adapter<C>()
where A1 : RecyclerView.Adapter<V1>, A1 : ComposableAdapter.ViewTypeProvider,
A2 : RecyclerView.Adapter<V2>, A2 : ComposableAdapter.ViewTypeProvider {
// body
}
class BiAdapter<C : RecyclerView.ViewHolder, V1 : C, V2 : C, out A1, out A2>(
val adapter1: A1,
val adapter2: A2
) : RecyclerView.Adapter<C>()
where
A1 : RecyclerView.Adapter<V1>, A1 : ComposableAdapter.ViewTypeProvider,
A2 : RecyclerView.Adapter<V2>, A2 : ComposableAdapter.ViewTypeProvider
{
// body
}
Type parameter list
Value argument list
Value parameter list
Rule id: no-blank-line-in-list
(standard
rule set)
Note
This rule is only run when ktlint_code_style
is set to ktlint_official
or when the rule is enabled explicitly.
Parameter list spacing¶
Consistent spacing inside the parameter list.
Rule id: parameter-list-spacing
(standard
rule set)
String template indent¶
Enforce consistent string template indentation for multiline string templates which are post-fixed with .trimIndent()
. The opening and closing """
are placed on separate lines and the indentation of the content of the template is aligned with the """
.
Rule id: string-template-indent
(standard
rule set)
Note
This rule is only run when ktlint_code_style
is set to ktlint_official
or when the rule is enabled explicitly.
Try catch finally spacing¶
Enforce consistent spacing in try { .. } catch { .. } finally { .. }
.
Rule id: try-catch-finally-spacing
(standard
rule set)
Note
This rule is only run when ktlint_code_style
is set to ktlint_official
or when the rule is enabled explicitly.
Type argument list spacing¶
Spacing before and after the angle brackets of a type argument list.
Rule id: type-argument-list-spacing
(standard
rule set)
Type parameter list spacing¶
Spacing after a type parameter list in function and class declarations.
Rule id: type-parameter-list-spacing
(standard
rule set)
Wrapping¶
Content receiver wrapping¶
Wraps the content receiver list to a separate line regardless of maximum line length. If the maximum line length is configured and is exceeded, wrap the context receivers and if needed its projection types to separate lines.
// ALways wrap regardless of whether max line length is set
context(Foo)
fun fooBar()
// Wrap each context receiver to a separate line when the
// entire context receiver list does not fit on a single line
context(
Fooooooooooooooooooo1,
Foooooooooooooooooooooooooooooo2
)
fun fooBar()
// Wrap each context receiver to a separate line when the
// entire context receiver list does not fit on a single line.
// Also, wrap each of it projection types in case a context
// receiver does not fit on a single line after it has been
// wrapped.
context(
Foooooooooooooooo<
Foo,
Bar
>
)
fun fooBar()
// Should be wrapped regardless of whether max line length is set
context(Foo) fun fooBar()
// Should be wrapped when the entire context receiver list does not
// fit on a single line
context(Fooooooooooooooooooo1, Foooooooooooooooooooooooooooooo2)
fun fooBar()
// Should be wrapped when the entire context receiver list does not
// fit on a single line. Also, it should wrap each of it projection
// type in case a context receiver does not fit on a single line
// after it has been wrapped.
context(Foooooooooooooooo<Foo, Bar>)
fun fooBar()
Rule id: context-receiver-wrapping
(standard
rule set)
Enum wrapping¶
An enum should be a single line, or each enum entry has to be placed on a separate line. In case the enumeration contains enum entries and declarations those are to be separated by a blank line.
Rule id: enum-wrapping
(standard
rule set)
Multiline expression wrapping¶
Multiline expression on the right hand side of an expression are forced to start on a separate line. Expressions in return statement are excluded as that would result in a compilation error.
Rule id: multiline-expression-wrapping
(standard
rule set)
Note
This rule is only run when ktlint_code_style
is set to ktlint_official
or when the rule is enabled explicitly.