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)
Chain method continuation¶
In a multiline method chain, the chain operators (.
or ?.
) have to be aligned with each other.
Multiple chained methods on a single line are allowed as long as the maximum line length, and the maximum number of chain operators are not exceeded. Under certain conditions, it is allowed that the expression before the first and/or the expression after the last chain operator is a multiline expression.
The .
in java.class
is ignored when wrapping on chain operators.
This rule can be configured with .editorconfig
property ktlint_chain_method_rule_force_multiline_when_chain_operator_count_greater_or_equal_than
.
Warning
Binary expression for which the left and/or right operand consist of method chain are currently being ignored by this rule. Please reach out, if you can help to determine what the best strategy is to deal with such kind of expressions.
Configuration setting | ktlint_official | intellij_idea | android_studio |
---|---|---|---|
ktlint_chain_method_rule_force_multiline_when_chain_operator_count_greater_or_equal_than Force wrapping of chained methods in case an expression contains at least the specified number of chain operators. If a chained method contains nested expressions, the chain operators of the inner expression are not taken into account. Use value unset (default) to disable this setting. |
4 | 4 | 4 |
Rule id: chain-method-continuation
(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.
Class signature¶
Rewrites the class signature to a consistent format respecting the .editorconfig
property max_line_length
if set. In the ktlint_official
code style all class parameters are wrapped by default. Set .editorconfig
property ktlint_class_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than
to a value greater than 1 to allow class with a few parameters to be placed on a single line.
The other code styles allow an infinite amount of parameters on the same line (as long as the max_line_length
is not exceeded) unless .editorconfig
property ktlint_class_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than
is set explicitly.
// Assume that max_line_length is not exceeded when written as single line
class Foo0
class Foo1(
a: Any,
)
class Foo2(
a: Any,
b: Any,
)
class Foo3(
@Foo a: Any,
b: Any,
c: Any,
)
class Foo4(
a: Any,
b: Any,
c: Any,
) : FooBar(a, c)
class Foo5 :
FooBar(
"bar1",
"bar2",
) {
// body
}
class Foo6(
val bar1: Bar,
val bar2: Bar,
) : FooBar(
bar1,
bar2,
) {
// body
}
class Foo7(
val bar1: Bar,
val bar2: Bar,
) : FooBar(
bar1,
bar2,
),
BarFoo1,
BarFoo2 {
// body
}
class Foo8
constructor(
val bar1: Bar,
val bar2: Bar,
) : FooBar(bar1, bar2),
BarFoo1,
BarFoo2 {
// body
}
// Assume that max_line_length is not exceeded when written as single line
class Foo0()
class Foo1(a: Any)
class Foo2(a: Any, b: Any)
class Foo3(@Foo a: Any, b: Any, c: Any)
class Foo4(a: Any, b: Any, c: Any) : FooBar(a, c)
class Foo5 : FooBar(
"bar1",
"bar2",
) {
// body
}
class Foo6(
val bar1: Bar,
val bar2: Bar,
) : FooBar(
bar1,
bar2,
) {
// body
}
class Foo7(
val bar1: Bar,
val bar2: Bar,
) : FooBar(
bar1,
bar2,
),
BarFoo1,
BarFoo2 {
// body
}
class Foo8
constructor(
val bar1: Bar,
val bar2: Bar,
) : FooBar(bar1, bar2),
BarFoo1,
BarFoo2 {
// body
}
// Assume that the last allowed character is
// at the X character on the right X
class Foo0
class Foo1(
a: Any,
)
class Foo2(a: Any)
class Foo3(
a: Any,
b: Any,
)
class Foo4(a: Any, b: Any)
class Foo5(@Foo a: Any, b: Any, c: Any)
class Foo6(a: Any, b: Any, c: Any) :
FooBar(a, c)
class Foo7 : FooBar(
"bar1",
"bar2",
) {
// body
}
class Foo8(
val bar1: Bar,
val bar2: Bar,
) : FooBar(
bar1,
bar2
) {
// body
}
class Foo9(
val bar1: Bar,
val bar2: Bar,
) : FooBar(
bar1,
bar2
),
BarFoo1,
BarFoo2 {
// body
}
class Foo10
constructor(
val bar1: Bar,
val bar2: Bar,
) : FooBar(bar1, bar2),
BarFoo1,
BarFoo2 {
// body
}
Configuration setting | ktlint_official | intellij_idea | android_studio |
---|---|---|---|
ktlint_class_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than Force wrapping of the parameters of the class signature in case it contains at least the specified number of parameters, even in case the entire class signature would fit on a single line. Use value unset to disable this setting. |
1 | unset |
unset |
Rule id: class-signature
(standard
rule set)
Condition wrapping¶
Wraps each operand in a multiline condition to a separate line.
Rule id: condition-wrapping
(standard
rule set)
Function expression body¶
Rewrites a function body only containing a return
or throw
expression to an expression body.
Note
If the function body contains a comment, it is not rewritten to an expression body.
fun foo1() = "foo"
fun foo2(): String = "foo"
fun foo3(): Unit = throw IllegalArgumentException("some message")
fun foo4(): Foo = throw IllegalArgumentException("some message")
fun foo5() {
return "foo" // some comment
}
fun foo6(): String {
/* some comment */
return "foo"
}
fun foo7() {
throw IllegalArgumentException("some message")
/* some comment */
}
fun foo8(): Foo {
throw IllegalArgumentException("some message")
// some comment
}
Rule id: function-expression-body
(standard
rule set)
Function literal¶
Enforces the parameters of a function literal and the arrow to be written on the same line as the opening brace if the maximum line length is not exceeded. In case the parameters are wrapped to multiple lines then this is respected.
If the function literal contains multiple parameter and at least one parameter other than the first parameter starts on a new line than all parameters and the arrow are wrapped to separate lines.
val foobar1 = { foo + bar }
val foobar2 =
{
foo + bar
}
val foobar3 =
{ foo: Foo ->
foo.repeat(2)
}
val foobar4 =
{ foo: Foo, bar: Bar ->
foo + bar
}
val foobar5 = { foo: Foo, bar: Bar -> foo + bar }
val foobar6 =
{
foo: Foo,
bar: Bar,
->
foo + bar
}
// Assume that the last allowed character is
// at the X character on the right X
val foobar7 =
barrrrrrrrrrrrrr {
fooooooooooooooo: Foo
->
foo.repeat(2)
}
Rule id: function-literal
(standard
rule set)
Function type modifier spacing¶
Enforce a single whitespace between the modifier list and the function type.
Rule id: function-type-modifier-spacing
(standard
rule set)
Mixed condition operators¶
Conditions should not use a both &&
and ||
operators between operators at the same level. By using parenthesis the expression is to be clarified.
Rule id: mixed-condition-operators
(standard
rule set)
Multiline loop¶
Braces required for multiline for, while, and do statements.
Rule id: multiline-loop
(standard
rule set)