diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/EnumsSeparated.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/EnumsSeparated.kt index 30970edc44..d268b6b243 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/EnumsSeparated.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/EnumsSeparated.kt @@ -9,10 +9,12 @@ import org.cqfn.diktat.ruleset.utils.getAllChildrenWithType import org.cqfn.diktat.ruleset.utils.hasChildOfType import org.cqfn.diktat.ruleset.utils.isClassEnum +import com.pinterest.ktlint.core.ast.ElementType.BLOCK_COMMENT import com.pinterest.ktlint.core.ast.ElementType.CLASS import com.pinterest.ktlint.core.ast.ElementType.CLASS_BODY import com.pinterest.ktlint.core.ast.ElementType.COMMA import com.pinterest.ktlint.core.ast.ElementType.ENUM_ENTRY +import com.pinterest.ktlint.core.ast.ElementType.EOL_COMMENT import com.pinterest.ktlint.core.ast.ElementType.IDENTIFIER import com.pinterest.ktlint.core.ast.ElementType.LBRACE import com.pinterest.ktlint.core.ast.ElementType.RBRACE @@ -48,13 +50,22 @@ class EnumsSeparated(configRules: List) : DiktatRule( if (!it.treeNext.isWhiteSpaceWithNewline()) { ENUMS_SEPARATED.warnAndFix(configRules, emitWarn, isFixMode, "enum entries must end with a line break", it.startOffset, it) { - it.appendNewlineMergingWhiteSpace(it.treeNext, it.treeNext) + it.appendNewline() } } } checkLastEnum(enumEntries.last()) } + private fun ASTNode.appendNewline() { + val nextNode = this.treeNext + if (nextNode.elementType == WHITE_SPACE) { + (nextNode as LeafPsiElement).rawReplaceWithText("\n${nextNode.text}") + } else { + this.treeParent.addChild(PsiWhiteSpaceImpl("\n"), nextNode) + } + } + private fun isEnumOneLine(nodes: List) = nodes.dropLast(1).none { it.treeNext.isWhiteSpaceWithNewline() } @@ -87,10 +98,19 @@ class EnumsSeparated(configRules: List) : DiktatRule( if (!node.hasChildOfType(COMMA)) { ENUMS_SEPARATED.warnAndFix(configRules, emitWarn, isFixMode, "last enum entry must end with a comma", node.startOffset, node) { - node.addChild(LeafPsiElement(COMMA, ","), node.findChildByType(SEMICOLON)!!.treePrev) + val commaLocation = node.findChildByType(SEMICOLON)!!.findLatestTreePrevMatching { + it.elementType !in setOf(EOL_COMMENT, BLOCK_COMMENT, WHITE_SPACE) + } + node.addChild(LeafPsiElement(COMMA, ","), commaLocation.treeNext) } } } + + private fun ASTNode.findLatestTreePrevMatching(predicate: (ASTNode) -> Boolean): ASTNode { + val result = this.treePrev + return if (predicate(result)) result else result.findLatestTreePrevMatching(predicate) + } + companion object { const val NAME_ID = "abq-enum-separated" private val simpleValue = listOf(IDENTIFIER, WHITE_SPACE, COMMA, SEMICOLON) diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/EnumsSeparatedFixTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/EnumsSeparatedFixTest.kt index 94a65a92bd..0617b45687 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/EnumsSeparatedFixTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/EnumsSeparatedFixTest.kt @@ -13,4 +13,10 @@ class EnumsSeparatedFixTest : FixTestBase("test/paragraph3/enum_separated", ::En fun `test enums split`() { fixAndCompare("EnumSeparatedExpected.kt", "EnumSeparatedTest.kt") } + + @Test + @Tag(WarningNames.ENUMS_SEPARATED) + fun `last element with comment`() { + fixAndCompare("LastElementCommentExpected.kt", "LastElementCommentTest.kt") + } } diff --git a/diktat-rules/src/test/resources/test/paragraph3/enum_separated/EnumSeparatedExpected.kt b/diktat-rules/src/test/resources/test/paragraph3/enum_separated/EnumSeparatedExpected.kt index 537470cb30..bd06af5c9f 100644 --- a/diktat-rules/src/test/resources/test/paragraph3/enum_separated/EnumSeparatedExpected.kt +++ b/diktat-rules/src/test/resources/test/paragraph3/enum_separated/EnumSeparatedExpected.kt @@ -7,7 +7,7 @@ enum class ENUM { enum class ENUM { RED(0xFF0000), GREEN(0x00FF00), - BLUE(0x0000FF) /*sdcsc*/, + BLUE(0x0000FF), /*sdcsc*/ ; } diff --git a/diktat-rules/src/test/resources/test/paragraph3/enum_separated/LastElementCommentExpected.kt b/diktat-rules/src/test/resources/test/paragraph3/enum_separated/LastElementCommentExpected.kt new file mode 100644 index 0000000000..bdc9943090 --- /dev/null +++ b/diktat-rules/src/test/resources/test/paragraph3/enum_separated/LastElementCommentExpected.kt @@ -0,0 +1,96 @@ +package test.paragraph3.enum_separated + +enum class Foo0 { + A, + B, + C, +; +} + +enum class Foo11 { + A, + B, + C, // some comment 11 +; +} + +enum class Foo12 { + A, + B, + C,// some comment 12 +; +} + +enum class Foo13 { + A, + B, + C, +;// some comment 13 +} + +enum class Foo14 { + A, + B, + C, +; // some comment 14 +} + +enum class Foo21 { + A, + B, + C, /* some comment 21 */ +; +} + +enum class Foo22 { + A, + B, + C,/* some comment 22 */ +; +} + +enum class Foo23 { + A, + B, + C, +;/* some comment 23 */ +} + +enum class Foo24 { + A, + B, + C, +; /* some comment 24 */ +} + +enum class Foo31 { + A, + B, + C, +; + /** some comment 31 */ +} + +enum class Foo32 { + A, + B, + C, +; +/** some comment 32 */ +} + +enum class Foo33 { + A, + B, + C, +; +/** some comment 33 */ +} + +enum class Foo34 { + A, + B, + C, +; + /** some comment 34 */ +} diff --git a/diktat-rules/src/test/resources/test/paragraph3/enum_separated/LastElementCommentTest.kt b/diktat-rules/src/test/resources/test/paragraph3/enum_separated/LastElementCommentTest.kt new file mode 100644 index 0000000000..0705384cdd --- /dev/null +++ b/diktat-rules/src/test/resources/test/paragraph3/enum_separated/LastElementCommentTest.kt @@ -0,0 +1,79 @@ +package test.paragraph3.enum_separated + +enum class Foo0 { + A, + B, + C +} + +enum class Foo11 { + A, + B, + C // some comment 11 +} + +enum class Foo12 { + A, + B, + C// some comment 12 +} + +enum class Foo13 { + A, + B, + C;// some comment 13 +} + +enum class Foo14 { + A, + B, + C; // some comment 14 +} + +enum class Foo21 { + A, + B, + C /* some comment 21 */ +} + +enum class Foo22 { + A, + B, + C/* some comment 22 */ +} + +enum class Foo23 { + A, + B, + C;/* some comment 23 */ +} + +enum class Foo24 { + A, + B, + C; /* some comment 24 */ +} + +enum class Foo31 { + A, + B, + C /** some comment 31 */ +} + +enum class Foo32 { + A, + B, + C/** some comment 32 */ +} + +enum class Foo33 { + A, + B, + C;/** some comment 33 */ +} + +enum class Foo34 { + A, + B, + C; /** some comment 34 */ +} \ No newline at end of file