-
Notifications
You must be signed in to change notification settings - Fork 512
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement a rule to lint enum entry name (#638)
* Implement a rule to lint enum entry name * Disable auto format for enum entry name for now * Ignore formatting test
- Loading branch information
1 parent
61fd025
commit 375509f
Showing
3 changed files
with
119 additions
and
1 deletion.
There are no files selected for viewing
59 changes: 59 additions & 0 deletions
59
...mental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/EnumEntryNameCaseRule.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,59 @@ | ||
package com.pinterest.ktlint.ruleset.experimental | ||
|
||
import com.pinterest.ktlint.core.Rule | ||
import org.jetbrains.kotlin.com.intellij.lang.ASTNode | ||
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.CompositeElement | ||
import org.jetbrains.kotlin.psi.KtEnumEntry | ||
|
||
class EnumEntryNameCaseRule : Rule("enum-entry-name-case") { | ||
|
||
companion object { | ||
const val ERROR_MESSAGE = "Enum entry name should be uppercase underscore-separated names like \"ENUM_ENTRY\" or upper camel-case like \"EnumEntry\"" | ||
} | ||
|
||
override fun visit( | ||
node: ASTNode, | ||
autoCorrect: Boolean, | ||
emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit | ||
) { | ||
if (node !is CompositeElement) { | ||
return | ||
} | ||
val enumEntry = node.psi as? KtEnumEntry ?: return | ||
val name = enumEntry.name ?: return | ||
|
||
if (name.containsLowerCase()) { | ||
// In case of lower camel case like "enumName", or all lower case like "enumname" | ||
if (!name.startsWithUpperCase()) { | ||
emit( | ||
node.startOffset, | ||
ERROR_MESSAGE, false | ||
) | ||
|
||
if (autoCorrect) correct(enumEntry, name) | ||
} | ||
|
||
// In case of lower case with underscore like "enum_name" | ||
else if (name.contains("_") && name.containsLowerCase()) { | ||
emit( | ||
node.startOffset, | ||
ERROR_MESSAGE, false | ||
) | ||
|
||
if (autoCorrect) correct(enumEntry, name) | ||
} | ||
} | ||
} | ||
|
||
private fun correct(enumEntry: KtEnumEntry, originalName: String) { | ||
enumEntry.setName(originalName.toUpperCase()) | ||
} | ||
|
||
private fun String.startsWithUpperCase(): Boolean { | ||
return this.isNotEmpty() && this[0].isUpperCase() | ||
} | ||
|
||
private fun String.containsLowerCase(): Boolean { | ||
return this.any { it.isLowerCase() } | ||
} | ||
} |
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
58 changes: 58 additions & 0 deletions
58
...al/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/EnumEntryNameCaseRuleTest.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,58 @@ | ||
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.Ignore | ||
import org.junit.Test | ||
|
||
class EnumEntryNameCaseRuleTest { | ||
|
||
@Test | ||
fun testFormatIsCorrect() { | ||
val formatted = | ||
""" | ||
enum class FirstEnum { | ||
ENUM_ENTRY | ||
} | ||
enum class SecondEnum { | ||
EnumEntry | ||
} | ||
""".trimIndent() | ||
|
||
assertThat(EnumEntryNameCaseRule().lint(formatted)).isEmpty() | ||
assertThat(EnumEntryNameCaseRule().format(formatted)).isEqualTo(formatted) | ||
} | ||
|
||
@Test | ||
@Ignore("https://github.com/pinterest/ktlint/pull/638#issuecomment-558119749") | ||
fun testFormat() { | ||
val unformatted = | ||
""" | ||
enum class FirstEnum { | ||
enumEntry | ||
} | ||
enum class SecondEnum { | ||
enum_entry | ||
} | ||
""".trimIndent() | ||
val formatted = | ||
""" | ||
enum class FirstEnum { | ||
ENUMENTRY | ||
} | ||
enum class SecondEnum { | ||
ENUM_ENTRY | ||
} | ||
""".trimIndent() | ||
|
||
assertThat(EnumEntryNameCaseRule().lint(unformatted)).isEqualTo( | ||
listOf( | ||
LintError(2, 5, "enum-entry-name-case", EnumEntryNameCaseRule.ERROR_MESSAGE), | ||
LintError(5, 5, "enum-entry-name-case", EnumEntryNameCaseRule.ERROR_MESSAGE) | ||
) | ||
) | ||
assertThat(EnumEntryNameCaseRule().format(unformatted)).isEqualTo(formatted) | ||
} | ||
} |