From 9d597cd0c00611ad61dd3c3db89d10b4c78a84fe Mon Sep 17 00:00:00 2001 From: Andrey Kuleshov Date: Mon, 15 Jun 2020 01:38:25 +0300 Subject: [PATCH] Changes to format fixing. Added aggressive autofix for Enum values format ### What's done: 1) Enum values case format fixing 2) Tests --- .../ruleset/huawei/utils/StringCaseUtils.kt | 65 +++++++++++++++---- .../huawei/chapter1/EnumValueCaseTest.kt | 2 + .../chapter1/IdentifierNamingFixTest.kt | 9 +++ .../class_/IncorrectClassNameExpected.kt | 2 + .../naming/class_/IncorrectClassNameTest.kt | 2 + .../naming/enum_/EnumValueCaseExpected.kt | 10 +++ .../naming/enum_/EnumValueCaseTest.kt | 10 +++ rules-config.json | 5 ++ 8 files changed, 94 insertions(+), 11 deletions(-) create mode 100644 diktat-huawei-rules/src/test/kotlin/com/huawei/rri/fixbot/ruleset/huawei/chapter1/EnumValueCaseTest.kt create mode 100644 diktat-huawei-rules/src/test/resources/test/paragraph1/naming/enum_/EnumValueCaseExpected.kt create mode 100644 diktat-huawei-rules/src/test/resources/test/paragraph1/naming/enum_/EnumValueCaseTest.kt diff --git a/diktat-huawei-rules/src/main/kotlin/com/huawei/rri/fixbot/ruleset/huawei/utils/StringCaseUtils.kt b/diktat-huawei-rules/src/main/kotlin/com/huawei/rri/fixbot/ruleset/huawei/utils/StringCaseUtils.kt index 359fc7a4a8..9c1c97e50d 100644 --- a/diktat-huawei-rules/src/main/kotlin/com/huawei/rri/fixbot/ruleset/huawei/utils/StringCaseUtils.kt +++ b/diktat-huawei-rules/src/main/kotlin/com/huawei/rri/fixbot/ruleset/huawei/utils/StringCaseUtils.kt @@ -35,6 +35,14 @@ fun String.toUpperSnakeCase(): String { // lower_snake -> LOWER_SNAKE if (this.isLowerSnakeCase()) return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_UNDERSCORE, this) + val idx = getFirstLetterOrDigit() + if (idx != -1) { + // any other format -> UPPER_SNAKE_CASE + // [p]a[SC]a[_]l -> [P]A_[SC]_A_[L] + return this[idx].toUpperCase().toString() + convertUnknownCaseToUpperSnake(this.substring(idx + 1), true) + } + + log.error("Not able to fix case format for: $this") return this } @@ -51,11 +59,17 @@ fun String.toLowerCamelCase(): String { // lower_snake -> LOWER_SNAKE if (this.isLowerSnakeCase()) return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, this) - // any other format -> camelCase - // changing first letter to uppercase and replacing several uppercase letters in raw to lowercase: - // example of change: [P]a[SC]a[_]l -> [p]a[Sc]a[L] - // FixMe: there is some discussion on how lowerN_Case should be resolved: to lowerNcase or to lowernCase or lowerNCase (current version) - return this[0].toLowerCase().toString() + convertUnknownCaseToCamel(this.substring(1), false) + val idx = getFirstLetterOrDigit() + if (idx != -1) { + // any other format -> camelCase + // changing first letter to uppercase and replacing several uppercase letters in raw to lowercase: + // example of change: [P]a[SC]a[_]l -> [p]a[Sc]a[L] + // FixMe: there is some discussion on how lowerN_Case should be resolved: to lowerNcase or to lowernCase or lowerNCase (current version) + return this[idx].toLowerCase().toString() + convertUnknownCaseToCamel(this.substring(idx + 1), false) + } + + log.error("Not able to fix case format for: $this") + return this } /** @@ -71,18 +85,25 @@ fun String.toPascalCase(): String { // lower_snake -> LowerSnake if (this.isLowerSnakeCase()) return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, this) - // any other format -> PascalCase - // changing first letter to uppercase and replacing several uppercase letters in raw to lowercase: - // example of change: [p]a[SC]a[_]l -> [P]a[Sc]a[L] - // FixMe: there is some discussion on how PascalN_Case should be resolved: to PascalNcase or to PascalnCase or PascalNCase (current version) - return this[0].toUpperCase().toString() + convertUnknownCaseToCamel(this.substring(1), true) + val idx = getFirstLetterOrDigit() + if (idx != -1) { + // any other format -> PascalCase + // changing first letter to uppercase and replacing several uppercase letters in raw to lowercase: + // example of change: [p]a[SC]a[_]l -> [P]a[Sc]a[L] + // FixMe: there is some discussion on how PascalN_Case should be resolved: to PascalNcase or to PascalnCase or PascalNCase (current version) + return this[idx].toUpperCase().toString() + convertUnknownCaseToCamel(this.substring(idx + 1), true) + } + + log.error("Not able to fix case format for: $this") + return this } private fun convertUnknownCaseToCamel(str: String, isFirstLetterCapital: Boolean): String { + // [p]a[SC]a[_]l -> [P]a[Sc]a[L] var isPreviousLetterCapital = isFirstLetterCapital var isPreviousLetterUnderscore = false return str.map { - return@map if (it.isUpperCase()) { + if (it.isUpperCase()) { val result = if (isPreviousLetterCapital && !isPreviousLetterUnderscore) it.toLowerCase() else it isPreviousLetterCapital = true isPreviousLetterUnderscore = false @@ -104,3 +125,25 @@ private fun convertUnknownCaseToCamel(str: String, isFirstLetterCapital: Boolean } }.joinToString("") } + +private fun convertUnknownCaseToUpperSnake(str: String, isFirstLetterCapital: Boolean): String { + // [p]a[SC]a[_]l -> [P]A_[SC]_A_[L] + var alreadyInsertedUnderscore = isFirstLetterCapital + return str.map { + if (it.isUpperCase()) { + if (!alreadyInsertedUnderscore) { + alreadyInsertedUnderscore = true + "_$it" + } else { + it + } + } else { + alreadyInsertedUnderscore = (it == '_') + it.toUpperCase() + } + + }.joinToString("") +} + +private fun String.getFirstLetterOrDigit() = + indexOfFirst { it.isLetterOrDigit() } diff --git a/diktat-huawei-rules/src/test/kotlin/com/huawei/rri/fixbot/ruleset/huawei/chapter1/EnumValueCaseTest.kt b/diktat-huawei-rules/src/test/kotlin/com/huawei/rri/fixbot/ruleset/huawei/chapter1/EnumValueCaseTest.kt new file mode 100644 index 0000000000..dfac4973e3 --- /dev/null +++ b/diktat-huawei-rules/src/test/kotlin/com/huawei/rri/fixbot/ruleset/huawei/chapter1/EnumValueCaseTest.kt @@ -0,0 +1,2 @@ +package com.huawei.rri.fixbot.ruleset.huawei.chapter1 + diff --git a/diktat-huawei-rules/src/test/kotlin/com/huawei/rri/fixbot/ruleset/huawei/chapter1/IdentifierNamingFixTest.kt b/diktat-huawei-rules/src/test/kotlin/com/huawei/rri/fixbot/ruleset/huawei/chapter1/IdentifierNamingFixTest.kt index 913ee930ad..38b692efbd 100644 --- a/diktat-huawei-rules/src/test/kotlin/com/huawei/rri/fixbot/ruleset/huawei/chapter1/IdentifierNamingFixTest.kt +++ b/diktat-huawei-rules/src/test/kotlin/com/huawei/rri/fixbot/ruleset/huawei/chapter1/IdentifierNamingFixTest.kt @@ -27,6 +27,15 @@ class IdentifierNamingFixTest { ).isEqualTo(true) } + @Test + fun `incorrect enum values case (fix)`() { + assertThat( + TestComparatorUnit("test/paragraph1/naming/enum_", ::format) + .compareFilesFromResources("EnumValueCaseExpected.kt", "EnumValueCaseTest.kt") + ).isEqualTo(true) + + } + private fun format(text: String, fileName: String): String = IdentifierNaming().format(text, fileName) private fun Rule.format(text: String, fileName: String): String { diff --git a/diktat-huawei-rules/src/test/resources/test/paragraph1/naming/class_/IncorrectClassNameExpected.kt b/diktat-huawei-rules/src/test/resources/test/paragraph1/naming/class_/IncorrectClassNameExpected.kt index 636337a63b..298b0de5f8 100644 --- a/diktat-huawei-rules/src/test/resources/test/paragraph1/naming/class_/IncorrectClassNameExpected.kt +++ b/diktat-huawei-rules/src/test/resources/test/paragraph1/naming/class_/IncorrectClassNameExpected.kt @@ -9,3 +9,5 @@ class Pascalcase6 {} class PascAlCase7 {} class PascaLCase8 {} class PascAlCase9 {} +class PascAlCase10 {} +class PascAlCase11 {} diff --git a/diktat-huawei-rules/src/test/resources/test/paragraph1/naming/class_/IncorrectClassNameTest.kt b/diktat-huawei-rules/src/test/resources/test/paragraph1/naming/class_/IncorrectClassNameTest.kt index 4b5b2720fb..7532d000ca 100644 --- a/diktat-huawei-rules/src/test/resources/test/paragraph1/naming/class_/IncorrectClassNameTest.kt +++ b/diktat-huawei-rules/src/test/resources/test/paragraph1/naming/class_/IncorrectClassNameTest.kt @@ -9,3 +9,5 @@ class Pascalcase6 {} class PascAl_Case7 {} class PascaL_Case8 {} class PascAL_Case9 {} +class _PascAL_Case10 {} +class PascAL_Case11_ {} diff --git a/diktat-huawei-rules/src/test/resources/test/paragraph1/naming/enum_/EnumValueCaseExpected.kt b/diktat-huawei-rules/src/test/resources/test/paragraph1/naming/enum_/EnumValueCaseExpected.kt new file mode 100644 index 0000000000..95ab57dfa0 --- /dev/null +++ b/diktat-huawei-rules/src/test/resources/test/paragraph1/naming/enum_/EnumValueCaseExpected.kt @@ -0,0 +1,10 @@ +package com.huawei.test.resources.test.paragraph1.naming.enum_ + +enum class EnumValueCaseTest { + PA_SC_SAL_L, + PASC_ASL_F, + START_PSAAA_DFE, + NAME_MYA_SAY_R, + NAME_MYA_SAY_R_ +} + diff --git a/diktat-huawei-rules/src/test/resources/test/paragraph1/naming/enum_/EnumValueCaseTest.kt b/diktat-huawei-rules/src/test/resources/test/paragraph1/naming/enum_/EnumValueCaseTest.kt new file mode 100644 index 0000000000..46727e4837 --- /dev/null +++ b/diktat-huawei-rules/src/test/resources/test/paragraph1/naming/enum_/EnumValueCaseTest.kt @@ -0,0 +1,10 @@ +package com.huawei.test.resources.test.paragraph1.naming.enum_ + +enum class EnumValueCaseTest { + paSC_SAl_l, + PascAsl_f, + START_PSaaa_DFE, + _NAme_MYa_sayR, + NAme_MYa_sayR_ +} + diff --git a/rules-config.json b/rules-config.json index 0d59a0b26a..484e7e13a2 100644 --- a/rules-config.json +++ b/rules-config.json @@ -114,6 +114,11 @@ "enabled": true, "configuration": "" }, + { + "name": "KDOC_WITHOUT_THROWS_TAG", + "enabled": true, + "configuration": "" + }, { "name": "KDOC_WITHOUT_THROWS_TAG", "enabled": true,