Repository: cqfn/diKTat
Pull request #393 (2020-10-13 09:35:06)

Use kotlinx.serialization instead of jackson

codecov[bot]: # [Codecov](https://codecov.io/gh/cqfn/diKTat/pull/393?src=pr&el=h1) Report
> Merging [#393](https://codecov.io/gh/cqfn/diKTat/pull/393?src=pr&el=desc) into [feature/kotlin-1.4](https://codecov.io/gh/cqfn/diKTat/commit/f24fea10ef83330bd2e89a8c35aa7b36e1424980?el=desc) will **decrease** coverage by `0.01%`.
> The diff coverage is `40.00%`.

[![Impacted file tree graph](https://codecov.io/gh/cqfn/diKTat/pull/393/graphs/tree.svg?width=650&height=150&src=pr&token=P2quRDffpt)](https://codecov.io/gh/cqfn/diKTat/pull/393?src=pr&el=tree)

```diff
@@                   Coverage Diff                    @@
##             feature/kotlin-1.4     #393      +/-   ##
========================================================
- Coverage                 82.59%   82.58%   -0.02%     
  Complexity                 1303     1303              
========================================================
  Files                        65       65              
  Lines                      3166     3164       -2     
  Branches                   1016     1017       +1     
========================================================
- Hits                       2615     2613       -2     
  Misses                      169      169              
  Partials                    382      382              
```

| Flag | Coverage Δ | Complexity Δ | |
|---|---|---|---|
| #unittests | `82.58% <40.00%> (-0.02%)` | `1303.00 <0.00> (ø)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/cqfn/diKTat/pull/393?src=pr&el=tree) | Coverage Δ | Complexity Δ | |
|---|---|---|---|
| [...n/kotlin/org/cqfn/diktat/common/cli/CliArgument.kt](https://codecov.io/gh/cqfn/diKTat/pull/393/diff?src=pr&el=tree#diff-ZGlrdGF0LWNvbW1vbi9zcmMvbWFpbi9rb3RsaW4vb3JnL2NxZm4vZGlrdGF0L2NvbW1vbi9jbGkvQ2xpQXJndW1lbnQua3Q=) | `0.00% <0.00%> (ø)` | `0.00 <0.00> (ø)` | |
| [...fn/diktat/common/config/rules/RulesConfigReader.kt](https://codecov.io/gh/cqfn/diKTat/pull/393/diff?src=pr&el=tree#diff-ZGlrdGF0LWNvbW1vbi9zcmMvbWFpbi9rb3RsaW4vb3JnL2NxZm4vZGlrdGF0L2NvbW1vbi9jb25maWcvcnVsZXMvUnVsZXNDb25maWdSZWFkZXIua3Q=) | `35.71% <50.00%> (-7.15%)` | `4.00 <0.00> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/cqfn/diKTat/pull/393?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/cqfn/diKTat/pull/393?src=pr&el=footer). Last update [f24fea1...91c1b5b](https://codecov.io/gh/cqfn/diKTat/pull/393?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/detekt-config.yml b/detekt-config.yml
index 0e1f5fbd..f75c59e8 100644
--- a/detekt-config.yml
+++ b/detekt-config.yml
@@ -810,4 +810,4 @@ style:
   WildcardImport:
     active: true
     excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
-    excludeImports: ['org.cqfn.diktat.ruleset.utils.*', 'java.util.*', 'kotlinx.android.synthetic.*']
\ No newline at end of file
+    excludeImports: ['org.cqfn.diktat.ruleset.utils.*', 'java.util.*', 'kotlinx.android.synthetic.*', 'kotlinx.serialization']
\ No newline at end of file
diff --git a/diktat-analysis.yml b/diktat-analysis.yml
index 2184ee19..fb7cc637 100644
--- a/diktat-analysis.yml
+++ b/diktat-analysis.yml
@@ -271,7 +271,6 @@
 - name: STRING_TEMPLATE_CURLY_BRACES
   enabled: true
   configuration: {}
-  typeReferenceLength: '25' # max length of type reference
 # Variables with `val` modifier - are immutable (read-only). Usage of such variables instead of `var` variables increases
 # robustness and readability of code, because `var` variables can be reassigned several times in the business logic.
 # This rule prohibits usage of `var`s as local variables - the only exception is accumulators and counters
diff --git a/diktat-common/pom.xml b/diktat-common/pom.xml
index 126cd2b1..1ef63e47 100644
--- a/diktat-common/pom.xml
+++ b/diktat-common/pom.xml
@@ -18,24 +18,14 @@
             <artifactId>kotlin-stdlib-jdk8</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-core</artifactId>
+            <groupId>org.jetbrains.kotlinx</groupId>
+            <artifactId>kotlinx-serialization-json-jvm</artifactId>
+            <version>${kotlinx.serialization.version}</version>
         </dependency>
         <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-annotations</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.fasterxml.jackson.dataformat</groupId>
-            <artifactId>jackson-dataformat-yaml</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-databind</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.fasterxml.jackson.module</groupId>
-            <artifactId>jackson-module-kotlin</artifactId>
+            <groupId>com.charleskorn.kaml</groupId>
+            <artifactId>kaml</artifactId>
+            <version>0.24.0</version>
         </dependency>
         <dependency>
             <groupId>commons-cli</groupId>
@@ -88,6 +78,18 @@
                         </configuration>
                     </execution>
                 </executions>
+                <configuration>
+                    <compilerPlugins>
+                        <plugin>kotlinx-serialization</plugin>
+                    </compilerPlugins>
+                </configuration>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.jetbrains.kotlin</groupId>
+                        <artifactId>kotlin-maven-serialization</artifactId>
+                        <version>${kotlin.version}</version>
+                    </dependency>
+                </dependencies>
             </plugin>
         </plugins>
     </build>
diff --git a/diktat-common/src/main/kotlin/org/cqfn/diktat/common/cli/CliArgument.kt b/diktat-common/src/main/kotlin/org/cqfn/diktat/common/cli/CliArgument.kt
index a31c2c74..14ab36b0 100644
--- a/diktat-common/src/main/kotlin/org/cqfn/diktat/common/cli/CliArgument.kt
+++ b/diktat-common/src/main/kotlin/org/cqfn/diktat/common/cli/CliArgument.kt
@@ -1,27 +1,22 @@
 package org.cqfn.diktat.common.cli
 
-import com.fasterxml.jackson.annotation.JsonCreator
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties
-import com.fasterxml.jackson.annotation.JsonProperty
 import org.apache.commons.cli.Option
+import kotlinx.serialization.*
 
 /**
  * This class is used to serialize/deserialize json representation
  * that is used to store command line arguments
  */
-@JsonIgnoreProperties(ignoreUnknown = true)
-class CliArgument @JsonCreator internal constructor(
+@Serializable
+data class CliArgument (
         // short argument representation like -h
-        @param:JsonProperty("shortName") private val shortName: String,
-        @param:JsonProperty("helpDescr") private val helpDescr: String,
+        private val shortName: String,
+        private val helpDescr: String,
         // long argument representation like --help
-        @param:JsonProperty("longName") private val longName: String,
+        private val longName: String,
         // indicates if option should have explicit argument
-        @param:JsonProperty("hasArgs") private val hasArgs: Boolean,
-        @param:JsonProperty("isRequired") private val isRequired: Boolean) {
-    override fun toString(): String = "(shortName: " + shortName + ", helpDescr: " + helpDescr + ", longName: " +
-            longName + ", hasArgs: " + hasArgs + ", isRequired: " + isRequired + ")"
-
+        private val hasArgs: Boolean,
+        private val isRequired: Boolean) {
     /**
      * Converts parameters received from json to [Option]
      *
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 9290cd4d..f648215a 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
@@ -4,11 +4,10 @@
 
 package org.cqfn.diktat.common.config.rules
 
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties
-import com.fasterxml.jackson.databind.ObjectMapper
-import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
-import com.fasterxml.jackson.module.kotlin.KotlinModule
-import com.fasterxml.jackson.module.kotlin.readValue
+import com.charleskorn.kaml.Yaml
+import com.charleskorn.kaml.YamlConfiguration
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.decodeFromString
 import java.io.BufferedReader
 import java.io.File
 import org.cqfn.diktat.common.config.reader.JsonResourceConfigReader
@@ -30,7 +29,7 @@ interface Rule {
 /**
  * Configuration of individual [Rule]
  */
-@JsonIgnoreProperties(ignoreUnknown = true)
+@Serializable
 data class RulesConfig(
         val name: String,
         val enabled: Boolean = true,
@@ -47,6 +46,8 @@ object EmptyConfiguration : RuleConfiguration(mapOf())
  * class returns the list of configurations that we have read from a yml: diktat-analysis.yml
  */
 open class RulesConfigReader(override val classLoader: ClassLoader) : JsonResourceConfigReader<List<RulesConfig>>() {
+    private val yamlSerializer by lazy { Yaml(configuration = YamlConfiguration(strictMode = true)) }
+
     /**
      * Parse resource file into list of [RulesConfig]
      *
@@ -54,10 +55,8 @@ open class RulesConfigReader(override val classLoader: ClassLoader) : JsonResour
      * @return list of [RulesConfig]
      */
     override fun parseResource(fileStream: BufferedReader): List<RulesConfig> {
-        val mapper = ObjectMapper(YAMLFactory())
-        mapper.registerModule(KotlinModule())
         return fileStream.use { stream ->
-            mapper.readValue(stream)
+            yamlSerializer.decodeFromString(stream.readLines().joinToString(separator = "\n"))
         }
     }
 
@@ -87,7 +86,9 @@ open class RulesConfigReader(override val classLoader: ClassLoader) : JsonResour
 /**
  * @return common configuration from list of all rules configuration
  */
-fun List<RulesConfig>.getCommonConfiguration() = lazy { CommonConfiguration(getCommonConfig()?.configuration) }
+fun List<RulesConfig>.getCommonConfiguration() = lazy {
+    CommonConfiguration(getCommonConfig()?.configuration)
+}
 
 /**
  * class returns the list of common configurations that we have read from a configuration map
diff --git a/diktat-rules/pom.xml b/diktat-rules/pom.xml
index 20c27700..31e11a7f 100644
--- a/diktat-rules/pom.xml
+++ b/diktat-rules/pom.xml
@@ -128,31 +128,6 @@
                     <mainClass>org.cqfn.diktat.ruleset.generation.GenerationKt</mainClass>
                 </configuration>
             </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <testExcludes>
-                        <testExclude>test/**</testExclude>
-                    </testExcludes>
-                </configuration>
-                <executions>
-                    <execution>
-                        <id>compile</id>
-                        <phase>compile</phase>
-                        <goals>
-                            <goal>compile</goal>
-                        </goals>
-                    </execution>
-                    <execution>
-                        <id>testCompile</id>
-                        <phase>test-compile</phase>
-                        <goals>
-                            <goal>testCompile</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
         </plugins>
     </build>
 
diff --git a/pom.xml b/pom.xml
index 5a306a8d..0f697837 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,10 +44,10 @@
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <kotlin.version>1.4.10</kotlin.version>
         <kotlin.compiler.incremental>true</kotlin.compiler.incremental>
+        <kotlinx.serialization.version>1.0.0</kotlinx.serialization.version>
         <ktlint.version>0.39.0</ktlint.version>
         <junit.version>5.7.0</junit.version>
         <guava.version>29.0-jre</guava.version>
-        <jackson.version>2.11.3</jackson.version>
         <slf4j.version>1.7.30</slf4j.version>
         <commons-cli.version>1.4</commons-cli.version>
         <diktat-check.version>0.1.2</diktat-check.version>
@@ -85,7 +85,7 @@
                 <version>${kotlin.version}</version>
             </dependency>
             <dependency>
-                <!-- temporary override for jackson-kotlin and kotlinpoet -->
+                <!-- temporary override for and kotlinpoet -->
                 <groupId>org.jetbrains.kotlin</groupId>
                 <artifactId>kotlin-reflect</artifactId>
                 <version>${kotlin.version}</version>
@@ -105,31 +105,6 @@
                 <artifactId>guava</artifactId>
                 <version>${guava.version}</version>
             </dependency>
-            <dependency>
-                <groupId>com.fasterxml.jackson.core</groupId>
-                <artifactId>jackson-core</artifactId>
-                <version>${jackson.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>com.fasterxml.jackson.core</groupId>
-                <artifactId>jackson-annotations</artifactId>
-                <version>${jackson.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>com.fasterxml.jackson.dataformat</groupId>
-                <artifactId>jackson-dataformat-yaml</artifactId>
-                <version>${jackson.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>com.fasterxml.jackson.core</groupId>
-                <artifactId>jackson-databind</artifactId>
-                <version>${jackson.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>com.fasterxml.jackson.module</groupId>
-                <artifactId>jackson-module-kotlin</artifactId>
-                <version>${jackson.version}</version>
-            </dependency>
             <dependency>
                 <groupId>commons-cli</groupId>
                 <artifactId>commons-cli</artifactId>


Test patch:
diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/RulesConfigYamlTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/RulesConfigYamlTest.kt
index aecdffa6..704a7bab 100644
--- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/RulesConfigYamlTest.kt
+++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/RulesConfigYamlTest.kt
@@ -1,6 +1,7 @@
 package org.cqfn.diktat.ruleset.utils
 
-import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
+import com.charleskorn.kaml.Yaml
+import kotlinx.serialization.encodeToString
 import org.cqfn.diktat.common.config.rules.RulesConfig
 import org.cqfn.diktat.common.config.rules.RulesConfigReader
 import org.cqfn.diktat.common.config.rules.getRuleConfig
@@ -35,15 +36,14 @@ class RulesConfigYamlTest {
         allRulesFromCode.forEach { rule ->
             val foundRule = allRulesFromConfig.getRuleConfig(rule)
             val ymlCodeSnippet = RulesConfig(rule.ruleName(), true, mapOf())
-            val jacksonMapper = jacksonObjectMapper()
 
-            val ruleYaml = jacksonMapper.writeValueAsString(ymlCodeSnippet)
+            val ruleYaml = Yaml.default.encodeToString(ymlCodeSnippet)
             Assertions.assertTrue(foundRule != null) {
                 """
                    Cannot find warning ${rule.ruleName()} in $filePath.
                    You can fix it by adding the following code below to $filePath:
                    $ruleYaml
-                """
+                """.trimIndent()
             }
         }
 
diff --git a/diktat-test-framework/pom.xml b/diktat-test-framework/pom.xml
index 97978590..7840fcf3 100644
--- a/diktat-test-framework/pom.xml
+++ b/diktat-test-framework/pom.xml
@@ -22,22 +22,6 @@
             <groupId>org.jetbrains.kotlin</groupId>
             <artifactId>kotlin-stdlib-jdk8</artifactId>
         </dependency>
-        <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-core</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-annotations</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-databind</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.fasterxml.jackson.module</groupId>
-            <artifactId>jackson-module-kotlin</artifactId>
-        </dependency>
         <dependency>
             <groupId>commons-cli</groupId>
             <artifactId>commons-cli</artifactId>
@@ -88,6 +72,9 @@
                                 <source>src/main/kotlin</source>
                                 <source>src/main/resources</source>
                             </sourceDirs>
+                            <compilerPlugins>
+                                <plugin>kotlinx-serialization</plugin>
+                            </compilerPlugins>
                         </configuration>
                     </execution>
                     <execution>
@@ -104,6 +91,13 @@
                         </configuration>
                     </execution>
                 </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.jetbrains.kotlin</groupId>
+                        <artifactId>kotlin-maven-serialization</artifactId>
+                        <version>${kotlin.version}</version>
+                    </dependency>
+                </dependencies>
             </plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
diff --git a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestArgumentsReader.kt b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestArgumentsReader.kt
index c4ead682..a573b5a1 100644
--- a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestArgumentsReader.kt
+++ b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestArgumentsReader.kt
@@ -1,7 +1,7 @@
 package org.cqfn.diktat.test.framework.config
 
-import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
-import com.fasterxml.jackson.module.kotlin.readValue
+import kotlinx.serialization.decodeFromString
+import kotlinx.serialization.json.Json
 import java.io.BufferedReader
 import java.io.IOException
 import java.util.stream.Collectors
@@ -90,7 +90,7 @@ class TestArgumentsReader(
     @Throws(IOException::class)
     override fun parseResource(fileStream: BufferedReader): List<CliArgument> {
         val jsonValue = fileStream.lines().collect(Collectors.joining())
-        return jacksonObjectMapper().readValue(jsonValue)
+        return Json.decodeFromString<List<CliArgument>>(jsonValue)
     }
 
     companion object {
diff --git a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestConfig.kt b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestConfig.kt
index 4fb098ec..a01765f4 100644
--- a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestConfig.kt
+++ b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestConfig.kt
@@ -1,27 +1,26 @@
 package org.cqfn.diktat.test.framework.config
 
-import com.fasterxml.jackson.annotation.JsonCreator
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties
-import com.fasterxml.jackson.annotation.JsonProperty
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
 
 /**
  * This class is used to serialize/deserialize json representation
  * that is used to store command line arguments
  */
-@JsonIgnoreProperties(ignoreUnknown = true)
+@Serializable
 @Suppress("ForbiddenComment")
-class TestConfig @JsonCreator internal constructor(
+class TestConfig internal constructor(
         // command line execution command, use shell like "cmd", "bash" or other
-        @param:JsonProperty("executionCommand") val executionCommand: String,
+    val executionCommand: String,
         // expected result file can be a full path or a relative path to a resource
-        @param:JsonProperty("expectedResultFile") val expectedResultFile: String,
+    val expectedResultFile: String,
         // testFile can be a full path or a relative path to a resource
-        @param:JsonProperty("testFile") val testFile: String,
+    val testFile: String,
         // executionType that  controls processing of the test (like COMPARE, MIXED, CHECK_WARN, e.t.c)
-        @param:JsonProperty("executionType") val executionType: ExecutionType,
-        @param:JsonProperty("profile") val testProfile: TestProfile,
+    val executionType: ExecutionType,
+    @SerialName("profile") val testProfile: TestProfile,
         // option that controls if changes and automatic fix should be done directly in file
-        @param:JsonProperty("inPlace", defaultValue = "false") val inPlace: Boolean
+    val inPlace: Boolean = false
 ) {
     /**
      * test name - it is not included in config content, but is injected on runtime by setter
diff --git a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestConfigReader.kt b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestConfigReader.kt
index 8e5d5ed4..74deef47 100644
--- a/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestConfigReader.kt
+++ b/diktat-test-framework/src/main/kotlin/org/cqfn/diktat/test/framework/config/TestConfigReader.kt
@@ -1,6 +1,7 @@
 package org.cqfn.diktat.test.framework.config
 
-import com.fasterxml.jackson.databind.ObjectMapper
+import kotlinx.serialization.decodeFromString
+import kotlinx.serialization.json.Json
 import java.io.BufferedReader
 import java.io.IOException
 import java.util.stream.Collectors
@@ -11,7 +12,7 @@ class TestConfigReader(configFilePath: String, override val classLoader: ClassLo
 
     @Throws(IOException::class)
     override fun parseResource(fileStream: BufferedReader): TestConfig {
-        val jsonValue = fileStream.lines().collect(Collectors.joining())
-        return ObjectMapper().readValue(jsonValue, TestConfig::class.java)
+        val jsonValue: String = fileStream.lines().collect(Collectors.joining())
+        return Json.decodeFromString<TestConfig>(jsonValue)
     }
 }