Skip to content

Commit

Permalink
Implement a rule to lint enum entry name (#638)
Browse files Browse the repository at this point in the history
* Implement a rule to lint enum entry name

* Disable auto format for enum entry name for now

* Ignore formatting test
  • Loading branch information
yukukotani authored and Tapchicoma committed Nov 26, 2019
1 parent 61fd025 commit 375509f
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 1 deletion.
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() }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class ExperimentalRuleSetProvider : RuleSetProvider {
IndentationRule(),
MultiLineIfElseRule(),
NoEmptyFirstLineInMethodBlockRule(),
PackageNameRule()
PackageNameRule(),
EnumEntryNameCaseRule()
)
}
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)
}
}

0 comments on commit 375509f

Please sign in to comment.