forked from pinterest/ktlint
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new experimental rule for aligning the initial stars in a block c…
…omment when present Closes pinterest#297
- Loading branch information
1 parent
cf96f51
commit 613d59b
Showing
6 changed files
with
171 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
.../kotlin/com/pinterest/ktlint/ruleset/experimental/BlockCommentInitialStarAlignmentRule.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package com.pinterest.ktlint.ruleset.experimental | ||
|
||
import com.pinterest.ktlint.core.Rule | ||
import com.pinterest.ktlint.core.ast.ElementType.BLOCK_COMMENT | ||
import com.pinterest.ktlint.core.ast.lineIndent | ||
import org.jetbrains.kotlin.com.intellij.lang.ASTNode | ||
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafElement | ||
|
||
/** | ||
* When present, align the initial star in a block comment. | ||
*/ | ||
class BlockCommentInitialStarAlignmentRule : | ||
Rule( | ||
"block-comment-initial-star-alignment", | ||
visitorModifiers = setOf( | ||
// The block comment is a node which can contain multiple lines. The indent of the second and later line | ||
// should be determined based on the indent of the block comment node. This indent is determined by the | ||
// indentation rule. | ||
VisitorModifier.RunAfterRule("standard:indent") | ||
) | ||
) { | ||
override fun visit( | ||
node: ASTNode, | ||
autoCorrect: Boolean, | ||
emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit | ||
) { | ||
if (node.elementType == BLOCK_COMMENT) { | ||
val expectedIndentForLineWithInitialStar = node.lineIndent() + " *" | ||
val lines = node.text.split("\n") | ||
var offset = node.startOffset | ||
val modifiedLines = mutableListOf<String>() | ||
lines.forEach { line -> | ||
val modifiedLine = | ||
Regex("^([\t ]+\\*)(.*)$") | ||
.find(line) | ||
?.let { matchResult -> | ||
val (prefix, content) = matchResult.destructured | ||
if (prefix != expectedIndentForLineWithInitialStar) { | ||
emit(offset + prefix.length, "Initial star should be align with start of block comment", true) | ||
expectedIndentForLineWithInitialStar + content | ||
} else { | ||
line | ||
} | ||
} | ||
?: line | ||
modifiedLines.add(modifiedLine) | ||
offset += line.length + 1 | ||
} | ||
if (autoCorrect) { | ||
val newText = modifiedLines.joinToString(separator = System.lineSeparator()) | ||
if (node.text != newText) { | ||
(node as LeafElement).rawReplaceWithText(newText) | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 94 additions & 0 deletions
94
.../src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/BlockCommentInitialStarTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package com.pinterest.ktlint.ruleset.experimental | ||
|
||
import com.pinterest.ktlint.core.LintError | ||
import com.pinterest.ktlint.test.format | ||
import com.pinterest.ktlint.test.lint | ||
import org.assertj.core.api.Assertions.assertThat | ||
import org.junit.jupiter.api.Test | ||
|
||
class BlockCommentInitialStarTest { | ||
@Test | ||
fun `Given a block comment for which the indentation followed by the star already aligns with the star in the first line of the block comment then do not reformat`() { | ||
val code = | ||
""" | ||
/* | ||
* This blocked is formatted well. | ||
*/ | ||
""".trimIndent() | ||
assertThat(BlockCommentInitialStarAlignmentRule().lint(code)).isEmpty() | ||
assertThat(BlockCommentInitialStarAlignmentRule().format(code)).isEqualTo(code) | ||
} | ||
|
||
@Test | ||
fun `Given a block comment with a line that does not have an initial star then do not reformat that line`() { | ||
val code = | ||
""" | ||
/* | ||
This blocked is formatted well. | ||
*/ | ||
""".trimIndent() | ||
assertThat(BlockCommentInitialStarAlignmentRule().lint(code)).isEmpty() | ||
assertThat(BlockCommentInitialStarAlignmentRule().format(code)).isEqualTo(code) | ||
} | ||
|
||
@Test | ||
fun `Given a block comment with a line that contains a star which is preceded by a non-space or non-tab character then do not reformat that line`() { | ||
val code = | ||
""" | ||
/* | ||
- This line contains a * but it is not the initial *. | ||
*/ | ||
""".trimIndent() | ||
assertThat(BlockCommentInitialStarAlignmentRule().lint(code)).isEmpty() | ||
assertThat(BlockCommentInitialStarAlignmentRule().format(code)).isEqualTo(code) | ||
} | ||
|
||
@Test | ||
fun `Given that the initial stars of the block comment are not aligned then reformat`() { | ||
val code = | ||
""" | ||
/* | ||
* This blocked is not formatted well. | ||
*/ | ||
""".trimIndent() | ||
val formattedCode = | ||
""" | ||
/* | ||
* This blocked is not formatted well. | ||
*/ | ||
""".trimIndent() | ||
assertThat(BlockCommentInitialStarAlignmentRule().lint(code)).containsExactly( | ||
LintError(2, 8, "block-comment-initial-star-alignment", "Initial star should be align with start of block comment"), | ||
LintError(3, 6, "block-comment-initial-star-alignment", "Initial star should be align with start of block comment") | ||
) | ||
assertThat(BlockCommentInitialStarAlignmentRule().format(code)).isEqualTo(formattedCode) | ||
} | ||
|
||
@Test | ||
fun `Given function contain a block comment for which the initial stars of the block comment are not aligned then reformat`() { | ||
val code = | ||
""" | ||
fun foo() { | ||
/* | ||
* This blocked is not formatted well. | ||
* This blocked is not formatted well. | ||
*/ | ||
} | ||
""".trimIndent() | ||
val formattedCode = | ||
""" | ||
fun foo() { | ||
/* | ||
* This blocked is not formatted well. | ||
* This blocked is not formatted well. | ||
*/ | ||
} | ||
""".trimIndent() | ||
assertThat(BlockCommentInitialStarAlignmentRule().lint(code)).containsExactly( | ||
LintError(3, 12, "block-comment-initial-star-alignment", "Initial star should be align with start of block comment"), | ||
LintError(4, 4, "block-comment-initial-star-alignment", "Initial star should be align with start of block comment"), | ||
LintError(5, 10, "block-comment-initial-star-alignment", "Initial star should be align with start of block comment") | ||
) | ||
assertThat(BlockCommentInitialStarAlignmentRule().format(code)).isEqualTo(formattedCode) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters