Repository: analysis-dev/diktat (kotlin)

Issue:
Diktat should not be printing the same error again when the Kotlin version is not specified
> Task :diktatFix
[ERROR] 2021-02-07 23:51:16 Kotlin version not specified in the configuration file. Will be using 1.4.21 version
[ERROR] 2021-02-07 23:51:16 Kotlin version not specified in the configuration file. Will be using 1.4.21 version
[ERROR] 2021-02-07 23:51:16 Kotlin version not specified in the configuration file. Will be using 1.4.21 version
[ERROR] 2021-02-07 23:51:16 Kotlin version not specified in the configuration file. Will be using 1.4.21 version
[ERROR] 2021-02-07 23:51:16 Kotlin version not specified in the configuration file. Will be using 1.4.21 version
[ERROR] 2021-02-07 23:51:16 Kotlin version not specified in the configuration file. Will be using 1.4.21 version
[ERROR] 2021-02-07 23:51:16 Kotlin version not specified in the configuration file. Will be using 1.4.21 version
[ERROR] 2021-02-07 23:51:16 Kotlin version not specified in the configuration file. Will be using 1.4.21 version
[ERROR] 2021-02-07 23:51:16 Kotlin version not specified in the configuration file. Will be using 1.4.21 version

Pull request:
### What's done:
   Added atomic counter
   closes #751

Patch:
diff --git a/diktat-common/src/main/kotlin/org/cqfn/diktat/common/config/rules/RulesConfigReader.kt b/diktat-common/src/main/kotlin/org/cqfn/diktat/common/config/rules/RulesConfigReader.kt
index 94394510b2..771e063597 100644
--- a/diktat-common/src/main/kotlin/org/cqfn/diktat/common/config/rules/RulesConfigReader.kt
+++ b/diktat-common/src/main/kotlin/org/cqfn/diktat/common/config/rules/RulesConfigReader.kt
@@ -14,6 +14,7 @@ import org.slf4j.LoggerFactory
 
 import java.io.BufferedReader
 import java.io.File
+import java.util.concurrent.atomic.AtomicInteger
 
 import kotlinx.serialization.Serializable
 import kotlinx.serialization.decodeFromString
@@ -122,7 +123,9 @@ data class CommonConfiguration(private val configuration: Map<String, String>?)
      */
     val kotlinVersion: KotlinVersion by lazy {
         configuration?.get("kotlinVersion")?.kotlinVersion() ?: run {
-            log.error("Kotlin version not specified in the configuration file. Will be using ${KotlinVersion.CURRENT} version")
+            if (visitorCounter.incrementAndGet() == 1) {
+                log.error("Kotlin version not specified in the configuration file. Will be using ${KotlinVersion.CURRENT} version")
+            }
             KotlinVersion.CURRENT
         }
     }
@@ -131,6 +134,13 @@ data class CommonConfiguration(private val configuration: Map<String, String>?)
      * False if configuration has been read from config file, true if defaults are used
      */
     val isDefault = configuration == null
+
+    companion object {
+        /**
+         * Counter that helps not to raise multiple warnings about kotlin version
+         */
+        var visitorCounter = AtomicInteger(0)
+    }
 }
 
 // ================== utils for List<RulesConfig> from yml config
@@ -138,9 +148,7 @@ data class CommonConfiguration(private val configuration: Map<String, String>?)
 /**
  * @return common configuration from list of all rules configuration
  */
-fun List<RulesConfig>.getCommonConfiguration() = lazy {
-    CommonConfiguration(getCommonConfig()?.configuration)
-}
+fun List<RulesConfig>.getCommonConfiguration() = CommonConfiguration(getCommonConfig()?.configuration)
 
 /**
  * Get [RulesConfig] for particular [Rule] object.
diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Chapters.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Chapters.kt
index 82886b3175..0861526047 100644
--- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Chapters.kt
+++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/constants/Chapters.kt
@@ -30,7 +30,7 @@ enum class Chapters(val number: String, val title: String) {
  */
 fun Warnings.isRuleFromActiveChapter(configRules: List<RulesConfig>): Boolean {
     val chapterFromRule = getChapterByWarning()
-    val configuration by configRules.getCommonConfiguration()
+    val configuration = configRules.getCommonConfiguration()
     val disabledChapters = configuration.disabledChapters
         ?.takeIf { it.isNotBlank() }
         ?.split(",")
diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/PackageNaming.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/PackageNaming.kt
index 8756f3d898..78b0c08dc8 100644
--- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/PackageNaming.kt
+++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/PackageNaming.kt
@@ -39,7 +39,7 @@ class PackageNaming(configRules: List<RulesConfig>) : DiktatRule("package-naming
     private lateinit var domainName: String
 
     override fun logic(node: ASTNode) {
-        val configuration by configRules.getCommonConfiguration()
+        val configuration = configRules.getCommonConfiguration()
         configuration.domainName?.let {
             domainName = it
             if (node.elementType == PACKAGE_DIRECTIVE) {
diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocComments.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocComments.kt
index 8e16f44d0f..d6cd89709c 100644
--- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocComments.kt
+++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocComments.kt
@@ -53,7 +53,7 @@ class KdocComments(configRules: List<RulesConfig>) : DiktatRule("kdoc-comments",
      * @param emit
      */
     override fun logic(node: ASTNode) {
-        val config = configRules.getCommonConfiguration().value
+        val config = configRules.getCommonConfiguration()
         val filePath = node.getRootNode().getFilePath()
         if (!(node.hasTestAnnotation() || isLocatedInTest(filePath.splitPathToDirs(), config.testAnchors))) {
             when (node.elementType) {
diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocMethods.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocMethods.kt
index 2e13a98b9f..a0fd9878d3 100644
--- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocMethods.kt
+++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocMethods.kt
@@ -75,7 +75,7 @@ class KdocMethods(configRules: List<RulesConfig>) : DiktatRule("kdoc-methods", c
      */
     override fun logic(node: ASTNode) {
         if (node.elementType == FUN && node.getFirstChildWithType(MODIFIER_LIST).isAccessibleOutside() && !node.isOverridden()) {
-            val config = configRules.getCommonConfiguration().value
+            val config = configRules.getCommonConfiguration()
             val filePath = node.getRootNode().getFilePath()
             val isTestMethod = node.hasTestAnnotation() || isLocatedInTest(filePath.splitPathToDirs(), config.testAnchors)
             if (!isTestMethod && !node.isStandardMethod() && !node.isSingleLineGetterOrSetter()) {
diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/TrailingCommaRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/TrailingCommaRule.kt
index 4d2d29c23a..acf14c8ad6 100644
--- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/TrailingCommaRule.kt
+++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/TrailingCommaRule.kt
@@ -50,7 +50,7 @@ import org.jetbrains.kotlin.psi.psiUtil.siblings
  */
 @Suppress("TOO_LONG_FUNCTION")
 class TrailingCommaRule(configRules: List<RulesConfig>) : DiktatRule("trailing-comma", configRules, listOf(TRAILING_COMMA)) {
-    private val commonConfig by configRules.getCommonConfiguration()
+    private val commonConfig = configRules.getCommonConfiguration()
     private val trailingConfig = this.configRules.getRuleConfig(TRAILING_COMMA)?.configuration ?: emptyMap()
     private val configuration by lazy {
         if (trailingConfig.isEmpty()) {
diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileStructureRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileStructureRule.kt
index 6adda7c8ea..d0cbb3f466 100644
--- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileStructureRule.kt
+++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileStructureRule.kt
@@ -61,7 +61,6 @@ class FileStructureRule(configRules: List<RulesConfig>) : DiktatRule("file-struc
     private val domainName by lazy {
         configRules
             .getCommonConfiguration()
-            .value
             .domainName
     }
     private val standardImportsAsName = StandardPlatforms
diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/AvoidUtilityClass.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/AvoidUtilityClass.kt
index 79635772ae..627f55f1e2 100644
--- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/AvoidUtilityClass.kt
+++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/AvoidUtilityClass.kt
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.psi.psiUtil.children
  */
 class AvoidUtilityClass(configRules: List<RulesConfig>) : DiktatRule("avoid-utility-class", configRules, listOf(AVOID_USING_UTILITY_CLASS)) {
     override fun logic(node: ASTNode) {
-        val config by configRules.getCommonConfiguration()
+        val config = configRules.getCommonConfiguration()
         val filePath = node.getRootNode().getFilePath()
         if (!(node.hasTestAnnotation() || isLocatedInTest(filePath.splitPathToDirs(), config.testAnchors))) {
             if (node.elementType == OBJECT_DECLARATION || node.elementType == CLASS) {
diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/InlineClassesRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/InlineClassesRule.kt
index 1665c8481e..24ba0c7fbd 100644
--- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/InlineClassesRule.kt
+++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/InlineClassesRule.kt
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
  */
 class InlineClassesRule(configRules: List<RulesConfig>) : DiktatRule("inline-classes", configRules, listOf(INLINE_CLASS_CAN_BE_USED)) {
     override fun logic(node: ASTNode) {
-        val configuration by configRules.getCommonConfiguration()
+        val configuration = configRules.getCommonConfiguration()
         if (node.elementType == CLASS && configuration.kotlinVersion >= ktVersion) {
             handleClasses(node.psi as KtClass)
         }


Test patch:
diff --git a/diktat-common/src/test/kotlin/org/cqfn/diktat/test/ConfigReaderTest.kt b/diktat-common/src/test/kotlin/org/cqfn/diktat/test/ConfigReaderTest.kt
index 4c0678fe65..ca7e2829e8 100644
--- a/diktat-common/src/test/kotlin/org/cqfn/diktat/test/ConfigReaderTest.kt
+++ b/diktat-common/src/test/kotlin/org/cqfn/diktat/test/ConfigReaderTest.kt
@@ -25,7 +25,7 @@ class ConfigReaderTest {
             .readResource("src/test/resources/test-rules-config.yml")
         val kotlinVersionForTest = KotlinVersion(1, 4, 21)
         requireNotNull(rulesConfigList)
-        assert(rulesConfigList.getCommonConfiguration().value.kotlinVersion == kotlinVersionForTest)
+        assert(rulesConfigList.getCommonConfiguration().kotlinVersion == kotlinVersionForTest)
         assert(rulesConfigList.find { it.name == DIKTAT_COMMON }
             ?.configuration
             ?.get("kotlinVersion")