diktat
diktat copied to clipboard
`WRONG_INDENTATION` rule behaving incorrectly with superclass constructor call arguments
Both this
class Klass : Base("foo")
and this superclass constructor calls are indented correctly, in full accordance with 3.3. Indentation:
class Klass :
Base("foo")
Now consider we want to split the superclass constructor call arguments into multiple lines:
class Klass : Base(
"foo"
)
Even this is correct, too. Now, let's put a newline before the superclass call:
class Klass :
Base(
"foo"
)
DiKTat will immediately complain:
Klass.kt:3:1: [WRONG_INDENTATION] only spaces are allowed for indentation and each indentation should equal to 4 spaces (tabs are not allowed): expected 4 but was 8 (diktat-ruleset:indentation)
Klass.kt:4:1: [WRONG_INDENTATION] only spaces are allowed for indentation and each indentation should equal to 4 spaces (tabs are not allowed): expected 0 but was 4 (diktat-ruleset:indentation)
So apparently DiKTat expects the following formatting (outright wrong):
class Klass :
Base(
"foo"
)
Steps to Reproduce
As it's obvious from the above example, two conditions must be met for the issue to manifest itself:
- The supertype constructor call should be put on a separate line.
- The supertype constructor call arguments should be put on individual lines.
There're more real-life examples which trigger this issue, e. g.:
class Klass :
Base(
"foo",
::Klass,
listOf(
"foo",
"bar",
"baz"
)
),
Cloneable,
CharSequence {
// ...
}
or even
class IndentationRuleFixTest :
FixTestBase(
"test/paragraph3/indentation",
::IndentationRule,
listOf(
RulesConfig(WRONG_INDENTATION.name, true,
mapOf(
"newlineAtEnd" to "true",
"extendedIndentOfParameters" to "true",
"alignedParameters" to "true",
"extendedIndentAfterOperators" to "true",
"extendedIndentBeforeDot" to "true",
)
)
)
),
IndentationRuleTestMixin,
IndentationRuleTestResources {
// ...
}
Environment information
- diktat version: 1.2.0
- build tool (maven/gradle): Maven
- how is diktat run (CLI, plugin, etc.): Maven plug-in
- kotlin version: 1.7.0
- operating system: Windows
If we look at this particular example:
class Klass :
Base(
"foo",
::Klass,
listOf(
"foo",
"bar",
"baz"
)
),
Cloneable,
CharSequence {
// ...
}
— it can be reformatted like this, triggering only a WRONG_NEWLINES warning and no WRONG_INDENTATION warnings (which is the expected behaviour):
class Klass : Base(
"foo",
::Klass,
listOf(
"foo",
"bar",
"baz"
)
), Cloneable, CharSequence {
// ...
}
— or like this, triggering false positive WRONG_INDENTATION warnings on lines 10-11:
class Klass : Base(
"foo",
::Klass,
listOf(
"foo",
"bar",
"baz"
)
),
Cloneable,
CharSequence {
// ...
}
Klass.kt:10:1: [WRONG_INDENTATION] only spaces are allowed for indentation and each indentation should equal to 4 spaces (tabs are not allowed): expected 0 but was 4 (diktat-ruleset:indentation)
Klass.kt:11:1: [WRONG_INDENTATION] only spaces are allowed for indentation and each indentation should equal to 4 spaces (tabs are not allowed): expected 0 but was 4 (diktat-ruleset:indentation)
Important, let's do it! But not break anything else :)
More examples:
class C(private val property: (rulesConfigList: List<RulesConfig>) -> Rule,
arg1: List<RulesConfig>?) :
Base(
id = DIKTAT_RULE_SET_ID,
about = NO_ABOUT,
) {
}
and
class C
@JvmOverloads
constructor(private val property: DiktatRuleSetFactory = DiktatRuleSetFactory()) :
Base(
id = DIKTAT_RULE_SET_ID,
about = About(
maintainer = "Diktat",
description = "Strict coding standard for Kotlin and a custom set of rules for detecting code smells, code style issues, and bugs",
license = "https://github.com/saveourtool/diktat/blob/master/LICENSE",
repositoryUrl = "https://github.com/saveourtool/diktat",
issueTrackerUrl = "https://github.com/saveourtool/diktat/issues",
),
) {
}