From 0ed802604c82cc6acad984ed7a21c3d90c4295dc Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Fri, 27 May 2022 11:40:38 +0300 Subject: [PATCH 01/12] Reused c.p.k.c.Rule.VisitorModifier.RunAfterRule ### What's done: * added a wrapper for rule with c.p.k.c.Rule.VisitorModifier.RunAfterRule is pointed to prev rule --- .../ruleset/rules/DiktatRuleSetProvider.kt | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt index 1ae2ad05ed..35e75633f6 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt @@ -1,5 +1,6 @@ package org.cqfn.diktat.ruleset.rules +import com.pinterest.ktlint.core.Rule import org.cqfn.diktat.common.config.rules.DIKTAT_COMMON import org.cqfn.diktat.common.config.rules.RulesConfig import org.cqfn.diktat.common.config.rules.RulesConfigReader @@ -81,6 +82,7 @@ import org.cqfn.diktat.ruleset.rules.chapter6.classes.StatelessClassesRule import com.pinterest.ktlint.core.RuleSet import com.pinterest.ktlint.core.RuleSetProvider +import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.org.jline.utils.Levenshtein import org.slf4j.LoggerFactory @@ -226,10 +228,12 @@ class DiktatRuleSetProvider(private var diktatConfigFile: String = DIKTAT_ANALYS .map { it.invoke(configRules) } - .toTypedArray() + val orderedRules = rules.mapIndexed { index, rule -> + OrderedRule(rule, if (index != 0) rules[index - 1] else null) + } return RuleSet( DIKTAT_RULE_SET_ID, - *rules + rules = orderedRules.toTypedArray() ) } @@ -262,7 +266,30 @@ class DiktatRuleSetProvider(private var diktatConfigFile: String = DIKTAT_ANALYS private fun resolveConfigFileFromSystemProperty(): String? = System.getProperty(DIKTAT_CONF_PROPERTY) + private class OrderedRule(private val rule: Rule, nextRule: Rule?): Rule(rule.id, adjustVisitorModifier(rule, nextRule)) { + override fun visit( + node: ASTNode, + autoCorrect: Boolean, + emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit + ) { + rule.visit(node, autoCorrect, emit) + } + } + companion object { private val log = LoggerFactory.getLogger(DiktatRuleSetProvider::class.java) + + private fun adjustVisitorModifier(rule: Rule, nextRule: Rule?): Set { + val visitorModifiers: Set = rule.visitorModifiers + require(visitorModifiers.isEmpty() || visitorModifiers.any { it is Rule.VisitorModifier.RunAfterRule }) { + "Rule ${rule.id} already contains VisitorModifier.RunAfterRule" + } + if (nextRule == null) return visitorModifiers + return visitorModifiers + Rule.VisitorModifier.RunAfterRule( + ruleId = nextRule.id, + loadOnlyWhenOtherRuleIsLoaded = false, + runOnlyWhenOtherRuleIsEnabled = false + ) + } } } From 158fc66c696ce656aa4a9e619b973d35572acd5d Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Fri, 27 May 2022 12:07:43 +0300 Subject: [PATCH 02/12] Reused c.p.k.c.Rule.VisitorModifier.RunAfterRule ### What's done: * fixed condition --- .git-hooks/commit-msg.sh | 3 ++- .../org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.git-hooks/commit-msg.sh b/.git-hooks/commit-msg.sh index f465ed4d47..91a120259f 100644 --- a/.git-hooks/commit-msg.sh +++ b/.git-hooks/commit-msg.sh @@ -2,8 +2,9 @@ commit_pattern="(Merge (remote-tracking )?branch|### What's done:)" error_msg="Your commit message doesn't match the pattern $commit_pattern. Please fix it." +commit_count="$(git rev-list --count master..HEAD 2> /dev/null)" -if [[ ! $( cat "$1" ) =~ $commit_pattern ]] +if [[ $commit_count = "0" && ! $( cat "$1" ) =~ $commit_pattern ]] then echo "$error_msg" exit 1 diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt index 35e75633f6..cfbebc06f3 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt @@ -281,7 +281,7 @@ class DiktatRuleSetProvider(private var diktatConfigFile: String = DIKTAT_ANALYS private fun adjustVisitorModifier(rule: Rule, nextRule: Rule?): Set { val visitorModifiers: Set = rule.visitorModifiers - require(visitorModifiers.isEmpty() || visitorModifiers.any { it is Rule.VisitorModifier.RunAfterRule }) { + require(visitorModifiers.none { it is Rule.VisitorModifier.RunAfterRule }) { "Rule ${rule.id} already contains VisitorModifier.RunAfterRule" } if (nextRule == null) return visitorModifiers From 5929f8245292daed6e9e152476b7c158358b3f9b Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Fri, 27 May 2022 12:09:41 +0300 Subject: [PATCH 03/12] Reused c.p.k.c.Rule.VisitorModifier.RunAfterRule ### What's done: * reused typealias --- .../org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt index cfbebc06f3..4e4bd64181 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt @@ -82,6 +82,7 @@ import org.cqfn.diktat.ruleset.rules.chapter6.classes.StatelessClassesRule import com.pinterest.ktlint.core.RuleSet import com.pinterest.ktlint.core.RuleSetProvider +import org.cqfn.diktat.ruleset.constants.EmitType import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.org.jline.utils.Levenshtein import org.slf4j.LoggerFactory @@ -270,7 +271,7 @@ class DiktatRuleSetProvider(private var diktatConfigFile: String = DIKTAT_ANALYS override fun visit( node: ASTNode, autoCorrect: Boolean, - emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit + emit: EmitType ) { rule.visit(node, autoCorrect, emit) } From f95df83d7d31f44dd93aa0351e990ed4282adae7 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Fri, 27 May 2022 12:12:18 +0300 Subject: [PATCH 04/12] Reused c.p.k.c.Rule.VisitorModifier.RunAfterRule ### What's done: * fixed import ordering --- .../org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt index 4e4bd64181..83d30cc6b8 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt @@ -1,9 +1,9 @@ package org.cqfn.diktat.ruleset.rules -import com.pinterest.ktlint.core.Rule import org.cqfn.diktat.common.config.rules.DIKTAT_COMMON import org.cqfn.diktat.common.config.rules.RulesConfig import org.cqfn.diktat.common.config.rules.RulesConfigReader +import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings import org.cqfn.diktat.ruleset.dummy.DummyWarning import org.cqfn.diktat.ruleset.rules.chapter1.FileNaming @@ -80,9 +80,9 @@ import org.cqfn.diktat.ruleset.rules.chapter6.classes.SingleConstructorRule import org.cqfn.diktat.ruleset.rules.chapter6.classes.SingleInitRule import org.cqfn.diktat.ruleset.rules.chapter6.classes.StatelessClassesRule +import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.RuleSet import com.pinterest.ktlint.core.RuleSetProvider -import org.cqfn.diktat.ruleset.constants.EmitType import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.org.jline.utils.Levenshtein import org.slf4j.LoggerFactory From 48b506bb4df5d3923a06e6170081f2f9d10c2b1f Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Fri, 27 May 2022 12:18:58 +0300 Subject: [PATCH 05/12] Reused c.p.k.c.Rule.VisitorModifier.RunAfterRule ### What's done: * fixed formatting issues --- .../ruleset/rules/DiktatRuleSetProvider.kt | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt index 83d30cc6b8..713dec7d51 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt @@ -267,7 +267,7 @@ class DiktatRuleSetProvider(private var diktatConfigFile: String = DIKTAT_ANALYS private fun resolveConfigFileFromSystemProperty(): String? = System.getProperty(DIKTAT_CONF_PROPERTY) - private class OrderedRule(private val rule: Rule, nextRule: Rule?): Rule(rule.id, adjustVisitorModifier(rule, nextRule)) { + private class OrderedRule(private val rule: Rule, nextRule: Rule?) : Rule(rule.id, adjustVisitorModifiers(rule, nextRule)) { override fun visit( node: ASTNode, autoCorrect: Boolean, @@ -280,17 +280,18 @@ class DiktatRuleSetProvider(private var diktatConfigFile: String = DIKTAT_ANALYS companion object { private val log = LoggerFactory.getLogger(DiktatRuleSetProvider::class.java) - private fun adjustVisitorModifier(rule: Rule, nextRule: Rule?): Set { + private fun adjustVisitorModifiers(rule: Rule, nextRule: Rule?): Set { val visitorModifiers: Set = rule.visitorModifiers require(visitorModifiers.none { it is Rule.VisitorModifier.RunAfterRule }) { "Rule ${rule.id} already contains VisitorModifier.RunAfterRule" } - if (nextRule == null) return visitorModifiers - return visitorModifiers + Rule.VisitorModifier.RunAfterRule( - ruleId = nextRule.id, - loadOnlyWhenOtherRuleIsLoaded = false, - runOnlyWhenOtherRuleIsEnabled = false - ) + return nextRule?.let { + visitorModifiers + Rule.VisitorModifier.RunAfterRule( + ruleId = it.id, + loadOnlyWhenOtherRuleIsLoaded = false, + runOnlyWhenOtherRuleIsEnabled = false + ) + } ?: visitorModifiers } } } From 01cfd3a55a51960957cd0b9274aab380b2a154d5 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Fri, 27 May 2022 12:38:04 +0300 Subject: [PATCH 06/12] Reused c.p.k.c.Rule.VisitorModifier.RunAfterRule ### What's done: * fixed test --- .../org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt | 5 ++++- .../org/cqfn/diktat/util/DiktatRuleSetProvider4Test.kt | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt index 713dec7d51..20f9a26a9a 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt @@ -267,7 +267,10 @@ class DiktatRuleSetProvider(private var diktatConfigFile: String = DIKTAT_ANALYS private fun resolveConfigFileFromSystemProperty(): String? = System.getProperty(DIKTAT_CONF_PROPERTY) - private class OrderedRule(private val rule: Rule, nextRule: Rule?) : Rule(rule.id, adjustVisitorModifiers(rule, nextRule)) { + internal class OrderedRule(val rule: Rule, nextRule: Rule?) : Rule(rule.id, adjustVisitorModifiers(rule, nextRule)) { + /** + * Delegating a call of this method + */ override fun visit( node: ASTNode, autoCorrect: Boolean, diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/DiktatRuleSetProvider4Test.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/DiktatRuleSetProvider4Test.kt index 5661b44b08..f41312246c 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/DiktatRuleSetProvider4Test.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/DiktatRuleSetProvider4Test.kt @@ -40,7 +40,10 @@ class DiktatRuleSetProviderTest { .filter { it.isFile } .map { it.nameWithoutExtension } .filterNot { it in ignoreFile } - val rulesName = DiktatRuleSetProvider().get().map { it::class.simpleName!! }.filter { it != "DummyWarning" } + val rulesName = DiktatRuleSetProvider().get() + .map { (it as? DiktatRuleSetProvider.OrderedRule)?.rule ?: it } + .map { it::class.simpleName!! } + .filter { it != "DummyWarning" } Assertions.assertEquals(filesName.sorted().toList(), rulesName.sorted()) } From be37f4884d044fa9e76179add6743fe39ea80d77 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Fri, 27 May 2022 12:53:39 +0300 Subject: [PATCH 07/12] Reused c.p.k.c.Rule.VisitorModifier.RunAfterRule ### What's done: * added javadocs --- .../cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt index 20f9a26a9a..c33b57be5b 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt @@ -267,7 +267,14 @@ class DiktatRuleSetProvider(private var diktatConfigFile: String = DIKTAT_ANALYS private fun resolveConfigFileFromSystemProperty(): String? = System.getProperty(DIKTAT_CONF_PROPERTY) - internal class OrderedRule(val rule: Rule, nextRule: Rule?) : Rule(rule.id, adjustVisitorModifiers(rule, nextRule)) { + + /** + * This is a wrapper around Ktlint Rule which adjusts visitorModifiers to keep order with prevRule + * + * @property rule KtLink Rule which this class wraps + * @param prevRule previous KtLink Rule, the wrapped rule is called after prevRule + */ + internal class OrderedRule(val rule: Rule, prevRule: Rule?) : Rule(rule.id, adjustVisitorModifiers(rule, prevRule)) { /** * Delegating a call of this method */ From 2ce1861970599ba305da9c73c5912196163c6a63 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Fri, 27 May 2022 13:22:56 +0300 Subject: [PATCH 08/12] Reused c.p.k.c.Rule.VisitorModifier.RunAfterRule ### What's done: * added javadocs --- .../org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt index bea0100d60..9ad46d4158 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt @@ -267,7 +267,6 @@ class DiktatRuleSetProvider(private var diktatConfigFile: String = DIKTAT_ANALYS private fun resolveConfigFileFromSystemProperty(): String? = System.getProperty(DIKTAT_CONF_PROPERTY) - /** * This is a wrapper around Ktlint Rule which adjusts visitorModifiers to keep order with prevRule * From e183597aa86904a260911732e394e3918cbf24d4 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Fri, 27 May 2022 13:28:50 +0300 Subject: [PATCH 09/12] Reused c.p.k.c.Rule.VisitorModifier.RunAfterRule ### What's done: * fixed tag in javadoc --- .../org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt index 9ad46d4158..de3e6aea38 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt @@ -271,6 +271,7 @@ class DiktatRuleSetProvider(private var diktatConfigFile: String = DIKTAT_ANALYS * This is a wrapper around Ktlint Rule which adjusts visitorModifiers to keep order with prevRule * * @property rule KtLink Rule which this class wraps + * * @param prevRule previous KtLink Rule, the wrapped rule is called after prevRule */ internal class OrderedRule(val rule: Rule, prevRule: Rule?) : Rule(rule.id, adjustVisitorModifiers(rule, prevRule)) { From ccd95695f6abdafe311e4ea306648b64808f2555 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Fri, 27 May 2022 13:59:16 +0300 Subject: [PATCH 10/12] Reused c.p.k.c.Rule.VisitorModifier.RunAfterRule ### What's done: * added test for OrderedRule --- .../diktat/util/DiktatRuleSetProvider4Test.kt | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/DiktatRuleSetProvider4Test.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/DiktatRuleSetProvider4Test.kt index f41312246c..2f18eb7cd0 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/DiktatRuleSetProvider4Test.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/DiktatRuleSetProvider4Test.kt @@ -6,12 +6,14 @@ package org.cqfn.diktat.util import org.cqfn.diktat.common.config.rules.RulesConfig import org.cqfn.diktat.common.config.rules.RulesConfigReader +import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.rules.DIKTAT_RULE_SET_ID import org.cqfn.diktat.ruleset.rules.DiktatRuleSetProvider import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.RuleSet import com.pinterest.ktlint.core.RuleSetProvider +import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test @@ -41,12 +43,70 @@ class DiktatRuleSetProviderTest { .map { it.nameWithoutExtension } .filterNot { it in ignoreFile } val rulesName = DiktatRuleSetProvider().get() + .onEachIndexed { index, rule -> + if (index != 0) { + Assertions.assertTrue( + rule.visitorModifiers.any { it is Rule.VisitorModifier.RunAfterRule }, + "Rule ${rule.id} doesn't contain Rule.VisitorModifier.RunAfterRule" + ) + } + } .map { (it as? DiktatRuleSetProvider.OrderedRule)?.rule ?: it } .map { it::class.simpleName!! } .filter { it != "DummyWarning" } Assertions.assertEquals(filesName.sorted().toList(), rulesName.sorted()) } + @Test + fun `check OrderedRule with VisitorModifier RunAfterRule`() { + val ruleWithRunAfterRule = object : Rule("invalid-rule", setOf(VisitorModifier.RunAfterRule("another-rule"))) { + override fun visit( + node: ASTNode, + autoCorrect: Boolean, + emit: EmitType + ) { + // do nothing + } + } + Assertions.assertThrows(IllegalArgumentException::class.java) { + DiktatRuleSetProvider.OrderedRule(ruleWithRunAfterRule, null) + } + } + + @Test + fun `check OrderedRule`() { + val rule1 = object : Rule("rule-first") { + override fun visit( + node: ASTNode, + autoCorrect: Boolean, + emit: EmitType + ) { + // do nothing + } + } + val rule2 = object : Rule("rule-second") { + override fun visit( + node: ASTNode, + autoCorrect: Boolean, + emit: EmitType + ) { + // do nothing + } + } + + val orderedRule1 = DiktatRuleSetProvider.OrderedRule(rule1, null) + Assertions.assertTrue(orderedRule1.visitorModifiers.none { it is Rule.VisitorModifier.RunAfterRule }, + "Found Rule.VisitorModifier.RunAfterRule for case without prevRule") + + val orderedRule2 = DiktatRuleSetProvider.OrderedRule(rule2, rule1) + val visitorModifiers2 = orderedRule2.visitorModifiers + .filterIsInstance() + Assertions.assertEquals(1, visitorModifiers2.size, + "Found invalid count of Rule.VisitorModifier.RunAfterRule for case with prevRule") + Assertions.assertEquals(rule1.id, visitorModifiers2[0].ruleId, + "Invalid ruleId in Rule.VisitorModifier.RunAfterRule") + } + companion object { private val ignoreFile = listOf("DiktatRuleSetProvider", "DiktatRule") } From 455e2cca50bd0c9a6dd7a7d9214db9289ae6002a Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Fri, 27 May 2022 14:25:14 +0300 Subject: [PATCH 11/12] Reused c.p.k.c.Rule.VisitorModifier.RunAfterRule ### What's done: * prevRule is NotNull now --- .../ruleset/rules/DiktatRuleSetProvider.kt | 22 +++++++------- .../diktat/util/DiktatRuleSetProvider4Test.kt | 29 ++++++++++++------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt index de3e6aea38..9bd00bcbd9 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt @@ -230,7 +230,7 @@ class DiktatRuleSetProvider(private var diktatConfigFile: String = DIKTAT_ANALYS it.invoke(configRules) } val orderedRules = rules.mapIndexed { index, rule -> - OrderedRule(rule, if (index != 0) rules[index - 1] else null) + if (index != 0) OrderedRule(rule, rules[index - 1]) else rule } return RuleSet( DIKTAT_RULE_SET_ID, @@ -269,12 +269,13 @@ class DiktatRuleSetProvider(private var diktatConfigFile: String = DIKTAT_ANALYS /** * This is a wrapper around Ktlint Rule which adjusts visitorModifiers to keep order with prevRule + * Added as a workaround after introducing a new logic for sorting KtLint Rules: https://github.com/pinterest/ktlint/issues/1478 * * @property rule KtLink Rule which this class wraps * * @param prevRule previous KtLink Rule, the wrapped rule is called after prevRule */ - internal class OrderedRule(val rule: Rule, prevRule: Rule?) : Rule(rule.id, adjustVisitorModifiers(rule, prevRule)) { + internal class OrderedRule(val rule: Rule, prevRule: Rule) : Rule(rule.id, adjustVisitorModifiers(rule, prevRule)) { /** * Delegating a call of this method */ @@ -290,18 +291,19 @@ class DiktatRuleSetProvider(private var diktatConfigFile: String = DIKTAT_ANALYS companion object { private val log = LoggerFactory.getLogger(DiktatRuleSetProvider::class.java) - private fun adjustVisitorModifiers(rule: Rule, nextRule: Rule?): Set { + private fun adjustVisitorModifiers(rule: Rule, prevRule: Rule): Set { val visitorModifiers: Set = rule.visitorModifiers require(visitorModifiers.none { it is Rule.VisitorModifier.RunAfterRule }) { "Rule ${rule.id} already contains VisitorModifier.RunAfterRule" } - return nextRule?.let { - visitorModifiers + Rule.VisitorModifier.RunAfterRule( - ruleId = it.id, - loadOnlyWhenOtherRuleIsLoaded = false, - runOnlyWhenOtherRuleIsEnabled = false - ) - } ?: visitorModifiers + require(rule.id != prevRule.id) { + "PrevRule has same ID as rule: ${rule.id}" + } + return visitorModifiers + Rule.VisitorModifier.RunAfterRule( + ruleId = prevRule.id, + loadOnlyWhenOtherRuleIsLoaded = false, + runOnlyWhenOtherRuleIsEnabled = false + ) } } } diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/DiktatRuleSetProvider4Test.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/DiktatRuleSetProvider4Test.kt index 2f18eb7cd0..502040826c 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/DiktatRuleSetProvider4Test.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/DiktatRuleSetProvider4Test.kt @@ -59,6 +59,19 @@ class DiktatRuleSetProviderTest { @Test fun `check OrderedRule with VisitorModifier RunAfterRule`() { + val rule = object : Rule("rule") { + override fun visit( + node: ASTNode, + autoCorrect: Boolean, + emit: EmitType + ) { + // do nothing + } + } + Assertions.assertThrows(IllegalArgumentException::class.java) { + DiktatRuleSetProvider.OrderedRule(rule, rule) + } + val ruleWithRunAfterRule = object : Rule("invalid-rule", setOf(VisitorModifier.RunAfterRule("another-rule"))) { override fun visit( node: ASTNode, @@ -69,7 +82,7 @@ class DiktatRuleSetProviderTest { } } Assertions.assertThrows(IllegalArgumentException::class.java) { - DiktatRuleSetProvider.OrderedRule(ruleWithRunAfterRule, null) + DiktatRuleSetProvider.OrderedRule(ruleWithRunAfterRule, rule) } } @@ -94,16 +107,12 @@ class DiktatRuleSetProviderTest { } } - val orderedRule1 = DiktatRuleSetProvider.OrderedRule(rule1, null) - Assertions.assertTrue(orderedRule1.visitorModifiers.none { it is Rule.VisitorModifier.RunAfterRule }, - "Found Rule.VisitorModifier.RunAfterRule for case without prevRule") - - val orderedRule2 = DiktatRuleSetProvider.OrderedRule(rule2, rule1) - val visitorModifiers2 = orderedRule2.visitorModifiers + val orderedRule = DiktatRuleSetProvider.OrderedRule(rule2, rule1) + val visitorModifiers = orderedRule.visitorModifiers .filterIsInstance() - Assertions.assertEquals(1, visitorModifiers2.size, - "Found invalid count of Rule.VisitorModifier.RunAfterRule for case with prevRule") - Assertions.assertEquals(rule1.id, visitorModifiers2[0].ruleId, + Assertions.assertEquals(1, visitorModifiers.size, + "Found invalid count of Rule.VisitorModifier.RunAfterRule") + Assertions.assertEquals(rule1.id, visitorModifiers[0].ruleId, "Invalid ruleId in Rule.VisitorModifier.RunAfterRule") } From cf4c438ceb36675d91f0b2cadca67459f4f30156 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Fri, 27 May 2022 14:37:59 +0300 Subject: [PATCH 12/12] Reused c.p.k.c.Rule.VisitorModifier.RunAfterRule ### What's done: * fixed formatting issue --- .../diktat/util/DiktatRuleSetProvider4Test.kt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/DiktatRuleSetProvider4Test.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/DiktatRuleSetProvider4Test.kt index 502040826c..1007c609ec 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/DiktatRuleSetProvider4Test.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/util/DiktatRuleSetProvider4Test.kt @@ -108,12 +108,17 @@ class DiktatRuleSetProviderTest { } val orderedRule = DiktatRuleSetProvider.OrderedRule(rule2, rule1) - val visitorModifiers = orderedRule.visitorModifiers + orderedRule.visitorModifiers .filterIsInstance() - Assertions.assertEquals(1, visitorModifiers.size, - "Found invalid count of Rule.VisitorModifier.RunAfterRule") - Assertions.assertEquals(rule1.id, visitorModifiers[0].ruleId, - "Invalid ruleId in Rule.VisitorModifier.RunAfterRule") + .also { + Assertions.assertEquals(1, it.size, + "Found invalid count of Rule.VisitorModifier.RunAfterRule") + } + .first() + .let { + Assertions.assertEquals(rule1.id, it.ruleId, + "Invalid ruleId in Rule.VisitorModifier.RunAfterRule") + } } companion object {