diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRule.kt index 20b547de5f..5908ebea29 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRule.kt @@ -4,6 +4,7 @@ import com.pinterest.ktlint.core.Rule import org.cqfn.diktat.common.config.rules.RulesConfig import org.cqfn.diktat.common.config.rules.isRuleEnabled import org.cqfn.diktat.ruleset.constants.EmitType +import org.cqfn.diktat.ruleset.utils.log import org.jetbrains.kotlin.com.intellij.lang.ASTNode typealias DiktatConfigRule = org.cqfn.diktat.common.config.rules.Rule @@ -21,7 +22,7 @@ abstract class DiktatRule(id: String, val configRules: List, val ru try { logic(node) } catch (e: Exception) { - // TODO: Specify message + log.error("Internal error has occurred in $id. Please make an issue on this bug at https://github.com/cqfn/diKTat/.\n Error: ${e.message}") } } } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/ImmutableValNoVarRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/ImmutableValNoVarRule.kt index d55abfcca1..26978d8d68 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/ImmutableValNoVarRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/ImmutableValNoVarRule.kt @@ -1,13 +1,12 @@ package org.cqfn.diktat.ruleset.rules.chapter4 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.SAY_NO_TO_VAR import org.cqfn.diktat.ruleset.utils.search.findAllVariablesWithAssignments import org.cqfn.diktat.ruleset.utils.search.findAllVariablesWithUsages -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.psi.KtBlockExpression import org.jetbrains.kotlin.psi.KtLambdaExpression @@ -20,16 +19,8 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfType * because `var` variables can be reassigned several times in the business logic. Of course, in some scenarios with loops or accumulators only `var`s can be used and are allowed. * FixMe: here we should also raise warnings for a reassignment of a var (if var has no assignments except in declaration - it can be final) */ -class ImmutableValNoVarRule(private val configRules: List) : Rule("no-var-rule") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class ImmutableValNoVarRule(configRules: List) : DiktatRule("no-var-rule", configRules, listOf(SAY_NO_TO_VAR)) { + override fun logic(node: ASTNode) { if (node.elementType == ElementType.FILE) { // we will raise warning for cases when var property has no assignments val varNoAssignments = node diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/NullChecksRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/NullChecksRule.kt index 79dff69830..366cff96d0 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/NullChecksRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/NullChecksRule.kt @@ -1,11 +1,10 @@ package org.cqfn.diktat.ruleset.rules.chapter4 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.AVOID_NULL_CHECKS +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.* -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType import com.pinterest.ktlint.core.ast.ElementType.BINARY_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.CONDITION @@ -27,16 +26,8 @@ import org.jetbrains.kotlin.psi.KtIfExpression * This rule check and fixes explicit null checks (explicit comparison with `null`) * There are several code-structures that can be used in Kotlin to avoid null-checks. For example: `?:`, `.let {}`, `.also {}`, e.t.c */ -class NullChecksRule(private val configRules: List) : Rule("null-checks") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class NullChecksRule(configRules: List) : DiktatRule("null-checks", configRules, listOf(AVOID_NULL_CHECKS)) { + override fun logic(node: ASTNode) { if (node.elementType == CONDITION) { node.parent(IF)?.let { // excluding complex cases with else-if statements, because they look better with explicit null-check diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/SmartCastRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/SmartCastRule.kt index 6d140c3929..45bbe16327 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/SmartCastRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/SmartCastRule.kt @@ -1,8 +1,8 @@ package org.cqfn.diktat.ruleset.rules.chapter4 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.SMART_CAST_NEEDED +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.KotlinParser import org.cqfn.diktat.ruleset.utils.findAllNodesWithSpecificType import org.cqfn.diktat.ruleset.utils.findParentNodeWithSpecificType @@ -12,7 +12,6 @@ import org.cqfn.diktat.ruleset.utils.hasChildOfType import org.cqfn.diktat.ruleset.utils.hasParent import org.cqfn.diktat.ruleset.utils.search.findAllVariablesWithUsages -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.BINARY_WITH_TYPE import com.pinterest.ktlint.core.ast.ElementType.BLOCK import com.pinterest.ktlint.core.ast.ElementType.DOT_QUALIFIED_EXPRESSION @@ -40,16 +39,8 @@ import org.jetbrains.kotlin.psi.psiUtil.parents /** * Rule that detects redundant explicit casts */ -class SmartCastRule(private val configRules: List) : Rule("smart-cast-rule") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class SmartCastRule(configRules: List) : DiktatRule("smart-cast-rule", configRules, listOf(SMART_CAST_NEEDED)) { + override fun logic(node: ASTNode) { if (node.elementType == FILE) { val usages = collectLocalPropertiesWithUsages(node) val properMap = collectReferenceList(usages) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/TypeAliasRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/TypeAliasRule.kt index c4aa2239ad..41e46615b6 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/TypeAliasRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/TypeAliasRule.kt @@ -3,11 +3,10 @@ package org.cqfn.diktat.ruleset.rules.chapter4 import org.cqfn.diktat.common.config.rules.RuleConfiguration import org.cqfn.diktat.common.config.rules.RulesConfig import org.cqfn.diktat.common.config.rules.getRuleConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.TYPE_ALIAS +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.* -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.LT import com.pinterest.ktlint.core.ast.ElementType.SUPER_TYPE_LIST import com.pinterest.ktlint.core.ast.ElementType.TYPEALIAS @@ -20,16 +19,8 @@ import org.jetbrains.kotlin.psi.psiUtil.parents * This rule checks if variable has long type reference and two or more nested generics. * Length type reference can be configured */ -class TypeAliasRule(private val configRules: List) : Rule("type-alias") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class TypeAliasRule(configRules: List) : DiktatRule("type-alias", configRules, listOf(TYPE_ALIAS)) { + override fun logic(node: ASTNode) { if (node.elementType == TYPE_REFERENCE && node .parents() .map { it.elementType } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/VariableGenericTypeDeclarationRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/VariableGenericTypeDeclarationRule.kt index 55ca6458c6..e6e7df82c7 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/VariableGenericTypeDeclarationRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/VariableGenericTypeDeclarationRule.kt @@ -1,11 +1,10 @@ package org.cqfn.diktat.ruleset.rules.chapter4 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType -import org.cqfn.diktat.ruleset.constants.Warnings +import org.cqfn.diktat.ruleset.constants.Warnings.GENERIC_VARIABLE_WRONG_DECLARATION +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.getAllChildrenWithType -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.CALL_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.DOT_QUALIFIED_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.PROPERTY @@ -22,16 +21,9 @@ import org.jetbrains.kotlin.psi.KtProperty * Recommended: val myVariable: Map = emptyMap() */ // FIXME: we now don't have access to return types, so we can perform this check only if explicit type is present, but should be able also if it's not. -class VariableGenericTypeDeclarationRule(private val configRules: List) : Rule("variable-generic-type") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class VariableGenericTypeDeclarationRule(configRules: List) : DiktatRule("variable-generic-type", configRules, + listOf(GENERIC_VARIABLE_WRONG_DECLARATION)) { + override fun logic(node: ASTNode) { when (node.elementType) { PROPERTY, VALUE_PARAMETER -> handleProperty(node) else -> { @@ -63,14 +55,14 @@ class VariableGenericTypeDeclarationRule(private val configRules: List first.text == second.text }) { - Warnings.GENERIC_VARIABLE_WRONG_DECLARATION.warnAndFix(configRules, emitWarn, isFixMode, + GENERIC_VARIABLE_WRONG_DECLARATION.warnAndFix(configRules, emitWarn, isFixMode, "type arguments are unnecessary in ${callExpr.text}", node.startOffset, node) { callExpr.removeChild(callExpr.findChildByType(TYPE_ARGUMENT_LIST)!!) } } if (leftSide == null && rightSide != null) { - Warnings.GENERIC_VARIABLE_WRONG_DECLARATION.warn(configRules, emitWarn, isFixMode, node.text, node.startOffset, node) + GENERIC_VARIABLE_WRONG_DECLARATION.warn(configRules, emitWarn, isFixMode, node.text, node.startOffset, node) } } } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/calculations/AccurateCalculationsRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/calculations/AccurateCalculationsRule.kt index 5bff177c52..cb40295a68 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/calculations/AccurateCalculationsRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter4/calculations/AccurateCalculationsRule.kt @@ -1,12 +1,11 @@ package org.cqfn.diktat.ruleset.rules.chapter4.calculations import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.FLOAT_IN_ACCURATE_CALCULATIONS +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.findLocalDeclaration import org.cqfn.diktat.ruleset.utils.getFunctionName -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.com.intellij.psi.PsiElement @@ -25,10 +24,7 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset * Exception: allows arithmetic operations only when absolute value of result is immediately used in comparison * Fixme: detect variables by type, not only floating-point literals */ -class AccurateCalculationsRule(private val configRules: List) : Rule("accurate-calculations") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - +class AccurateCalculationsRule(configRules: List) : DiktatRule("accurate-calculations", configRules, listOf(FLOAT_IN_ACCURATE_CALCULATIONS)) { private fun KtCallExpression?.isAbsOfFloat() = this ?.run { (calleeExpression as? KtNameReferenceExpression) @@ -114,12 +110,7 @@ class AccurateCalculationsRule(private val configRules: List) : Rul * @param autoCorrect * @param emit */ - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - + override fun logic(node: ASTNode) { when (val psi = node.psi) { is KtBinaryExpression -> handleBinaryExpression(psi) is KtDotQualifiedExpression -> handleFunction(psi) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/AsyncAndSyncRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/AsyncAndSyncRule.kt index 99b899dcf9..927b6fb637 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/AsyncAndSyncRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/AsyncAndSyncRule.kt @@ -1,11 +1,10 @@ package org.cqfn.diktat.ruleset.rules.chapter5 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.RUN_BLOCKING_INSIDE_ASYNC +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.hasChildOfType -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.CALL_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.FUN import com.pinterest.ktlint.core.ast.ElementType.LAMBDA_ARGUMENT @@ -18,17 +17,10 @@ import org.jetbrains.kotlin.psi.psiUtil.hasSuspendModifier /** * This rule finds if using runBlocking in asynchronous code */ -class AsyncAndSyncRule(private val configRules: List) : Rule("sync-in-async") { +class AsyncAndSyncRule(configRules: List) : DiktatRule("sync-in-async", configRules, listOf(RUN_BLOCKING_INSIDE_ASYNC)) { private val asyncList = listOf("async", "launch") - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect + override fun logic(node: ASTNode) { if (node.isRunBlocking()) { checkRunBlocking(node) } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/AvoidNestedFunctionsRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/AvoidNestedFunctionsRule.kt index 22cd128edd..e597764640 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/AvoidNestedFunctionsRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/AvoidNestedFunctionsRule.kt @@ -1,14 +1,13 @@ package org.cqfn.diktat.ruleset.rules.chapter5 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.AVOID_NESTED_FUNCTIONS +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.findAllNodesWithSpecificType import org.cqfn.diktat.ruleset.utils.getFirstChildWithType import org.cqfn.diktat.ruleset.utils.hasChildOfType import org.cqfn.diktat.ruleset.utils.hasParent -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.CLASS_BODY import com.pinterest.ktlint.core.ast.ElementType.FUN import com.pinterest.ktlint.core.ast.ElementType.IDENTIFIER @@ -25,16 +24,8 @@ import org.jetbrains.kotlin.psi.psiUtil.parents /** * This rule checks for nested functions and warns if it finds any. */ -class AvoidNestedFunctionsRule(private val configRules: List) : Rule("avoid-nested-functions") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class AvoidNestedFunctionsRule(configRules: List) : DiktatRule("avoid-nested-functions", configRules, listOf(AVOID_NESTED_FUNCTIONS)) { + override fun logic(node: ASTNode) { if (node.elementType == FUN) { handleNestedFunctions(node) } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/CheckInverseMethodRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/CheckInverseMethodRule.kt index ef009953fb..8c92f48a18 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/CheckInverseMethodRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/CheckInverseMethodRule.kt @@ -1,10 +1,9 @@ package org.cqfn.diktat.ruleset.rules.chapter5 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.INVERSE_FUNCTION_PREFERRED +import org.cqfn.diktat.ruleset.rules.DiktatRule -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.BLOCK_COMMENT import com.pinterest.ktlint.core.ast.ElementType.CALL_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.IDENTIFIER @@ -23,16 +22,8 @@ import org.jetbrains.kotlin.psi.psiUtil.siblings * This rule checks if inverse method can be used. * For example if there is !isEmpty() on collection call that it changes it to isNotEmpty() */ -class CheckInverseMethodRule(private val configRules: List) : Rule("inverse-method") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class CheckInverseMethodRule(configRules: List) : DiktatRule("inverse-method", configRules, listOf(INVERSE_FUNCTION_PREFERRED)) { + override fun logic(node: ASTNode) { if (node.elementType == CALL_EXPRESSION && node.text in methodMap.keys) { checkCallExpressionName(node) } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/CustomLabel.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/CustomLabel.kt index 175572475b..518040b1b3 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/CustomLabel.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/CustomLabel.kt @@ -1,11 +1,10 @@ package org.cqfn.diktat.ruleset.rules.chapter5 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.CUSTOM_LABEL +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.loopType -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.BREAK import com.pinterest.ktlint.core.ast.ElementType.CALL_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.CONTINUE @@ -18,19 +17,12 @@ import org.jetbrains.kotlin.psi.psiUtil.parents /** * Rule that checks using custom label */ -class CustomLabel(private val configRules: List) : Rule("custom-label") { - private var isFixMode: Boolean = false +class CustomLabel(configRules: List) : DiktatRule("custom-label", configRules, listOf(CUSTOM_LABEL)) { private val forEachReference = listOf("forEach", "forEachIndexed") private val labels = listOf("@loop", "@forEach", "@forEachIndexed") private val stopWords = listOf(RETURN, BREAK, CONTINUE) - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect + override fun logic(node: ASTNode) { if (node.elementType == LABEL_QUALIFIER && node.text !in labels && node.treeParent.elementType in stopWords) { val nestedCount = node.parents().count { it.elementType in loopType || diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/FunctionArgumentsSize.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/FunctionArgumentsSize.kt index 3d66bc5fea..5f07f8a9f2 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/FunctionArgumentsSize.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/FunctionArgumentsSize.kt @@ -3,10 +3,9 @@ package org.cqfn.diktat.ruleset.rules.chapter5 import org.cqfn.diktat.common.config.rules.RuleConfiguration import org.cqfn.diktat.common.config.rules.RulesConfig import org.cqfn.diktat.common.config.rules.getRuleConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.TOO_MANY_PARAMETERS +import org.cqfn.diktat.ruleset.rules.DiktatRule -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType import com.pinterest.ktlint.core.ast.ElementType.IDENTIFIER import org.jetbrains.kotlin.com.intellij.lang.ASTNode @@ -15,19 +14,12 @@ import org.jetbrains.kotlin.psi.KtFunction /** * Rule that checks that function doesn't contains too many parameters */ -class FunctionArgumentsSize(private val configRules: List) : Rule("argument-size") { - private var isFixMode: Boolean = false +class FunctionArgumentsSize(configRules: List) : DiktatRule("argument-size", configRules, listOf(TOO_MANY_PARAMETERS)) { private val configuration: FunctionArgumentsSizeConfiguration by lazy { FunctionArgumentsSizeConfiguration(configRules.getRuleConfig(TOO_MANY_PARAMETERS)?.configuration ?: emptyMap()) } - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect + override fun logic(node: ASTNode) { if (node.elementType == ElementType.FUN) { checkFun(node, configuration.maxParameterSize) } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/FunctionLength.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/FunctionLength.kt index 907111ad8e..670fef2377 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/FunctionLength.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/FunctionLength.kt @@ -3,11 +3,10 @@ package org.cqfn.diktat.ruleset.rules.chapter5 import org.cqfn.diktat.common.config.rules.RuleConfiguration import org.cqfn.diktat.common.config.rules.RulesConfig import org.cqfn.diktat.common.config.rules.getRuleConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.TOO_LONG_FUNCTION +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.* -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.FUN import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.psi.KtFunction @@ -15,16 +14,8 @@ import org.jetbrains.kotlin.psi.KtFunction /** * Rule 5.1.1 check function length */ -class FunctionLength(private val configRules: List) : Rule("function-length") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class FunctionLength(configRules: List) : DiktatRule("function-length", configRules, listOf(TOO_LONG_FUNCTION)) { + override fun logic(node: ASTNode) { val configuration = FunctionLengthConfiguration( configRules.getRuleConfig(TOO_LONG_FUNCTION)?.configuration ?: emptyMap() ) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/LambdaLengthRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/LambdaLengthRule.kt index 69f5d77969..f231535a74 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/LambdaLengthRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/LambdaLengthRule.kt @@ -3,34 +3,24 @@ package org.cqfn.diktat.ruleset.rules.chapter5 import org.cqfn.diktat.common.config.rules.RuleConfiguration import org.cqfn.diktat.common.config.rules.RulesConfig import org.cqfn.diktat.common.config.rules.getRuleConfig -import org.cqfn.diktat.ruleset.constants.EmitType -import org.cqfn.diktat.ruleset.constants.Warnings +import org.cqfn.diktat.ruleset.constants.Warnings.TOO_MANY_LINES_IN_LAMBDA +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.* -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType import org.jetbrains.kotlin.com.intellij.lang.ASTNode /** * Rule 5.2.5 check lambda length without parameters */ -class LambdaLengthRule(private val configRules: List) : Rule("lambda-length") { +class LambdaLengthRule(configRules: List) : DiktatRule("lambda-length", configRules, listOf(TOO_MANY_LINES_IN_LAMBDA)) { private val configuration by lazy { LambdaLengthConfiguration( - this.configRules.getRuleConfig(Warnings.TOO_MANY_LINES_IN_LAMBDA)?.configuration ?: emptyMap() + this.configRules.getRuleConfig(TOO_MANY_LINES_IN_LAMBDA)?.configuration ?: emptyMap() ) } - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit( - node: ASTNode, - autoCorrect: Boolean, - emit: EmitType - ) { - emitWarn = emit - isFixMode = autoCorrect + override fun logic(node: ASTNode) { if (node.elementType == ElementType.LAMBDA_EXPRESSION) { checkLambda(node, configuration) } @@ -48,7 +38,7 @@ class LambdaLengthRule(private val configRules: List) : Rule("lambd val isIt = copyNode.findAllNodesWithSpecificType(ElementType.REFERENCE_EXPRESSION).map { re -> re.text }.contains("it") val parameters = node.findChildByType(ElementType.FUNCTION_LITERAL)?.findChildByType(ElementType.VALUE_PARAMETER_LIST) if (parameters == null && isIt) { - Warnings.TOO_MANY_LINES_IN_LAMBDA.warn(configRules, emitWarn, isFixMode, + TOO_MANY_LINES_IN_LAMBDA.warn(configRules, emitWarn, isFixMode, "max length lambda without arguments is ${configuration.maxLambdaLength}, but you have $sizeLambda", node.startOffset, node) } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/LambdaParameterOrder.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/LambdaParameterOrder.kt index 486948f80a..28bf1a9082 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/LambdaParameterOrder.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/LambdaParameterOrder.kt @@ -1,11 +1,10 @@ package org.cqfn.diktat.ruleset.rules.chapter5 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.LAMBDA_IS_NOT_LAST_PARAMETER +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.hasChildOfType -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType import com.pinterest.ktlint.core.ast.ElementType.FUNCTION_TYPE import com.pinterest.ktlint.core.ast.ElementType.IDENTIFIER @@ -16,16 +15,8 @@ import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty /** * Rule that checks if parameter with function type is the last in parameter list */ -class LambdaParameterOrder(private val configRules: List) : Rule("lambda-parameter-order") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class LambdaParameterOrder(configRules: List) : DiktatRule("lambda-parameter-order", configRules, listOf(LAMBDA_IS_NOT_LAST_PARAMETER)) { + override fun logic(node: ASTNode) { if (node.elementType == ElementType.FUN) { checkArguments(node) } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/NestedFunctionBlock.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/NestedFunctionBlock.kt index 5fe828fb2a..dc537c668a 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/NestedFunctionBlock.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/NestedFunctionBlock.kt @@ -3,12 +3,11 @@ package org.cqfn.diktat.ruleset.rules.chapter5 import org.cqfn.diktat.common.config.rules.RuleConfiguration import org.cqfn.diktat.common.config.rules.RulesConfig import org.cqfn.diktat.common.config.rules.getRuleConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.NESTED_BLOCK +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.findAllNodesWithSpecificType import org.cqfn.diktat.ruleset.utils.hasChildOfType -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.CLASS import com.pinterest.ktlint.core.ast.ElementType.FUN import com.pinterest.ktlint.core.ast.ElementType.FUNCTION_LITERAL @@ -21,19 +20,12 @@ import org.jetbrains.kotlin.psi.psiUtil.parents /** * Rule 5.1.2 Nested blokcs */ -class NestedFunctionBlock(private val configRules: List) : Rule("nested-block") { +class NestedFunctionBlock(configRules: List) : DiktatRule("nested-block", configRules, listOf(NESTED_BLOCK)) { private val configuration: NestedBlockConfiguration by lazy { NestedBlockConfiguration(configRules.getRuleConfig(NESTED_BLOCK)?.configuration ?: emptyMap()) } - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect + override fun logic(node: ASTNode) { if (node.elementType in nullificationType) { countNestedBlocks(node, configuration.maxNestedBlockQuantity) } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/OverloadingArgumentsFunction.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/OverloadingArgumentsFunction.kt index db03967186..81bc291a87 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/OverloadingArgumentsFunction.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/OverloadingArgumentsFunction.kt @@ -1,13 +1,12 @@ package org.cqfn.diktat.ruleset.rules.chapter5 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.WRONG_OVERLOADING_FUNCTION_ARGUMENTS +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.allSiblings import org.cqfn.diktat.ruleset.utils.findChildAfter import org.cqfn.diktat.ruleset.utils.findChildBefore -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.FUN import com.pinterest.ktlint.core.ast.ElementType.IDENTIFIER import com.pinterest.ktlint.core.ast.ElementType.TYPE_REFERENCE @@ -18,16 +17,9 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset /** * Rule that suggests to use functions with default parameters instead of multiple overloads */ -class OverloadingArgumentsFunction(private val configRules: List) : Rule("overloading-default-values") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - isFixMode = autoCorrect - emitWarn = emit - +class OverloadingArgumentsFunction(configRules: List) : DiktatRule("overloading-default-values", configRules, + listOf(WRONG_OVERLOADING_FUNCTION_ARGUMENTS)) { + override fun logic(node: ASTNode) { if (node.elementType == FUN) { checkFun(node.psi as KtFunction) } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/AvoidEmptyPrimaryConstructor.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/AvoidEmptyPrimaryConstructor.kt index 7f26d48443..d90f3ae304 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/AvoidEmptyPrimaryConstructor.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/AvoidEmptyPrimaryConstructor.kt @@ -1,10 +1,9 @@ package org.cqfn.diktat.ruleset.rules.chapter6 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.EMPTY_PRIMARY_CONSTRUCTOR +import org.cqfn.diktat.ruleset.rules.DiktatRule -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.CLASS import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.psi.KtClass @@ -12,16 +11,8 @@ import org.jetbrains.kotlin.psi.KtClass /** * This rule checks if a class has an empty primary constructor. */ -class AvoidEmptyPrimaryConstructor(private val configRules: List) : Rule("avoid-empty-primary-constructor") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class AvoidEmptyPrimaryConstructor(configRules: List) : DiktatRule("avoid-empty-primary-constructor", configRules, listOf(EMPTY_PRIMARY_CONSTRUCTOR)) { + override fun logic(node: ASTNode) { if (node.elementType == CLASS) { checkClass(node.psi as KtClass) } 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 c2898168bb..79635772ae 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 @@ -2,11 +2,10 @@ package org.cqfn.diktat.ruleset.rules.chapter6 import org.cqfn.diktat.common.config.rules.RulesConfig import org.cqfn.diktat.common.config.rules.getCommonConfiguration -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.AVOID_USING_UTILITY_CLASS +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.* -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.BLOCK_COMMENT import com.pinterest.ktlint.core.ast.ElementType.CLASS import com.pinterest.ktlint.core.ast.ElementType.CLASS_BODY @@ -25,15 +24,8 @@ import org.jetbrains.kotlin.psi.psiUtil.children /** * Rule 6.4.1 checks that class/object, with a word "util" in its name, has only functions. */ -class AvoidUtilityClass(private val configRules: List) : Rule("avoid-utility-class") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect +class AvoidUtilityClass(configRules: List) : DiktatRule("avoid-utility-class", configRules, listOf(AVOID_USING_UTILITY_CLASS)) { + override fun logic(node: ASTNode) { val config by configRules.getCommonConfiguration() val filePath = node.getRootNode().getFilePath() if (!(node.hasTestAnnotation() || isLocatedInTest(filePath.splitPathToDirs(), config.testAnchors))) { diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/CustomGetterSetterRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/CustomGetterSetterRule.kt index a04266d072..9002f51737 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/CustomGetterSetterRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/CustomGetterSetterRule.kt @@ -1,11 +1,10 @@ package org.cqfn.diktat.ruleset.rules.chapter6 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType -import org.cqfn.diktat.ruleset.constants.Warnings +import org.cqfn.diktat.ruleset.constants.Warnings.CUSTOM_GETTERS_SETTERS +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.* -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.GET_KEYWORD import com.pinterest.ktlint.core.ast.ElementType.MODIFIER_LIST import com.pinterest.ktlint.core.ast.ElementType.PRIVATE_KEYWORD @@ -16,16 +15,8 @@ import org.jetbrains.kotlin.com.intellij.lang.ASTNode /** * Inspection that checks that no custom getters and setters are used for properties. */ -class CustomGetterSetterRule(private val configRules: List) : Rule("custom-getter-setter") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class CustomGetterSetterRule(configRules: List) : DiktatRule("custom-getter-setter", configRules, listOf(CUSTOM_GETTERS_SETTERS)) { + override fun logic(node: ASTNode) { if (node.elementType == PROPERTY_ACCESSOR) { checkForCustomGetersSetters(node) } @@ -39,12 +30,12 @@ class CustomGetterSetterRule(private val configRules: List) : Rule( setter?.let { // only private custom setters are allowed if (!isPrivateSetter) { - Warnings.CUSTOM_GETTERS_SETTERS.warn(configRules, emitWarn, isFixMode, setter.text, setter.startOffset, node) + CUSTOM_GETTERS_SETTERS.warn(configRules, emitWarn, isFixMode, setter.text, setter.startOffset, node) } } getter?.let { - Warnings.CUSTOM_GETTERS_SETTERS.warn(configRules, emitWarn, isFixMode, getter.text, getter.startOffset, node) + CUSTOM_GETTERS_SETTERS.warn(configRules, emitWarn, isFixMode, getter.text, getter.startOffset, node) } } } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/ExtensionFunctionsInFileRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/ExtensionFunctionsInFileRule.kt index e9a025ee13..6c0329ee5b 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/ExtensionFunctionsInFileRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/ExtensionFunctionsInFileRule.kt @@ -1,13 +1,12 @@ package org.cqfn.diktat.ruleset.rules.chapter6 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType -import org.cqfn.diktat.ruleset.constants.Warnings +import org.cqfn.diktat.ruleset.constants.Warnings.EXTENSION_FUNCTION_WITH_CLASS +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.findAllNodesWithSpecificType import org.cqfn.diktat.ruleset.utils.getAllChildrenWithType import org.cqfn.diktat.ruleset.utils.getFirstChildWithType -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType import com.pinterest.ktlint.core.ast.ElementType.CLASS import com.pinterest.ktlint.core.ast.ElementType.FUN @@ -21,16 +20,9 @@ import org.jetbrains.kotlin.psi.KtFunction /** * This rule checks if there are any extension functions for the class in the same file, where it is defined */ -class ExtensionFunctionsInFileRule(private val configRules: List) : Rule("extension-functions-class-file") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class ExtensionFunctionsInFileRule(configRules: List) : DiktatRule("extension-functions-class-file", configRules, + listOf(EXTENSION_FUNCTION_WITH_CLASS)) { + override fun logic(node: ASTNode) { if (node.elementType == ElementType.FILE) { val classNames = collectAllClassNames(node) @@ -48,7 +40,7 @@ class ExtensionFunctionsInFileRule(private val configRules: List) : } private fun fireWarning(node: ASTNode) { - Warnings.EXTENSION_FUNCTION_WITH_CLASS.warn(configRules, emitWarn, isFixMode, "fun ${(node.psi as KtFunction).name}", node.startOffset, node) + EXTENSION_FUNCTION_WITH_CLASS.warn(configRules, emitWarn, isFixMode, "fun ${(node.psi as KtFunction).name}", node.startOffset, node) } private fun collectAllExtensionFunctionsWithSameClassName(node: ASTNode, classNames: List): List = diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/ExtensionFunctionsSameNameRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/ExtensionFunctionsSameNameRule.kt index 59205894d0..e8c1270191 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/ExtensionFunctionsSameNameRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/ExtensionFunctionsSameNameRule.kt @@ -1,8 +1,8 @@ package org.cqfn.diktat.ruleset.rules.chapter6 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.EXTENSION_FUNCTION_SAME_SIGNATURE +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.findAllNodesWithSpecificType import org.cqfn.diktat.ruleset.utils.findChildAfter import org.cqfn.diktat.ruleset.utils.findChildBefore @@ -11,7 +11,6 @@ import org.cqfn.diktat.ruleset.utils.getAllChildrenWithType import org.cqfn.diktat.ruleset.utils.getFirstChildWithType import org.cqfn.diktat.ruleset.utils.hasChildOfType -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.CLASS import com.pinterest.ktlint.core.ast.ElementType.COLON import com.pinterest.ktlint.core.ast.ElementType.DOT @@ -33,15 +32,9 @@ internal typealias SimilarSignatures = List) : Rule("extension-functions-same-name") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect +class ExtensionFunctionsSameNameRule(configRules: List) : DiktatRule("extension-functions-same-name", configRules, + listOf(EXTENSION_FUNCTION_SAME_SIGNATURE)) { + override fun logic(node: ASTNode) { /** * 1) Collect all classes that extend other classes (collect related classes) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/ImplicitBackingPropertyRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/ImplicitBackingPropertyRule.kt index 06ceee31fb..cb4c967cff 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/ImplicitBackingPropertyRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/ImplicitBackingPropertyRule.kt @@ -1,14 +1,13 @@ package org.cqfn.diktat.ruleset.rules.chapter6 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.NO_CORRESPONDING_PROPERTY +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.findAllNodesWithSpecificType import org.cqfn.diktat.ruleset.utils.getFirstChildWithType import org.cqfn.diktat.ruleset.utils.hasAnyChildOfTypes import org.cqfn.diktat.ruleset.utils.hasChildOfType -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.BLOCK import com.pinterest.ktlint.core.ast.ElementType.CLASS_BODY import com.pinterest.ktlint.core.ast.ElementType.DOT_QUALIFIED_EXPRESSION @@ -25,16 +24,9 @@ import org.jetbrains.kotlin.psi.KtProperty /** * This rule checks if there is a backing property for field with property accessors, in case they don't use field keyword */ -class ImplicitBackingPropertyRule(private val configRules: List) : Rule("implicit-backing-property") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class ImplicitBackingPropertyRule(configRules: List) : DiktatRule("implicit-backing-property", configRules, + listOf(NO_CORRESPONDING_PROPERTY)) { + override fun logic(node: ASTNode) { if (node.elementType == CLASS_BODY) { findAllProperties(node) } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/PropertyAccessorFields.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/PropertyAccessorFields.kt index 23ffd8fdd3..cdd75f4376 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/PropertyAccessorFields.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/PropertyAccessorFields.kt @@ -1,12 +1,11 @@ package org.cqfn.diktat.ruleset.rules.chapter6 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.WRONG_NAME_OF_VARIABLE_INSIDE_ACCESSOR +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.findAllNodesWithSpecificType import org.cqfn.diktat.ruleset.utils.isGoingAfter -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.BLOCK import com.pinterest.ktlint.core.ast.ElementType.DOT_QUALIFIED_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.IDENTIFIER @@ -21,18 +20,8 @@ import org.jetbrains.kotlin.psi.KtProperty /** * Rule check that never use the name of a variable in the custom getter or setter */ -class PropertyAccessorFields(private val configRules: List) : Rule("getter-setter-fields") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit( - node: ASTNode, - autoCorrect: Boolean, - emit: EmitType - ) { - isFixMode = autoCorrect - emitWarn = emit - +class PropertyAccessorFields(configRules: List) : DiktatRule("getter-setter-fields", configRules, listOf(WRONG_NAME_OF_VARIABLE_INSIDE_ACCESSOR)) { + override fun logic(node: ASTNode) { if (node.elementType == PROPERTY_ACCESSOR) { checkPropertyAccessor(node) } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/TrivialPropertyAccessors.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/TrivialPropertyAccessors.kt index fec5142e9a..6f8c6f11c8 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/TrivialPropertyAccessors.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/TrivialPropertyAccessors.kt @@ -1,14 +1,13 @@ package org.cqfn.diktat.ruleset.rules.chapter6 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType -import org.cqfn.diktat.ruleset.constants.Warnings +import org.cqfn.diktat.ruleset.constants.Warnings.TRIVIAL_ACCESSORS_ARE_NOT_RECOMMENDED +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.findAllNodesWithSpecificType import org.cqfn.diktat.ruleset.utils.getFirstChildWithType import org.cqfn.diktat.ruleset.utils.getIdentifierName import org.cqfn.diktat.ruleset.utils.hasChildOfType -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.BINARY_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.BLOCK import com.pinterest.ktlint.core.ast.ElementType.BLOCK_COMMENT @@ -27,16 +26,9 @@ import org.jetbrains.kotlin.psi.KtPropertyAccessor /** * This rule checks if there are any trivial getters and setters and, if so, deletes them */ -class TrivialPropertyAccessors(private val configRules: List) : Rule("trivial-property-accessors") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class TrivialPropertyAccessors(configRules: List) : DiktatRule("trivial-property-accessors", configRules, + listOf(TRIVIAL_ACCESSORS_ARE_NOT_RECOMMENDED)) { + override fun logic(node: ASTNode) { if (node.elementType == PROPERTY_ACCESSOR) { handlePropertyAccessors(node) } @@ -85,7 +77,7 @@ class TrivialPropertyAccessors(private val configRules: List) : Rul } private fun raiseWarning(node: ASTNode) { - Warnings.TRIVIAL_ACCESSORS_ARE_NOT_RECOMMENDED.warnAndFix(configRules, emitWarn, isFixMode, node.text, node.startOffset, node) { + TRIVIAL_ACCESSORS_ARE_NOT_RECOMMENDED.warnAndFix(configRules, emitWarn, isFixMode, node.text, node.startOffset, node) { val property = (node.psi as KtPropertyAccessor).property.node if (node.treePrev.isWhiteSpace()) { property.removeChild(node.treePrev) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/UselessSupertype.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/UselessSupertype.kt index 2e57fec2ca..c740b623aa 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/UselessSupertype.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/UselessSupertype.kt @@ -1,11 +1,10 @@ package org.cqfn.diktat.ruleset.rules.chapter6 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.USELESS_SUPERTYPE +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.* -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.CALL_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.CLASS import com.pinterest.ktlint.core.ast.ElementType.CLASS_BODY @@ -32,16 +31,8 @@ import java.util.HashMap * Explicit supertype qualification should not be used if there is not clash between called methods * fixme can't fix supertypes that are defined in other files. */ -class UselessSupertype(private val configRules: List) : Rule("useless-override") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class UselessSupertype(configRules: List) : DiktatRule("useless-override", configRules, listOf(USELESS_SUPERTYPE)) { + override fun logic(node: ASTNode) { if (node.elementType == CLASS) { checkClass(node) } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/AbstractClassesRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/AbstractClassesRule.kt index 927f4757d4..4755f42b55 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/AbstractClassesRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/AbstractClassesRule.kt @@ -1,13 +1,12 @@ package org.cqfn.diktat.ruleset.rules.chapter6.classes import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.CLASS_SHOULD_NOT_BE_ABSTRACT +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.getAllChildrenWithType import org.cqfn.diktat.ruleset.utils.getFirstChildWithType import org.cqfn.diktat.ruleset.utils.hasChildOfType -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.ABSTRACT_KEYWORD import com.pinterest.ktlint.core.ast.ElementType.CLASS import com.pinterest.ktlint.core.ast.ElementType.CLASS_BODY @@ -20,16 +19,8 @@ import org.jetbrains.kotlin.com.intellij.lang.ASTNode /** * Checks if abstract class has any abstract method. If not, warns that class should not be abstract */ -class AbstractClassesRule(private val configRule: List) : Rule("abstract-classes") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class AbstractClassesRule(configRules: List) : DiktatRule("abstract-classes", configRules, listOf(CLASS_SHOULD_NOT_BE_ABSTRACT)) { + override fun logic(node: ASTNode) { if (node.elementType == CLASS) { val classBody = node.getFirstChildWithType(CLASS_BODY) ?: return @@ -49,7 +40,7 @@ class AbstractClassesRule(private val configRule: List) : Rule("abs val identifier = classNode.getFirstChildWithType(IDENTIFIER)!!.text if (functions.isNotEmpty() && functions.none { hasAbstractModifier(it) }) { - CLASS_SHOULD_NOT_BE_ABSTRACT.warnAndFix(configRule, emitWarn, isFixMode, identifier, node.startOffset, node) { + CLASS_SHOULD_NOT_BE_ABSTRACT.warnAndFix(configRules, emitWarn, isFixMode, identifier, node.startOffset, node) { val modList = classNode.getFirstChildWithType(MODIFIER_LIST)!! if (modList.getChildren(null).size > 1) { val abstractKeyword = modList.getFirstChildWithType(ABSTRACT_KEYWORD)!! diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/CompactInitialization.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/CompactInitialization.kt index 4c64fa4f95..807459f103 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/CompactInitialization.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/CompactInitialization.kt @@ -1,13 +1,12 @@ package org.cqfn.diktat.ruleset.rules.chapter6.classes import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType -import org.cqfn.diktat.ruleset.constants.Warnings +import org.cqfn.diktat.ruleset.constants.Warnings.COMPACT_OBJECT_INITIALIZATION +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.KotlinParser import org.cqfn.diktat.ruleset.utils.getFunctionName import org.cqfn.diktat.ruleset.utils.log -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.LBRACE import com.pinterest.ktlint.core.ast.ElementType.WHITE_SPACE import com.pinterest.ktlint.core.ast.isPartOfComment @@ -28,19 +27,10 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset * FixMe: When assigned variable's name is also a `this@apply`'s property, it should be changed to qualified name, * e.g `this@Foo`. But for this we need a mechanism to determine declaration scope and it's label. */ -class CompactInitialization(private val configRules: List) : Rule("class-compact-initialization") { - private var isFixMode: Boolean = false +class CompactInitialization(configRules: List) : DiktatRule("class-compact-initialization", configRules, listOf(COMPACT_OBJECT_INITIALIZATION)) { private val kotlinParser by lazy { KotlinParser() } - private lateinit var emitWarn: EmitType - - override fun visit( - node: ASTNode, - autoCorrect: Boolean, - emit: EmitType - ) { - emitWarn = emit - isFixMode = autoCorrect + override fun logic(node: ASTNode) { node .psi .let { it as? KtProperty } @@ -72,7 +62,7 @@ class CompactInitialization(private val configRules: List) : Rule(" } .toList() .forEach { (assignment, field) -> - Warnings.COMPACT_OBJECT_INITIALIZATION.warnAndFix( + COMPACT_OBJECT_INITIALIZATION.warnAndFix( configRules, emitWarn, isFixMode, field.text, assignment.startOffset, assignment.node ) { diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/DataClassesRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/DataClassesRule.kt index 884a85a02a..f89eb1239b 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/DataClassesRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/DataClassesRule.kt @@ -1,13 +1,12 @@ package org.cqfn.diktat.ruleset.rules.chapter6.classes import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.USE_DATA_CLASS +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.getAllChildrenWithType import org.cqfn.diktat.ruleset.utils.getFirstChildWithType import org.cqfn.diktat.ruleset.utils.hasChildOfType -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.ABSTRACT_KEYWORD import com.pinterest.ktlint.core.ast.ElementType.BLOCK import com.pinterest.ktlint.core.ast.ElementType.CLASS @@ -32,16 +31,8 @@ import org.jetbrains.kotlin.psi.KtPrimaryConstructor /** * This rule checks if class can be made as data class */ -class DataClassesRule(private val configRule: List) : Rule("data-classes") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class DataClassesRule(configRules: List) : DiktatRule("data-classes", configRules, listOf(USE_DATA_CLASS)) { + override fun logic(node: ASTNode) { if (node.elementType == CLASS) { handleClass(node) } @@ -59,7 +50,7 @@ class DataClassesRule(private val configRule: List) : Rule("data-cl // fixme: Need to know types of vars and props to create data class private fun raiseWarn(node: ASTNode) { - USE_DATA_CLASS.warn(configRule, emitWarn, isFixMode, "${(node.psi as KtClass).name}", node.startOffset, node) + USE_DATA_CLASS.warn(configRules, emitWarn, isFixMode, "${(node.psi as KtClass).name}", node.startOffset, node) } @Suppress("UnsafeCallOnNullableType", "FUNCTION_BOOLEAN_PREFIX", "ComplexMethod") 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 dd254abdb1..1665c8481e 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 @@ -2,12 +2,11 @@ package org.cqfn.diktat.ruleset.rules.chapter6.classes import org.cqfn.diktat.common.config.rules.RulesConfig import org.cqfn.diktat.common.config.rules.getCommonConfiguration -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.INLINE_CLASS_CAN_BE_USED +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.getFirstChildWithType import org.cqfn.diktat.ruleset.utils.hasChildOfType -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.CLASS import com.pinterest.ktlint.core.ast.ElementType.CONSTRUCTOR_CALLEE import com.pinterest.ktlint.core.ast.ElementType.FINAL_KEYWORD @@ -26,19 +25,9 @@ import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType /** * This rule checks if inline class can be used. */ -class InlineClassesRule(private val configRule: List) : Rule("inline-classes") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit( - node: ASTNode, - autoCorrect: Boolean, - emit: EmitType - ) { - emitWarn = emit - isFixMode = autoCorrect - - val configuration by configRule.getCommonConfiguration() +class InlineClassesRule(configRules: List) : DiktatRule("inline-classes", configRules, listOf(INLINE_CLASS_CAN_BE_USED)) { + override fun logic(node: ASTNode) { + val configuration by configRules.getCommonConfiguration() if (node.elementType == CLASS && configuration.kotlinVersion >= ktVersion) { handleClasses(node.psi as KtClass) } @@ -50,7 +39,7 @@ class InlineClassesRule(private val configRule: List) : Rule("inlin !isExtendingClass(classPsi.node) && classPsi.node.getFirstChildWithType(MODIFIER_LIST)?.getChildren(null)?.all { it.elementType in goodModifiers } != false) { // Fixme: since it's an experimental feature we shouldn't do fixer - INLINE_CLASS_CAN_BE_USED.warn(configRule, emitWarn, isFixMode, "class ${classPsi.name}", classPsi.node.startOffset, classPsi.node) + INLINE_CLASS_CAN_BE_USED.warn(configRules, emitWarn, isFixMode, "class ${classPsi.name}", classPsi.node.startOffset, classPsi.node) } } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/SingleConstructorRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/SingleConstructorRule.kt index 37713e15f4..802c2fde9c 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/SingleConstructorRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/SingleConstructorRule.kt @@ -1,15 +1,14 @@ package org.cqfn.diktat.ruleset.rules.chapter6.classes import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.SINGLE_CONSTRUCTOR_SHOULD_BE_PRIMARY +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.KotlinParser import org.cqfn.diktat.ruleset.utils.getAllChildrenWithType import org.cqfn.diktat.ruleset.utils.getIdentifierName import org.cqfn.diktat.ruleset.utils.hasChildOfType import org.cqfn.diktat.ruleset.utils.isGoingAfter -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.CLASS import com.pinterest.ktlint.core.ast.ElementType.CLASS_BODY import com.pinterest.ktlint.core.ast.ElementType.MODIFIER_LIST @@ -34,19 +33,10 @@ import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType * This rule ensures that if a class has a single constructor, this constructor is primary. * Secondary constructor is converted into primary, statements that are not assignments are moved into an `init` block. */ -class SingleConstructorRule(private val config: List) : Rule("single-constructor") { - private var isFixMode: Boolean = false +class SingleConstructorRule(configRules: List) : DiktatRule("single-constructor", configRules, listOf(SINGLE_CONSTRUCTOR_SHOULD_BE_PRIMARY)) { private val kotlinParser by lazy { KotlinParser() } - private lateinit var emitWarn: EmitType - - override fun visit( - node: ASTNode, - autoCorrect: Boolean, - emit: EmitType - ) { - emitWarn = emit - isFixMode = autoCorrect + override fun logic(node: ASTNode) { if (node.elementType == CLASS) { handleClassConstructors(node) } @@ -61,7 +51,7 @@ class SingleConstructorRule(private val config: List) : Rule("singl ?.singleOrNull() ?.let { secondaryCtor -> SINGLE_CONSTRUCTOR_SHOULD_BE_PRIMARY.warnAndFix( - config, emitWarn, isFixMode, "in class <${node.getIdentifierName()?.text}>", + configRules, emitWarn, isFixMode, "in class <${node.getIdentifierName()?.text}>", node.startOffset, node ) { convertConstructorToPrimary(node, secondaryCtor) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/SingleInitRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/SingleInitRule.kt index 0bb834b155..722410920f 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/SingleInitRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/SingleInitRule.kt @@ -14,6 +14,8 @@ import com.pinterest.ktlint.core.ast.ElementType.EQ import com.pinterest.ktlint.core.ast.ElementType.PROPERTY import com.pinterest.ktlint.core.ast.ElementType.WHITE_SPACE import com.pinterest.ktlint.core.ast.parent +import org.cqfn.diktat.ruleset.constants.Warnings.MULTIPLE_INIT_BLOCKS +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl @@ -26,18 +28,8 @@ import org.jetbrains.kotlin.psi.psiUtil.children /** * The rule that checks whether a class has a single `init` block or multiple. Having multiple `init` blocks is a bad practice. */ -class SingleInitRule(private val configRule: List) : Rule("multiple-init-block") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit( - node: ASTNode, - autoCorrect: Boolean, - emit: EmitType - ) { - emitWarn = emit - isFixMode = autoCorrect - +class SingleInitRule(configRules: List) : DiktatRule("multiple-init-block", configRules, listOf(MULTIPLE_INIT_BLOCKS)) { + override fun logic(node: ASTNode) { when (node.elementType) { CLASS_BODY -> handleInitBlocks(node) else -> return @@ -53,7 +45,7 @@ class SingleInitRule(private val configRule: List) : Rule("multiple .takeIf { it.size > 1 } ?.let { initBlocks -> val className = node.treeParent.getIdentifierName()?.text - Warnings.MULTIPLE_INIT_BLOCKS.warnAndFix(configRule, emitWarn, isFixMode, + MULTIPLE_INIT_BLOCKS.warnAndFix(configRules, emitWarn, isFixMode, "in class <$className> found ${initBlocks.size} `init` blocks", node.startOffset, node) { mergeInitBlocks(initBlocks) } @@ -107,7 +99,7 @@ class SingleInitRule(private val configRule: List) : Rule("multiple } .takeIf { it.isNotEmpty() } ?.let { map -> - Warnings.MULTIPLE_INIT_BLOCKS.warnAndFix(configRule, emitWarn, isFixMode, + MULTIPLE_INIT_BLOCKS.warnAndFix(configRules, emitWarn, isFixMode, "`init` block has assignments that can be moved to declarations", initBlock.startOffset, initBlock ) { map.forEach { (property, assignments) -> diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/StatelessClassesRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/StatelessClassesRule.kt index 358fa4c337..7ed2903736 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/StatelessClassesRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/StatelessClassesRule.kt @@ -1,14 +1,13 @@ package org.cqfn.diktat.ruleset.rules.chapter6.classes import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType -import org.cqfn.diktat.ruleset.constants.Warnings +import org.cqfn.diktat.ruleset.constants.Warnings.OBJECT_IS_PREFERRED +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.findAllNodesWithSpecificType import org.cqfn.diktat.ruleset.utils.getAllChildrenWithType import org.cqfn.diktat.ruleset.utils.getFirstChildWithType import org.cqfn.diktat.ruleset.utils.hasChildOfType -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.CLASS import com.pinterest.ktlint.core.ast.ElementType.CLASS_KEYWORD import com.pinterest.ktlint.core.ast.ElementType.FILE @@ -28,16 +27,8 @@ import org.jetbrains.kotlin.psi.KtClass /** * This rule checks if class is stateless and if so changes it to object. */ -class StatelessClassesRule(private val configRule: List) : Rule("stateless-class") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class StatelessClassesRule(configRules: List) : DiktatRule("stateless-class", configRules, listOf(OBJECT_IS_PREFERRED)) { + override fun logic(node: ASTNode) { // Fixme: We should find interfaces in all project and then check them if (node.elementType == FILE) { val interfacesNodes = node @@ -53,7 +44,7 @@ class StatelessClassesRule(private val configRule: List) : Rule("st @Suppress("UnsafeCallOnNullableType") private fun handleClass(node: ASTNode, interfaces: List) { if (isClassExtendsValidInterface(node, interfaces) && isStatelessClass(node)) { - Warnings.OBJECT_IS_PREFERRED.warnAndFix(configRule, emitWarn, isFixMode, + OBJECT_IS_PREFERRED.warnAndFix(configRules, emitWarn, isFixMode, "class ${(node.psi as KtClass).name!!}", node.startOffset, node) { val newObjectNode = CompositeElement(OBJECT_DECLARATION) node.treeParent.addChild(newObjectNode, node) 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 d6d58f0ebf..58ef54f4ee 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 @@ -45,6 +45,6 @@ class DiktatRuleSetProviderTest { } companion object { - private val ignoreFile = listOf("DiktatRuleSetProvider") + private val ignoreFile = listOf("DiktatRuleSetProvider", "DiktatRule") } }