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 new file mode 100644 index 0000000000..20b547de5f --- /dev/null +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRule.kt @@ -0,0 +1,33 @@ +package org.cqfn.diktat.ruleset.rules + +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.jetbrains.kotlin.com.intellij.lang.ASTNode + +typealias DiktatConfigRule = org.cqfn.diktat.common.config.rules.Rule + +abstract class DiktatRule(id: String, val configRules: List, val rules: List): Rule(id) { + var isFixMode: Boolean = false + lateinit var emitWarn: EmitType + + override fun visit(node: ASTNode, autoCorrect: Boolean, emit: EmitType) { + emitWarn = emit + isFixMode = autoCorrect + + if (check()) return + else { + try { + logic(node) + } catch (e: Exception) { + // TODO: Specify message + } + } + } + + private fun check(): Boolean { + return rules.none { configRules.isRuleEnabled(it) } + } + abstract fun logic(node: ASTNode) +} \ No newline at end of file diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/FileNaming.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/FileNaming.kt index 16b71d2074..26fc069de3 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/FileNaming.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/FileNaming.kt @@ -1,16 +1,15 @@ package org.cqfn.diktat.ruleset.rules.chapter1 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.FILE_NAME_INCORRECT import org.cqfn.diktat.ruleset.constants.Warnings.FILE_NAME_MATCH_CLASS +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.getAllChildrenWithType import org.cqfn.diktat.ruleset.utils.getFilePath import org.cqfn.diktat.ruleset.utils.getFirstChildWithType import org.cqfn.diktat.ruleset.utils.isKotlinScript import org.cqfn.diktat.ruleset.utils.isPascalCase -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.CLASS import com.pinterest.ktlint.core.ast.ElementType.FILE import com.pinterest.ktlint.core.ast.ElementType.IDENTIFIER @@ -27,17 +26,10 @@ import java.io.File * Aggressive: In case file contains only one class on upper level - it should be named with the same name */ @Suppress("ForbiddenComment") -class FileNaming(private val configRules: List) : Rule("file-naming") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType +class FileNaming(configRules: List) : DiktatRule("file-naming", configRules, listOf(FILE_NAME_INCORRECT, FILE_NAME_MATCH_CLASS)) { private lateinit var filePath: String - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - + override fun logic(node: ASTNode) { if (node.elementType == FILE) { filePath = node.getFilePath() if (!filePath.isKotlinScript()) { diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt index 974d5c8ab6..d6f6de7c02 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/IdentifierNaming.kt @@ -3,7 +3,6 @@ package org.cqfn.diktat.ruleset.rules.chapter1 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.BACKTICKS_PROHIBITED import org.cqfn.diktat.ruleset.constants.Warnings.CLASS_NAME_INCORRECT import org.cqfn.diktat.ruleset.constants.Warnings.CONFUSING_IDENTIFIER_NAMING @@ -18,6 +17,7 @@ import org.cqfn.diktat.ruleset.constants.Warnings.OBJECT_NAME_INCORRECT import org.cqfn.diktat.ruleset.constants.Warnings.VARIABLE_HAS_PREFIX import org.cqfn.diktat.ruleset.constants.Warnings.VARIABLE_NAME_INCORRECT import org.cqfn.diktat.ruleset.constants.Warnings.VARIABLE_NAME_INCORRECT_FORMAT +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.Style import org.cqfn.diktat.ruleset.utils.containsOneLetterOrZero import org.cqfn.diktat.ruleset.utils.findChildAfter @@ -42,7 +42,6 @@ import org.cqfn.diktat.ruleset.utils.toLowerCamelCase import org.cqfn.diktat.ruleset.utils.toPascalCase import org.cqfn.diktat.ruleset.utils.toUpperSnakeCase -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType import com.pinterest.ktlint.core.ast.ElementType.CATCH import com.pinterest.ktlint.core.ast.ElementType.CATCH_KEYWORD @@ -80,7 +79,11 @@ import org.jetbrains.kotlin.psi.psiUtil.parents * // FixMe: because it fixes only declaration without the usages */ @Suppress("ForbiddenComment", "MISSING_KDOC_CLASS_ELEMENTS") -class IdentifierNaming(private val configRules: List) : Rule("identifier-naming") { +class IdentifierNaming(configRules: List) : DiktatRule("identifier-naming", configRules, + listOf(BACKTICKS_PROHIBITED, VARIABLE_NAME_INCORRECT, VARIABLE_NAME_INCORRECT_FORMAT, CONSTANT_UPPERCASE, + VARIABLE_HAS_PREFIX, CONFUSING_IDENTIFIER_NAMING, GENERIC_NAME, CLASS_NAME_INCORRECT, + ENUM_VALUE, EXCEPTION_SUFFIX, FUNCTION_BOOLEAN_PREFIX, FUNCTION_NAME_INCORRECT_CASE, + IDENTIFIER_LENGTH, OBJECT_NAME_INCORRECT)) { private val allMethodPrefixes by lazy { if (configuration.allowedBooleanPrefixes.isNullOrEmpty()) { booleanMethodPrefixes @@ -93,17 +96,10 @@ class IdentifierNaming(private val configRules: List) : Rule("ident this.configRules.getRuleConfig(FUNCTION_BOOLEAN_PREFIX)?.configuration ?: emptyMap() ) } - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - override fun visit( - node: ASTNode, - autoCorrect: Boolean, - emit: EmitType + override fun logic( + node: ASTNode ) { - isFixMode = autoCorrect - emitWarn = emit - // backticks are prohibited for identifier declarations everywhere except test methods that are marked with @Test annotation if (isIdentifierWithBackticks(node)) { return diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/PackageNaming.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/PackageNaming.kt index 1506e73958..8675cbb18c 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/PackageNaming.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter1/PackageNaming.kt @@ -2,16 +2,15 @@ package org.cqfn.diktat.ruleset.rules.chapter1 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.INCORRECT_PACKAGE_SEPARATOR import org.cqfn.diktat.ruleset.constants.Warnings.PACKAGE_NAME_INCORRECT_CASE import org.cqfn.diktat.ruleset.constants.Warnings.PACKAGE_NAME_INCORRECT_PATH import org.cqfn.diktat.ruleset.constants.Warnings.PACKAGE_NAME_INCORRECT_PREFIX import org.cqfn.diktat.ruleset.constants.Warnings.PACKAGE_NAME_INCORRECT_SYMBOLS import org.cqfn.diktat.ruleset.constants.Warnings.PACKAGE_NAME_MISSING +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.DOT_QUALIFIED_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.IDENTIFIER import com.pinterest.ktlint.core.ast.ElementType.PACKAGE_DIRECTIVE @@ -34,17 +33,12 @@ import java.util.concurrent.atomic.AtomicInteger * package a.b.c.D -> then class D should be placed in a/b/c/ directories */ @Suppress("ForbiddenComment", "TOO_MANY_LINES_IN_LAMBDA") -class PackageNaming(private val configRules: List) : Rule("package-naming") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType +class PackageNaming(configRules: List) : DiktatRule("package-naming", configRules, + listOf(INCORRECT_PACKAGE_SEPARATOR, PACKAGE_NAME_INCORRECT_CASE, PACKAGE_NAME_MISSING, + PACKAGE_NAME_INCORRECT_PATH, PACKAGE_NAME_INCORRECT_PREFIX, PACKAGE_NAME_INCORRECT_SYMBOLS)) { private lateinit var domainName: String - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - isFixMode = autoCorrect - emitWarn = emit - + override fun logic(node: ASTNode) { val configuration by configRules.getCommonConfiguration() configuration.domainName?.let { domainName = it diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/comments/CommentsRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/comments/CommentsRule.kt index d3413646c0..38d860bcbd 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/comments/CommentsRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/comments/CommentsRule.kt @@ -1,12 +1,11 @@ package org.cqfn.diktat.ruleset.rules.chapter2.comments import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.ListOfPairs import org.cqfn.diktat.ruleset.constants.Warnings.COMMENTED_OUT_CODE +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.findAllNodesWithSpecificType -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.BLOCK_COMMENT import com.pinterest.ktlint.core.ast.ElementType.EOL_COMMENT import com.pinterest.ktlint.core.ast.ElementType.FILE @@ -24,18 +23,10 @@ import org.jetbrains.kotlin.resolve.ImportPath * No commented out code is allowed, including imports. */ @Suppress("ForbiddenComment") -class CommentsRule(private val configRules: List) : Rule("comments") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType +class CommentsRule(configRules: List) : DiktatRule("comments", configRules, listOf(COMMENTED_OUT_CODE)) { private lateinit var ktPsiFactory: KtPsiFactory - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType - ) { - emitWarn = emit - isFixMode = autoCorrect - + override fun logic(node: ASTNode) { ktPsiFactory = KtPsiFactory(node.psi.project, false) // regarding markGenerated see KDoc in Kotlin sources if (node.elementType == FILE) { checkCommentedCode(node) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/comments/HeaderCommentRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/comments/HeaderCommentRule.kt index 0ee9564756..cd52612518 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/comments/HeaderCommentRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/comments/HeaderCommentRule.kt @@ -3,12 +3,12 @@ package org.cqfn.diktat.ruleset.rules.chapter2.comments 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.HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE import org.cqfn.diktat.ruleset.constants.Warnings.HEADER_MISSING_OR_WRONG_COPYRIGHT import org.cqfn.diktat.ruleset.constants.Warnings.HEADER_NOT_BEFORE_PACKAGE import org.cqfn.diktat.ruleset.constants.Warnings.HEADER_WRONG_FORMAT import org.cqfn.diktat.ruleset.constants.Warnings.WRONG_COPYRIGHT_YEAR +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.copyrightWords import org.cqfn.diktat.ruleset.utils.findChildAfter import org.cqfn.diktat.ruleset.utils.findChildBefore @@ -17,7 +17,6 @@ import org.cqfn.diktat.ruleset.utils.getFirstChildWithType import org.cqfn.diktat.ruleset.utils.log import org.cqfn.diktat.ruleset.utils.moveChildBefore -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType import com.pinterest.ktlint.core.ast.ElementType.BLOCK_COMMENT import com.pinterest.ktlint.core.ast.ElementType.FILE @@ -40,16 +39,10 @@ import java.time.LocalDate * 4) Ensure files with many or zero classes have proper description */ @Suppress("ForbiddenComment") -class HeaderCommentRule(private val configRules: List) : Rule("header-comment") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - isFixMode = autoCorrect - emitWarn = emit - +class HeaderCommentRule(configRules: List) : DiktatRule("header-comment", configRules, + listOf(HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE, HEADER_MISSING_OR_WRONG_COPYRIGHT, HEADER_NOT_BEFORE_PACKAGE, + HEADER_NOT_BEFORE_PACKAGE, HEADER_WRONG_FORMAT, WRONG_COPYRIGHT_YEAR)) { + override fun logic(node: ASTNode) { if (node.elementType == FILE) { checkCopyright(node) if (checkHeaderKdocPosition(node)) { diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/CommentsFormatting.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/CommentsFormatting.kt index 1bad4117e3..e43938ea1f 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/CommentsFormatting.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/CommentsFormatting.kt @@ -3,14 +3,13 @@ package org.cqfn.diktat.ruleset.rules.chapter2.kdoc 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.COMMENT_WHITE_SPACE import org.cqfn.diktat.ruleset.constants.Warnings.FIRST_COMMENT_NO_SPACES import org.cqfn.diktat.ruleset.constants.Warnings.IF_ELSE_COMMENTS import org.cqfn.diktat.ruleset.constants.Warnings.WRONG_NEWLINES_AROUND_KDOC +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 import com.pinterest.ktlint.core.ast.ElementType.BLOCK_COMMENT import com.pinterest.ktlint.core.ast.ElementType.CLASS @@ -50,21 +49,15 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl * * Leave one single space between the comment on the right side of the code and the code. * * Comments in if else should be inside code blocks. Exception: General if comment */ -class CommentsFormatting(private val configRules: List) : Rule("kdoc-comments-codeblocks-formatting") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - +class CommentsFormatting(configRules: List) : DiktatRule("kdoc-comments-codeblocks-formatting", configRules, + listOf(COMMENT_WHITE_SPACE, FIRST_COMMENT_NO_SPACES, + IF_ELSE_COMMENTS, WRONG_NEWLINES_AROUND_KDOC)) { /** * @param node * @param autoCorrect * @param emit */ - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - isFixMode = autoCorrect - emitWarn = emit - + override fun logic(node: ASTNode) { val configuration = CommentsFormattingConfiguration( configRules.getRuleConfig(COMMENT_WHITE_SPACE)?.configuration ?: emptyMap()) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocComments.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocComments.kt index 017ae3022c..d4c4e8171f 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocComments.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocComments.kt @@ -2,16 +2,15 @@ package org.cqfn.diktat.ruleset.rules.chapter2.kdoc 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 import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_EXTRA_PROPERTY import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_NO_CONSTRUCTOR_PROPERTY import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT import org.cqfn.diktat.ruleset.constants.Warnings.MISSING_KDOC_CLASS_ELEMENTS import org.cqfn.diktat.ruleset.constants.Warnings.MISSING_KDOC_TOP_LEVEL +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 @@ -45,23 +44,15 @@ import org.jetbrains.kotlin.psi.psiUtil.parents * 2) All internal elements in class like class, property or function should be documented with KDoc * 3) All properties declared in the primary constructor are documented using `@property` tag in class KDoc */ -class KdocComments(private val configRules: List) : Rule("kdoc-comments") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - +class KdocComments(configRules: List) : DiktatRule("kdoc-comments", configRules, + listOf(KDOC_EXTRA_PROPERTY, KDOC_NO_CONSTRUCTOR_PROPERTY, + KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT, MISSING_KDOC_CLASS_ELEMENTS, MISSING_KDOC_TOP_LEVEL)) { /** * @param node * @param autoCorrect * @param emit */ - override fun visit( - node: ASTNode, - autoCorrect: Boolean, - emit: EmitType - ) { - emitWarn = emit - isFixMode = autoCorrect - + override fun logic(node: ASTNode) { val config = configRules.getCommonConfiguration().value 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/chapter2/kdoc/KdocFormatting.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocFormatting.kt index c51d35729e..6c8028b461 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocFormatting.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocFormatting.kt @@ -3,7 +3,6 @@ package org.cqfn.diktat.ruleset.rules.chapter2.kdoc 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.KDOC_CONTAINS_DATE_OR_AUTHOR import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_EMPTY_KDOC import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_NEWLINES_BEFORE_BASIC_TAGS @@ -13,6 +12,7 @@ import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_NO_NEWLINES_BETWEEN_BASIC import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_NO_NEWLINE_AFTER_SPECIAL_TAGS import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_WRONG_SPACES_AFTER_TAG import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_WRONG_TAGS_ORDER +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 @@ -23,7 +23,6 @@ import org.cqfn.diktat.ruleset.utils.hasChildMatching import org.cqfn.diktat.ruleset.utils.kDocTags import org.cqfn.diktat.ruleset.utils.leaveOnlyOneNewLine -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType import com.pinterest.ktlint.core.ast.ElementType.KDOC import com.pinterest.ktlint.core.ast.ElementType.KDOC_LEADING_ASTERISK @@ -60,24 +59,20 @@ import java.time.temporal.ChronoField * 7) ensuring @since tag contains only versions and not dates */ @Suppress("ForbiddenComment") -class KdocFormatting(private val configRules: List) : Rule("kdoc-formatting") { +class KdocFormatting(configRules: List) : DiktatRule("kdoc-formatting", configRules, + listOf(KDOC_CONTAINS_DATE_OR_AUTHOR, KDOC_EMPTY_KDOC, KDOC_NEWLINES_BEFORE_BASIC_TAGS, KDOC_NO_DEPRECATED_TAG, + KDOC_NO_EMPTY_TAGS, KDOC_NO_NEWLINES_BETWEEN_BASIC_TAGS, KDOC_NO_NEWLINE_AFTER_SPECIAL_TAGS, + KDOC_WRONG_SPACES_AFTER_TAG, KDOC_WRONG_TAGS_ORDER)) { private val basicTagsList = listOf(KDocKnownTag.PARAM, KDocKnownTag.RETURN, KDocKnownTag.THROWS) private val specialTagNames = setOf("implSpec", "implNote", "apiNote") - private var isFixMode: Boolean = false private var versionRegex: Regex? = null - private lateinit var emitWarn: EmitType /** * @param node * @param autoCorrect * @param emit */ - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - isFixMode = autoCorrect - emitWarn = emit - + override fun logic(node: ASTNode) { versionRegex ?: run { versionRegex = KdocFormatConfiguration( configRules.getRuleConfig(KDOC_CONTAINS_DATE_OR_AUTHOR)?.configuration ?: emptyMap() diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocMethods.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocMethods.kt index 5ba0bed00c..9be7199034 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocMethods.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter2/kdoc/KdocMethods.kt @@ -2,12 +2,12 @@ package org.cqfn.diktat.ruleset.rules.chapter2.kdoc 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.KDOC_TRIVIAL_KDOC_ON_FUNCTION import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_WITHOUT_PARAM_TAG import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_WITHOUT_RETURN_TAG import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_WITHOUT_THROWS_TAG import org.cqfn.diktat.ruleset.constants.Warnings.MISSING_KDOC_ON_FUNCTION +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.KotlinParser import org.cqfn.diktat.ruleset.utils.appendNewlineMergingWhiteSpace import org.cqfn.diktat.ruleset.utils.findAllNodesWithSpecificType @@ -30,7 +30,6 @@ import org.cqfn.diktat.ruleset.utils.kDocTags import org.cqfn.diktat.ruleset.utils.parameterNames import org.cqfn.diktat.ruleset.utils.splitPathToDirs -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.CALLABLE_REFERENCE_EXPRESSION @@ -66,21 +65,15 @@ import org.jetbrains.kotlin.psi.psiUtil.referenceExpression * Currently only `throw` keyword from this methods body is supported for `@throws` check. */ @Suppress("ForbiddenComment") -class KdocMethods(private val configRules: List) : Rule("kdoc-methods") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - +class KdocMethods(configRules: List) : DiktatRule("kdoc-methods", configRules, + listOf(KDOC_TRIVIAL_KDOC_ON_FUNCTION, KDOC_WITHOUT_PARAM_TAG, KDOC_WITHOUT_RETURN_TAG, + KDOC_WITHOUT_THROWS_TAG, MISSING_KDOC_ON_FUNCTION)) { /** * @param node * @param autoCorrect * @param emit */ - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - isFixMode = autoCorrect - emitWarn = emit - + override fun logic(node: ASTNode) { if (node.elementType == FUN && node.getFirstChildWithType(MODIFIER_LIST).isAccessibleOutside() && !node.isOverridden()) { val config = configRules.getCommonConfiguration().value val filePath = node.getRootNode().getFilePath() diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/AnnotationNewLineRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/AnnotationNewLineRule.kt index 2d1e43229b..dbd1f16b1a 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/AnnotationNewLineRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/AnnotationNewLineRule.kt @@ -1,11 +1,10 @@ package org.cqfn.diktat.ruleset.rules.chapter3 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.ANNOTATION_NEW_LINE +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.ANNOTATION_ENTRY import com.pinterest.ktlint.core.ast.ElementType.CLASS import com.pinterest.ktlint.core.ast.ElementType.FUN @@ -20,16 +19,8 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl /** * This rule makes each annotation applied to a class, method or constructor is on its own line. Except: if first annotation of constructor, class or method */ -class AnnotationNewLineRule(private val configRules: List) : Rule("annotation-new-line") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class AnnotationNewLineRule(configRules: List) : DiktatRule("annotation-new-line", configRules, listOf(ANNOTATION_NEW_LINE)) { + override fun logic(node: ASTNode) { when (node.elementType) { CLASS, FUN, PRIMARY_CONSTRUCTOR, SECONDARY_CONSTRUCTOR -> checkAnnotation(node) else -> return @@ -56,7 +47,7 @@ class AnnotationNewLineRule(private val configRules: List) : Rule(" private fun deleteSpaces(node: ASTNode, rightSide: Boolean) { - Warnings.ANNOTATION_NEW_LINE.warnAndFix(configRules, emitWarn, isFixMode, "${node.text} not on a single line", + ANNOTATION_NEW_LINE.warnAndFix(configRules, emitWarn, isFixMode, "${node.text} not on a single line", node.startOffset, node) { if (rightSide) { if (node.treeNext?.isWhiteSpace() == true) { diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/BlockStructureBraces.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/BlockStructureBraces.kt index 055d0b1cfb..fd1b254786 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/BlockStructureBraces.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/BlockStructureBraces.kt @@ -3,11 +3,10 @@ package org.cqfn.diktat.ruleset.rules.chapter3 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.BRACES_BLOCK_STRUCTURE_ERROR +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 import com.pinterest.ktlint.core.ast.ElementType.BODY import com.pinterest.ktlint.core.ast.ElementType.CATCH @@ -50,16 +49,8 @@ import org.jetbrains.kotlin.psi.KtTryExpression * - opening brace of lambda * - braces around `else`/`catch`/`finally`/`while` (in `do-while` loop) */ -class BlockStructureBraces(private val configRules: List) : Rule("block-structure") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class BlockStructureBraces(configRules: List) : DiktatRule("block-structure", configRules, listOf(BRACES_BLOCK_STRUCTURE_ERROR)) { + override fun logic(node: ASTNode) { val configuration = BlockStructureBracesConfiguration( configRules.getRuleConfig(BRACES_BLOCK_STRUCTURE_ERROR)?.configuration ?: emptyMap() ) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/BracesInConditionalsAndLoopsRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/BracesInConditionalsAndLoopsRule.kt index bde41f027d..d03b9a7dab 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/BracesInConditionalsAndLoopsRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/BracesInConditionalsAndLoopsRule.kt @@ -1,13 +1,12 @@ package org.cqfn.diktat.ruleset.rules.chapter3 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.NO_BRACES_IN_CONDITIONALS_AND_LOOPS +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.findChildrenMatching import org.cqfn.diktat.ruleset.utils.isSingleLineIfElse import org.cqfn.diktat.ruleset.utils.loopType -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType import com.pinterest.ktlint.core.ast.ElementType.BLOCK import com.pinterest.ktlint.core.ast.ElementType.DO_KEYWORD @@ -35,16 +34,8 @@ import org.jetbrains.kotlin.psi.psiUtil.astReplace /** * Rule that checks that all conditionals and loops have braces. */ -class BracesInConditionalsAndLoopsRule(private val configRules: List) : Rule("braces-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 BracesInConditionalsAndLoopsRule(configRules: List) : DiktatRule("braces-rule", configRules, listOf(NO_BRACES_IN_CONDITIONALS_AND_LOOPS)) { + override fun logic(node: ASTNode) { when (node.elementType) { IF -> checkIfNode(node) WHEN -> checkWhenBranches(node) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/ClassLikeStructuresOrderRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/ClassLikeStructuresOrderRule.kt index a0e260122b..8bdc56d16b 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/ClassLikeStructuresOrderRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/ClassLikeStructuresOrderRule.kt @@ -1,12 +1,11 @@ package org.cqfn.diktat.ruleset.rules.chapter3 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.BLANK_LINE_BETWEEN_PROPERTIES import org.cqfn.diktat.ruleset.constants.Warnings.WRONG_ORDER_IN_CLASS_LIKE_STRUCTURES +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 @@ -42,16 +41,9 @@ import org.jetbrains.kotlin.psi.psiUtil.siblings /** * Rule that checks order of declarations inside classes, interfaces and objects. */ -class ClassLikeStructuresOrderRule(private val configRules: List) : Rule("class-like-structures") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class ClassLikeStructuresOrderRule(configRules: List) : DiktatRule("class-like-structures", configRules, + listOf(BLANK_LINE_BETWEEN_PROPERTIES, WRONG_ORDER_IN_CLASS_LIKE_STRUCTURES)) { + override fun logic(node: ASTNode) { if (node.elementType == CLASS_BODY) { checkDeclarationsOrderInClass(node) } else if (node.elementType == PROPERTY) { diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/ConsecutiveSpacesRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/ConsecutiveSpacesRule.kt index 43020086b9..caac371b96 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/ConsecutiveSpacesRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/ConsecutiveSpacesRule.kt @@ -3,10 +3,9 @@ package org.cqfn.diktat.ruleset.rules.chapter3 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_CONSECUTIVE_SPACES +import org.cqfn.diktat.ruleset.rules.DiktatRule -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.ENUM_ENTRY import com.pinterest.ktlint.core.ast.ElementType.EOL_COMMENT import com.pinterest.ktlint.core.ast.ElementType.WHITE_SPACE @@ -21,16 +20,8 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafElement * 2) If saveInitialFormattingForEnums is true then white spaces in enums will not be affected * */ -class ConsecutiveSpacesRule(private val configRules: List) : Rule("too-many-spaces") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class ConsecutiveSpacesRule(configRules: List) : DiktatRule("too-many-spaces", configRules, listOf(TOO_MANY_CONSECUTIVE_SPACES)) { + override fun logic(node: ASTNode) { val configuration = TooManySpacesRuleConfiguration( configRules.getRuleConfig(TOO_MANY_CONSECUTIVE_SPACES)?.configuration ?: emptyMap()) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/EmptyBlock.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/EmptyBlock.kt index 1b8ccfe088..b02baf662d 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/EmptyBlock.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/EmptyBlock.kt @@ -3,8 +3,8 @@ package org.cqfn.diktat.ruleset.rules.chapter3 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.EMPTY_BLOCK_STRUCTURE_ERROR +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.findLBrace import org.cqfn.diktat.ruleset.utils.findLeafWithSpecificType import org.cqfn.diktat.ruleset.utils.findParentNodeWithSpecificType @@ -13,7 +13,6 @@ import org.cqfn.diktat.ruleset.utils.isBlockEmpty import org.cqfn.diktat.ruleset.utils.isOverridden import org.cqfn.diktat.ruleset.utils.isPascalCase -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.CALL_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.FUNCTION_LITERAL import com.pinterest.ktlint.core.ast.ElementType.IDENTIFIER @@ -26,15 +25,8 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl /** * Rule that checks if empty code blocks (`{ }`) are used and checks their formatting. */ -class EmptyBlock(private val configRules: List) : Rule("empty-block-structure") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect +class EmptyBlock(configRules: List) : DiktatRule("empty-block-structure", configRules, listOf(EMPTY_BLOCK_STRUCTURE_ERROR)) { + override fun logic(node: ASTNode) { val configuration = EmptyBlockStyleConfiguration( configRules.getRuleConfig(EMPTY_BLOCK_STRUCTURE_ERROR)?.configuration ?: emptyMap() diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/EnumsSeparated.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/EnumsSeparated.kt index f3572561ca..cbe6e1c8e9 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/EnumsSeparated.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/EnumsSeparated.kt @@ -1,15 +1,14 @@ package org.cqfn.diktat.ruleset.rules.chapter3 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.ENUMS_SEPARATED +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.allSiblings import org.cqfn.diktat.ruleset.utils.appendNewlineMergingWhiteSpace import org.cqfn.diktat.ruleset.utils.getAllChildrenWithType import org.cqfn.diktat.ruleset.utils.hasChildOfType import org.cqfn.diktat.ruleset.utils.isClassEnum -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.COMMA @@ -27,16 +26,8 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl /** * Rule that checks enum classes formatting */ -class EnumsSeparated(private val configRules: List) : Rule("enum-separated") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class EnumsSeparated(configRules: List) : DiktatRule("enum-separated", configRules, listOf(ENUMS_SEPARATED)) { + override fun logic(node: ASTNode) { if (node.elementType == CLASS && node.hasChildOfType(CLASS_BODY)) { if (node.isClassEnum()) { checkEnumEntry(node) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/LineLength.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/LineLength.kt index 608abb0106..92612f05be 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/LineLength.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/LineLength.kt @@ -3,14 +3,13 @@ package org.cqfn.diktat.ruleset.rules.chapter3 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.LONG_LINE +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.KotlinParser import org.cqfn.diktat.ruleset.utils.appendNewlineMergingWhiteSpace import org.cqfn.diktat.ruleset.utils.calculateLineColByOffset 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.BOOLEAN_CONSTANT @@ -58,17 +57,10 @@ import java.net.URL * Rule can fix long binary expressions in condition inside `if` and in property declarations and one line functions */ @Suppress("ForbiddenComment") -class LineLength(private val configRules: List) : Rule("line-length") { - private var isFixMode: Boolean = false +class LineLength(configRules: List) : DiktatRule("line-length", configRules, listOf(LONG_LINE)) { private lateinit var positionByOffset: (Int) -> Pair - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect + override fun logic(node: ASTNode) { val configuration = LineLengthConfiguration( configRules.getRuleConfig(LONG_LINE)?.configuration ?: emptyMap()) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/LongNumericalValuesSeparatedRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/LongNumericalValuesSeparatedRule.kt index 9a4435361f..93da60e617 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/LongNumericalValuesSeparatedRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/LongNumericalValuesSeparatedRule.kt @@ -3,10 +3,9 @@ package org.cqfn.diktat.ruleset.rules.chapter3 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.LONG_NUMERICAL_VALUES_SEPARATED +import org.cqfn.diktat.ruleset.rules.DiktatRule -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.FLOAT_LITERAL import com.pinterest.ktlint.core.ast.ElementType.INTEGER_LITERAL import org.jetbrains.kotlin.com.intellij.lang.ASTNode @@ -17,22 +16,14 @@ import java.lang.StringBuilder /** * Rule that checks if numerical separators (`_`) are used for long numerical literals */ -class LongNumericalValuesSeparatedRule(private val configRules: List) : Rule("long-numerical-values") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class LongNumericalValuesSeparatedRule(configRules: List) : DiktatRule("long-numerical-values", configRules, listOf(LONG_NUMERICAL_VALUES_SEPARATED)) { + override fun logic(node: ASTNode) { val configuration = LongNumericalValuesConfiguration( - configRules.getRuleConfig(Warnings.LONG_NUMERICAL_VALUES_SEPARATED)?.configuration ?: emptyMap()) + configRules.getRuleConfig(LONG_NUMERICAL_VALUES_SEPARATED)?.configuration ?: emptyMap()) if (node.elementType == INTEGER_LITERAL) { if (!isValidConstant(node.text, configuration, node)) { - Warnings.LONG_NUMERICAL_VALUES_SEPARATED.warnAndFix(configRules, emitWarn, isFixMode, node.text, node.startOffset, node) { + LONG_NUMERICAL_VALUES_SEPARATED.warnAndFix(configRules, emitWarn, isFixMode, node.text, node.startOffset, node) { fixIntegerConstant(node, configuration.maxBlockLength) } } @@ -42,7 +33,7 @@ class LongNumericalValuesSeparatedRule(private val configRules: List configuration.maxBlockLength) { - Warnings.LONG_NUMERICAL_VALUES_SEPARATED.warn(configRules, emitWarn, false, "this block is too long $it", node.startOffset, node) + LONG_NUMERICAL_VALUES_SEPARATED.warn(configRules, emitWarn, false, "this block is too long $it", node.startOffset, node) } } } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/MultipleModifiersSequence.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/MultipleModifiersSequence.kt index b4c9d2b676..113c2b9077 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/MultipleModifiersSequence.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/MultipleModifiersSequence.kt @@ -1,10 +1,9 @@ package org.cqfn.diktat.ruleset.rules.chapter3 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.WRONG_MULTIPLE_MODIFIERS_ORDER +import org.cqfn.diktat.ruleset.rules.DiktatRule -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.ANNOTATION_ENTRY import com.pinterest.ktlint.core.ast.ElementType.MODIFIER_LIST import com.pinterest.ktlint.core.ast.ElementType.WHITE_SPACE @@ -16,16 +15,8 @@ import org.jetbrains.kotlin.psi.psiUtil.children /** * @property configRules */ -class MultipleModifiersSequence(private val configRules: List) : Rule("multiple-modifiers") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class MultipleModifiersSequence(configRules: List) : DiktatRule("multiple-modifiers", configRules, listOf(WRONG_MULTIPLE_MODIFIERS_ORDER)) { + override fun logic(node: ASTNode) { if (node.elementType == MODIFIER_LIST) { checkModifierList(node) checkAnnotation(node) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/NullableTypeRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/NullableTypeRule.kt index 813781ae0a..8215f3b5a5 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/NullableTypeRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/NullableTypeRule.kt @@ -1,13 +1,12 @@ package org.cqfn.diktat.ruleset.rules.chapter3 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.NULLABLE_PROPERTY_TYPE +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.hasChildOfType -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.BOOLEAN_CONSTANT import com.pinterest.ktlint.core.ast.ElementType.CALL_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.CHARACTER_CONSTANT @@ -38,16 +37,8 @@ import org.jetbrains.kotlin.com.intellij.psi.tree.IElementType /** * Rule that checks if nullable types are used and suggest to substitute them with non-nullable */ -class NullableTypeRule(private val configRules: List) : Rule("nullable-type") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - isFixMode = autoCorrect - emitWarn = emit - +class NullableTypeRule(configRules: List) : DiktatRule("nullable-type", configRules, listOf(NULLABLE_PROPERTY_TYPE)) { + override fun logic(node: ASTNode) { if (node.elementType == PROPERTY) { checkProperty(node) } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/SingleLineStatementsRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/SingleLineStatementsRule.kt index 48e0b7c178..bf6be2c0df 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/SingleLineStatementsRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/SingleLineStatementsRule.kt @@ -1,17 +1,16 @@ package org.cqfn.diktat.ruleset.rules.chapter3 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.MORE_THAN_ONE_STATEMENT_PER_LINE import org.cqfn.diktat.ruleset.utils.appendNewlineMergingWhiteSpace import org.cqfn.diktat.ruleset.utils.extractLineOfText import org.cqfn.diktat.ruleset.utils.isBeginByNewline import org.cqfn.diktat.ruleset.utils.isFollowedByNewline -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.ENUM_ENTRY import com.pinterest.ktlint.core.ast.ElementType.SEMICOLON import com.pinterest.ktlint.core.ast.parent +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.PsiWhiteSpaceImpl import org.jetbrains.kotlin.com.intellij.psi.tree.TokenSet @@ -19,16 +18,8 @@ import org.jetbrains.kotlin.com.intellij.psi.tree.TokenSet /** * Rule that looks for multiple statements on a single line separated with a `;` and splits them in multiple lines. */ -class SingleLineStatementsRule(private val configRules: List) : Rule("statement") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class SingleLineStatementsRule(configRules: List) : DiktatRule("statement", configRules, listOf(MORE_THAN_ONE_STATEMENT_PER_LINE)) { + override fun logic(node: ASTNode) { checkSemicolon(node) } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/SortRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/SortRule.kt index d2cd57178d..8f9179558f 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/SortRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/SortRule.kt @@ -3,12 +3,11 @@ package org.cqfn.diktat.ruleset.rules.chapter3 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.WRONG_DECLARATIONS_ORDER +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.hasChildOfType import org.cqfn.diktat.ruleset.utils.isClassEnum -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType import com.pinterest.ktlint.core.ast.ElementType.CLASS_BODY import com.pinterest.ktlint.core.ast.ElementType.COMMA @@ -27,16 +26,8 @@ import org.jetbrains.kotlin.psi.KtObjectDeclaration /** * Rule that sorts class properties and enum members alphabetically */ -class SortRule(private val configRules: List) : Rule("sort-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 SortRule(configRules: List) : DiktatRule("sort-rule", configRules, listOf(WRONG_DECLARATIONS_ORDER)) { + override fun logic(node: ASTNode) { val configuration = SortRuleConfiguration( configRules.getRuleConfig(WRONG_DECLARATIONS_ORDER)?.configuration ?: emptyMap() ) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/StringConcatenationRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/StringConcatenationRule.kt index e3b4918316..cdd52d046d 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/StringConcatenationRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/StringConcatenationRule.kt @@ -1,13 +1,12 @@ package org.cqfn.diktat.ruleset.rules.chapter3 import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.STRING_CONCATENATION +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.findAllNodesWithSpecificType import org.cqfn.diktat.ruleset.utils.findParentNodeWithSpecificType import org.cqfn.diktat.ruleset.utils.getFirstChildWithType -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.BINARY_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.OPERATION_REFERENCE import com.pinterest.ktlint.core.ast.ElementType.PLUS @@ -20,16 +19,8 @@ import org.jetbrains.kotlin.com.intellij.lang.ASTNode * // FixMe: fixes will be added * // FixMe: .toString() method and functions that return strings are not supported */ -class StringConcatenationRule(private val configRules: List) : Rule("string-concatenation") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class StringConcatenationRule(configRules: List) : DiktatRule("string-concatenation", configRules, listOf(STRING_CONCATENATION)) { + override fun logic(node: ASTNode) { if (node.elementType == BINARY_EXPRESSION) { // searching top-level binary expression to detect any operations with "plus" (+) // string concatenation is prohibited only for single line statements diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/StringTemplateFormatRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/StringTemplateFormatRule.kt index f12edd04ab..002a017349 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/StringTemplateFormatRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/StringTemplateFormatRule.kt @@ -2,11 +2,12 @@ package org.cqfn.diktat.ruleset.rules.chapter3 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.STRING_TEMPLATE_CURLY_BRACES +import org.cqfn.diktat.ruleset.constants.Warnings.STRING_TEMPLATE_QUOTES +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.findAllNodesWithSpecificType import org.cqfn.diktat.ruleset.utils.hasAnyChildOfTypes -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.ARRAY_ACCESS_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.CLOSING_QUOTE import com.pinterest.ktlint.core.ast.ElementType.FLOAT_CONSTANT @@ -27,16 +28,9 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement * * FixMe: The important caveat here: in "$foo" kotlin compiler adds implicit call to foo.toString() in case foo type is not string. */ -class StringTemplateFormatRule(private val configRules: List) : Rule("string-template-format") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class StringTemplateFormatRule(configRules: List) : DiktatRule("string-template-format", configRules, + listOf(STRING_TEMPLATE_CURLY_BRACES, STRING_TEMPLATE_QUOTES)) { + override fun logic(node: ASTNode) { when (node.elementType) { LONG_STRING_TEMPLATE_ENTRY -> handleLongStringTemplate(node) SHORT_STRING_TEMPLATE_ENTRY -> handleShortStringTemplate(node) @@ -49,7 +43,7 @@ class StringTemplateFormatRule(private val configRules: List) : Rul private fun handleLongStringTemplate(node: ASTNode) { // Checking if in long templates {a.foo()} there are function calls or class toString call if (bracesCanBeOmitted(node)) { - Warnings.STRING_TEMPLATE_CURLY_BRACES.warnAndFix(configRules, emitWarn, isFixMode, node.text, node.startOffset, node) { + STRING_TEMPLATE_CURLY_BRACES.warnAndFix(configRules, emitWarn, isFixMode, node.text, node.startOffset, node) { val identifierName = node.findChildByType(REFERENCE_EXPRESSION) identifierName?.let { val shortTemplate = CompositeElement(SHORT_STRING_TEMPLATE_ENTRY) @@ -76,7 +70,7 @@ class StringTemplateFormatRule(private val configRules: List) : Rul val identifierName = node.findChildByType(REFERENCE_EXPRESSION)?.text if (identifierName != null && node.treeParent.text.trim('"', '$') == identifierName) { - Warnings.STRING_TEMPLATE_QUOTES.warnAndFix(configRules, emitWarn, isFixMode, node.text, node.startOffset, node) { + STRING_TEMPLATE_QUOTES.warnAndFix(configRules, emitWarn, isFixMode, node.text, node.startOffset, node) { val identifier = node.findChildByType(REFERENCE_EXPRESSION)!!.copyElement() // node.treeParent is String template that we need to delete node.treeParent.treeParent.addChild(identifier, node.treeParent) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/WhenMustHaveElseRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/WhenMustHaveElseRule.kt index 31e600f083..f40c874d7f 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/WhenMustHaveElseRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/WhenMustHaveElseRule.kt @@ -1,13 +1,12 @@ package org.cqfn.diktat.ruleset.rules.chapter3 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.WHEN_WITHOUT_ELSE +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.appendNewlineMergingWhiteSpace import org.cqfn.diktat.ruleset.utils.hasParent import org.cqfn.diktat.ruleset.utils.isBeginByNewline -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType import com.pinterest.ktlint.core.ast.ElementType.ARROW import com.pinterest.ktlint.core.ast.ElementType.BLOCK @@ -37,16 +36,8 @@ import org.jetbrains.kotlin.psi.KtWhenExpression * The compiler can issue a warning when it is missing. */ @Suppress("ForbiddenComment") -class WhenMustHaveElseRule(private val configRules: List) : Rule("no-else-in-when") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class WhenMustHaveElseRule(configRules: List) : DiktatRule("no-else-in-when", configRules, listOf(WHEN_WITHOUT_ELSE)) { + override fun logic(node: ASTNode) { if (node.elementType == ElementType.WHEN && isStatement(node)) { checkEntries(node) } @@ -54,7 +45,7 @@ class WhenMustHaveElseRule(private val configRules: List) : Rule("n private fun checkEntries(node: ASTNode) { if (!hasElse(node)) { - Warnings.WHEN_WITHOUT_ELSE.warnAndFix(configRules, emitWarn, isFixMode, "else was not found", node.startOffset, node) { + WHEN_WITHOUT_ELSE.warnAndFix(configRules, emitWarn, isFixMode, "else was not found", node.startOffset, node) { val whenEntryElse = CompositeElement(WHEN_ENTRY) if (!node.lastChildNode.isBeginByNewline()) { node.appendNewlineMergingWhiteSpace(node.lastChildNode.treePrev, node.lastChildNode) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/BlankLinesRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/BlankLinesRule.kt index d602e7c8bb..2cd8be0c2e 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/BlankLinesRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/BlankLinesRule.kt @@ -1,20 +1,17 @@ package org.cqfn.diktat.ruleset.rules.chapter3.files import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.TOO_MANY_BLANK_LINES -import org.cqfn.diktat.ruleset.utils.findAllNodesWithSpecificType +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.getFirstChildWithType import org.cqfn.diktat.ruleset.utils.leaveExactlyNumNewLines import org.cqfn.diktat.ruleset.utils.leaveOnlyOneNewLine import org.cqfn.diktat.ruleset.utils.numNewLines -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.FILE import com.pinterest.ktlint.core.ast.ElementType.FUNCTION_LITERAL -import com.pinterest.ktlint.core.ast.ElementType.LAMBDA_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.LBRACE import com.pinterest.ktlint.core.ast.ElementType.RBRACE import com.pinterest.ktlint.core.ast.ElementType.SCRIPT @@ -26,16 +23,8 @@ import org.jetbrains.kotlin.com.intellij.lang.ASTNode * 1. Checks that no more than two consecutive blank lines are used in a row * 2. Checks that blank lines are not put in the beginning or at the end of code blocks with curly braces */ -class BlankLinesRule(private val configRules: List) : Rule("blank-lines") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class BlankLinesRule(configRules: List) : DiktatRule("blank-lines", configRules, listOf(TOO_MANY_BLANK_LINES)) { + override fun logic(node: ASTNode) { if (node.elementType == WHITE_SPACE) { // note that no blank lines counts as one newline if (node.numNewLines() == 2) { diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileSize.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileSize.kt index 2aacf55407..e9d8086b2b 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileSize.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileSize.kt @@ -3,12 +3,11 @@ package org.cqfn.diktat.ruleset.rules.chapter3.files 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.FILE_IS_TOO_LONG +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.getFilePath import org.cqfn.diktat.ruleset.utils.splitPathToDirs -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.slf4j.LoggerFactory @@ -16,20 +15,14 @@ import org.slf4j.LoggerFactory /** * Rule that checks number of lines in a file */ -class FileSize(private val configRules: List) : Rule("file-size") { - private var isFixMode: Boolean = false +class FileSize(configRules: List) : DiktatRule("file-size", configRules, listOf(FILE_IS_TOO_LONG)) { private val configuration by lazy { FileSizeConfiguration( this.configRules.getRuleConfig(FILE_IS_TOO_LONG)?.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.FILE) { val filePathParts = node.getFilePath().splitPathToDirs() if (SRC_PATH !in filePathParts) { diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileStructureRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileStructureRule.kt index af0d204bb2..ba5254a62e 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileStructureRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileStructureRule.kt @@ -4,7 +4,6 @@ import org.cqfn.diktat.common.config.rules.RuleConfiguration import org.cqfn.diktat.common.config.rules.RulesConfig import org.cqfn.diktat.common.config.rules.getCommonConfiguration import org.cqfn.diktat.common.config.rules.getRuleConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.FILE_CONTAINS_ONLY_COMMENTS import org.cqfn.diktat.ruleset.constants.Warnings.FILE_INCORRECT_BLOCKS_ORDER import org.cqfn.diktat.ruleset.constants.Warnings.FILE_NO_BLANK_LINE_BETWEEN_BLOCKS @@ -12,6 +11,7 @@ import org.cqfn.diktat.ruleset.constants.Warnings.FILE_UNORDERED_IMPORTS import org.cqfn.diktat.ruleset.constants.Warnings.FILE_WILDCARD_IMPORTS import org.cqfn.diktat.ruleset.constants.Warnings.UNUSED_IMPORT import org.cqfn.diktat.ruleset.rules.chapter1.PackageNaming.Companion.PACKAGE_SEPARATOR +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.StandardPlatforms import org.cqfn.diktat.ruleset.utils.copyrightWords import org.cqfn.diktat.ruleset.utils.findAllNodesWithSpecificType @@ -19,7 +19,6 @@ import org.cqfn.diktat.ruleset.utils.handleIncorrectOrder import org.cqfn.diktat.ruleset.utils.moveChildBefore import org.cqfn.diktat.ruleset.utils.operatorMap -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.BLOCK_COMMENT import com.pinterest.ktlint.core.ast.ElementType.EOL_COMMENT import com.pinterest.ktlint.core.ast.ElementType.FILE @@ -56,8 +55,9 @@ import org.jetbrains.kotlin.psi.psiUtil.siblings * 4. Ensures imports are ordered alphabetically without blank lines * 5. Ensures there are no wildcard imports */ -class FileStructureRule(private val configRules: List) : Rule("file-structure") { - private var isFixMode: Boolean = false +class FileStructureRule(configRules: List) : DiktatRule("file-structure", configRules, + listOf(FILE_CONTAINS_ONLY_COMMENTS, FILE_INCORRECT_BLOCKS_ORDER, FILE_NO_BLANK_LINE_BETWEEN_BLOCKS, + FILE_UNORDERED_IMPORTS, FILE_WILDCARD_IMPORTS, UNUSED_IMPORT)) { private val domainName by lazy { configRules .getCommonConfiguration() @@ -73,14 +73,8 @@ class FileStructureRule(private val configRules: List) : Rule("file } private val refSet: MutableSet = mutableSetOf() private var packageName = "" - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - isFixMode = autoCorrect - emitWarn = emit + override fun logic(node: ASTNode) { if (node.elementType == FILE) { val wildcardImportsConfig = WildCardImportsConfig( this.configRules.getRuleConfig(FILE_WILDCARD_IMPORTS)?.configuration ?: emptyMap() diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/IndentationRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/IndentationRule.kt index 1af2aa40ec..79a3aac6cc 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/IndentationRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/IndentationRule.kt @@ -6,8 +6,8 @@ package org.cqfn.diktat.ruleset.rules.chapter3.files 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.WRONG_INDENTATION +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.getAllChildrenWithType import org.cqfn.diktat.ruleset.utils.getAllLeafsWithSpecificType import org.cqfn.diktat.ruleset.utils.getFilePath @@ -26,7 +26,6 @@ import org.cqfn.diktat.ruleset.utils.indentation.ValueParameterListChecker import org.cqfn.diktat.ruleset.utils.leaveOnlyOneNewLine import org.cqfn.diktat.ruleset.utils.log -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.ELSE @@ -65,21 +64,14 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult * Additionally, a set of CustomIndentationChecker objects checks all WHITE_SPACE node if they are exceptions from general rules. * @see CustomIndentationChecker */ -class IndentationRule(private val configRules: List) : Rule("indentation") { - private var isFixMode: Boolean = false +class IndentationRule(configRules: List) : DiktatRule("indentation", configRules, listOf(WRONG_INDENTATION)) { private val configuration: IndentationConfig by lazy { IndentationConfig(configRules.getRuleConfig(WRONG_INDENTATION)?.configuration ?: emptyMap()) } private lateinit var filePath: String - private lateinit var emitWarn: EmitType private lateinit var customIndentationCheckers: List - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - isFixMode = autoCorrect - emitWarn = emit - + override fun logic(node: ASTNode) { if (node.elementType == FILE) { filePath = node.getFilePath() diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/NewlinesRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/NewlinesRule.kt index 60d9d0a211..d75eedfcaa 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/NewlinesRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/NewlinesRule.kt @@ -3,14 +3,13 @@ package org.cqfn.diktat.ruleset.rules.chapter3.files 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.ListOfList import org.cqfn.diktat.ruleset.constants.Warnings.COMPLEX_EXPRESSION import org.cqfn.diktat.ruleset.constants.Warnings.REDUNDANT_SEMICOLON import org.cqfn.diktat.ruleset.constants.Warnings.WRONG_NEWLINES +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.ANDAND import com.pinterest.ktlint.core.ast.ElementType.ARROW import com.pinterest.ktlint.core.ast.ElementType.BINARY_EXPRESSION @@ -96,19 +95,11 @@ import org.jetbrains.kotlin.psi.psiUtil.siblings * 10. Complex expression inside condition replaced with new variable */ @Suppress("ForbiddenComment") -class NewlinesRule(private val configRules: List) : Rule("newlines") { +class NewlinesRule(configRules: List) : DiktatRule("newlines", configRules, listOf(COMPLEX_EXPRESSION, REDUNDANT_SEMICOLON, WRONG_NEWLINES)) { private val configuration by lazy { NewlinesRuleConfiguration(configRules.getRuleConfig(WRONG_NEWLINES)?.configuration ?: emptyMap()) } - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - isFixMode = autoCorrect - emitWarn = emit - + override fun logic(node: ASTNode) { when (node.elementType) { SEMICOLON -> handleSemicolon(node) OPERATION_REFERENCE, EQ -> handleOperatorWithLineBreakAfter(node) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/WhiteSpaceRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/WhiteSpaceRule.kt index 7a56d93ec2..b05694f620 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/WhiteSpaceRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/WhiteSpaceRule.kt @@ -1,12 +1,11 @@ package org.cqfn.diktat.ruleset.rules.chapter3.files import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.WRONG_WHITESPACE +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.hasChildOfType import org.cqfn.diktat.ruleset.utils.log -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.ANNOTATION_ENTRY import com.pinterest.ktlint.core.ast.ElementType.ARROW import com.pinterest.ktlint.core.ast.ElementType.BINARY_EXPRESSION @@ -93,16 +92,9 @@ import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf * 10. There should be no spaces between prefix/postfix operator (like `!!` or `++`) and it's operand */ @Suppress("ForbiddenComment") -class WhiteSpaceRule(private val configRules: List) : Rule("horizontal-whitespace") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType +class WhiteSpaceRule(configRules: List) : DiktatRule("horizontal-whitespace", configRules, listOf(WRONG_WHITESPACE)) { @Suppress("ComplexMethod") - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - + override fun logic(node: ASTNode) { when (node.elementType) { // keywords CONSTRUCTOR_KEYWORD -> handleConstructor(node) diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/identifiers/LocalVariablesRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/identifiers/LocalVariablesRule.kt index 9d34d51248..6f5c2880c9 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/identifiers/LocalVariablesRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/identifiers/LocalVariablesRule.kt @@ -1,8 +1,8 @@ package org.cqfn.diktat.ruleset.rules.chapter3.identifiers import org.cqfn.diktat.common.config.rules.RulesConfig -import org.cqfn.diktat.ruleset.constants.EmitType import org.cqfn.diktat.ruleset.constants.Warnings.LOCAL_VARIABLE_EARLY_DECLARATION +import org.cqfn.diktat.ruleset.rules.DiktatRule import org.cqfn.diktat.ruleset.utils.containsOnlyConstants import org.cqfn.diktat.ruleset.utils.getDeclarationScope import org.cqfn.diktat.ruleset.utils.getLineNumber @@ -10,7 +10,6 @@ import org.cqfn.diktat.ruleset.utils.lastLineNumber import org.cqfn.diktat.ruleset.utils.numNewLines import org.cqfn.diktat.ruleset.utils.search.findAllVariablesWithUsages -import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.FILE import com.pinterest.ktlint.core.ast.ElementType.WHITE_SPACE import com.pinterest.ktlint.core.ast.isPartOfComment @@ -38,16 +37,8 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset * * Only properties without initialization or initialized with expressions based on constants are supported. * * Properties initialized with constructor calls cannot be distinguished from method call and are no supported. */ -class LocalVariablesRule(private val configRules: List) : Rule("local-variables") { - private var isFixMode: Boolean = false - private lateinit var emitWarn: EmitType - - override fun visit(node: ASTNode, - autoCorrect: Boolean, - emit: EmitType) { - emitWarn = emit - isFixMode = autoCorrect - +class LocalVariablesRule(configRules: List) : DiktatRule("local-variables", configRules, listOf(LOCAL_VARIABLE_EARLY_DECLARATION)) { + override fun logic(node: ASTNode) { if (node.elementType == FILE) { // collect all local properties and associate with corresponding references val propertiesToUsages = collectLocalPropertiesWithUsages(node)