Skip to content

Commit

Permalink
Fix KDOC indentation for tab indentation style
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul Dingemans committed Oct 31, 2021
1 parent a8ccc56 commit 1d52f00
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import com.pinterest.ktlint.core.ast.ElementType.FUN
import com.pinterest.ktlint.core.ast.ElementType.FUNCTION_LITERAL
import com.pinterest.ktlint.core.ast.ElementType.GT
import com.pinterest.ktlint.core.ast.ElementType.KDOC
import com.pinterest.ktlint.core.ast.ElementType.KDOC_END
import com.pinterest.ktlint.core.ast.ElementType.KDOC_LEADING_ASTERISK
import com.pinterest.ktlint.core.ast.ElementType.KDOC_START
import com.pinterest.ktlint.core.ast.ElementType.LAMBDA_EXPRESSION
import com.pinterest.ktlint.core.ast.ElementType.LBRACE
Expand All @@ -44,7 +46,6 @@ import com.pinterest.ktlint.core.ast.ElementType.RBRACE
import com.pinterest.ktlint.core.ast.ElementType.RBRACKET
import com.pinterest.ktlint.core.ast.ElementType.REGULAR_STRING_PART
import com.pinterest.ktlint.core.ast.ElementType.RPAR
import com.pinterest.ktlint.core.ast.ElementType.SAFE_ACCESS
import com.pinterest.ktlint.core.ast.ElementType.SAFE_ACCESS_EXPRESSION
import com.pinterest.ktlint.core.ast.ElementType.SHORT_STRING_TEMPLATE_ENTRY
import com.pinterest.ktlint.core.ast.ElementType.STRING_TEMPLATE
Expand Down Expand Up @@ -989,7 +990,14 @@ class IndentationRule : Rule("indent"), Rule.Modifier.RestrictToRootLast {
}
}
IndentStyle.TAB -> {
if (' ' in nodeIndent) {
val isKdocIndent = node.isKDocIndent()
val indentWithoutKdocIndent =
if (isKdocIndent) {
nodeIndent.removeSuffix(" ")
} else {
nodeIndent
}
if (' ' in indentWithoutKdocIndent) {
emit(
node.startOffset + text.length - nodeIndent.length,
"Unexpected space character(s)",
Expand All @@ -998,7 +1006,13 @@ class IndentationRule : Rule("indent"), Rule.Modifier.RestrictToRootLast {
// First normalize the indent to spaces using the tab width.
val asSpaces = nodeIndent.replace("\t", " ".repeat(editorConfig.tabWidth))
// Then divide that space-based indent into tabs.
"\t".repeat(asSpaces.length / editorConfig.tabWidth)
"\t".repeat(asSpaces.length / editorConfig.tabWidth) +
// Re-add the kdoc indent when it was present before
if (isKdocIndent) {
" "
} else {
""
}
} else {
nodeIndent
}
Expand Down Expand Up @@ -1117,6 +1131,15 @@ class IndentationRule : Rule("indent"), Rule.Modifier.RestrictToRootLast {
}
}

private fun ASTNode.isKDocIndent() =
if (text.lastOrNull() == ' ') {
// The indentation of a KDoc comment contains a space as the last character regardless of the indentation style
// (tabs or spaces) except for the starting line of the KDoc comment
nextLeaf()?.elementType == KDOC_LEADING_ASTERISK || nextLeaf()?.elementType == KDOC_END
} else {
false
}

private fun ASTNode.isIndentBeforeClosingQuote() =
elementType == CLOSING_QUOTE || (text.isBlank() && nextCodeSibling()?.elementType == CLOSING_QUOTE)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1296,6 +1296,53 @@ internal class IndentationRuleTest {
assertThat(IndentationRule().format(code)).isEqualTo(code)
}

@Test
fun `format kdoc`() {
@Suppress("RemoveCurlyBracesFromTemplate")
val code =
"""
/**
* some function1
*/
fun someFunction1() {
return Unit
}
class SomeClass {
/**
* some function2
*/
fun someFunction2() {
return Unit
}
}
""".trimIndent()
@Suppress("RemoveCurlyBracesFromTemplate")
val codeTabs =
"""
/**
* some function1
*/
fun someFunction1() {
${TAB}return Unit
}
class SomeClass {
${TAB}/**
${TAB} * some function2
${TAB} */
${TAB}fun someFunction2() {
${TAB}${TAB}return Unit
${TAB}}
}
""".trimIndent()
assertThat(IndentationRule().lint(code)).isEmpty()
assertThat(IndentationRule().format(code)).isEqualTo(code)

assertThat(IndentationRule().lint(codeTabs, INDENT_STYLE_TABS)).isEmpty()
assertThat(IndentationRule().format(codeTabs, INDENT_STYLE_TABS)).isEqualTo(codeTabs)
}

private companion object {
const val MULTILINE_STRING_QUOTE = "${'"'}${'"'}${'"'}"
const val TAB = "${'\t'}"
Expand Down

0 comments on commit 1d52f00

Please sign in to comment.