Experimental rules
Important
Experimental rules in ktlint are part of the standard ruleset. Experimental rules are run only when .editorconfig
property ktlint_experimental
is enabled. Or, when a specific experimental rule is enabled via .editorconfig
property ktlint_<rule-set-id>_<rule-id>
.
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
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
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
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
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
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
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
Package naming¶
Enforce naming of package.
This rule can also be suppressed with the IntelliJ IDEA inspection suppression PackageName
.
Rule id: package-naming
Property naming¶
Enforce naming of property.
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
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
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
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
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
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
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
Type parameter list spacing¶
Spacing after a type parameter list in function and class declarations.
Rule id: type-parameter-list-spacing
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
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
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
Note
This rule is only run when ktlint_code_style
is set to ktlint_official
or when the rule is enabled explicitly.