From 8fa1ece6a3c61565a5b58e5effca82b187d82071 Mon Sep 17 00:00:00 2001 From: Denis Kumar Date: Tue, 11 May 2021 17:41:56 +0300 Subject: [PATCH 1/4] Value Parameter in Magic Number Rule (#874) * Value Parameter in Magi Number Rule ### What's done: Added new flag to handle value parameter Added this flag to config files Added tests --- diktat-analysis.yml | 2 + .../ruleset/rules/chapter3/MagicNumberRule.kt | 7 +++- .../cqfn/diktat/ruleset/utils/AstNodeUtils.kt | 1 + .../main/resources/diktat-analysis-huawei.yml | 2 + .../chapter3/MagicNumberRuleWarnTest.kt | 39 +++++++++++++++++++ examples/maven/diktat-analysis.yml | 2 + 6 files changed, 51 insertions(+), 2 deletions(-) diff --git a/diktat-analysis.yml b/diktat-analysis.yml index fc8c6764ee..14bfcb612c 100644 --- a/diktat-analysis.yml +++ b/diktat-analysis.yml @@ -312,6 +312,8 @@ ignorePropertyDeclaration: "false" # Is ignore local variable ignoreLocalVariableDeclaration: "false" + # Is ignore value parameter + ignoreValueParameter: "true" # Is ignore constant ignoreConstantDeclaration: "true" # Is ignore property in companion object diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/MagicNumberRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/MagicNumberRule.kt index cf6174d2a0..643362eb52 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/MagicNumberRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/MagicNumberRule.kt @@ -16,6 +16,7 @@ import com.pinterest.ktlint.core.ast.ElementType.MINUS import com.pinterest.ktlint.core.ast.ElementType.OPERATION_REFERENCE import com.pinterest.ktlint.core.ast.ElementType.PROPERTY import com.pinterest.ktlint.core.ast.ElementType.RANGE +import com.pinterest.ktlint.core.ast.ElementType.VALUE_PARAMETER import com.pinterest.ktlint.core.ast.parent import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.psi.KtFunction @@ -49,7 +50,8 @@ class MagicNumberRule(configRules: List) : DiktatRule( val isHashFunction = node.parent({ it.elementType == FUN && it.isHashFun() }) != null val isConstant = node.parent({ it.elementType == PROPERTY && it.isConstant() }) != null val isPropertyDeclaration = !isConstant && node.parent({ it.elementType == PROPERTY && !it.isNodeFromCompanionObject() }) != null - val isLocalVariable = node.parent({ it.isVarProperty() && (it.psi as KtProperty).isLocal }) != null + val isLocalVariable = node.parent({ it.elementType == PROPERTY && it.isVarProperty() && (it.psi as KtProperty).isLocal }) != null + val isValueParameter = node.parent({ it.elementType == VALUE_PARAMETER }) != null val isCompanionObjectProperty = node.parent({ it.elementType == PROPERTY && it.isNodeFromCompanionObject() }) != null val isEnums = node.parent({ it.elementType == ENUM_ENTRY }) != null val isRanges = node.treeParent.run { @@ -58,7 +60,7 @@ class MagicNumberRule(configRules: List) : DiktatRule( } val isExtensionFunctions = node.parent({ it.elementType == FUN && (it.psi as KtFunction).isExtensionDeclaration() }) != null && node.parents().find { it.elementType == PROPERTY } == null - val result = listOf(isHashFunction, isPropertyDeclaration, isLocalVariable, isConstant, + val result = listOf(isHashFunction, isPropertyDeclaration, isLocalVariable, isValueParameter, isConstant, isCompanionObjectProperty, isEnums, isRanges, isExtensionFunctions).zip(mapConfiguration.map { configuration.getParameter(it.key) }) if (result.any { it.first && it.first != it.second } && !isIgnoreNumber) { MAGIC_NUMBER.warn(configRules, emitWarn, isFixMode, nodeText, node.startOffset, node) @@ -98,6 +100,7 @@ class MagicNumberRule(configRules: List) : DiktatRule( "ignoreHashCodeFunction" to true, "ignorePropertyDeclaration" to false, "ignoreLocalVariableDeclaration" to false, + "ignoreValueParameter" to true, "ignoreConstantDeclaration" to true, "ignoreCompanionObjectPropertyDeclaration" to true, "ignoreEnums" to false, diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt index e68bb1c44c..6b6359f8b5 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt @@ -29,6 +29,7 @@ import com.pinterest.ktlint.core.ast.ElementType.LBRACE import com.pinterest.ktlint.core.ast.ElementType.MODIFIER_LIST import com.pinterest.ktlint.core.ast.ElementType.OVERRIDE_KEYWORD import com.pinterest.ktlint.core.ast.ElementType.PRIVATE_KEYWORD +import com.pinterest.ktlint.core.ast.ElementType.PROPERTY import com.pinterest.ktlint.core.ast.ElementType.PROTECTED_KEYWORD import com.pinterest.ktlint.core.ast.ElementType.PUBLIC_KEYWORD import com.pinterest.ktlint.core.ast.ElementType.WHITE_SPACE diff --git a/diktat-rules/src/main/resources/diktat-analysis-huawei.yml b/diktat-rules/src/main/resources/diktat-analysis-huawei.yml index e49788b609..9354b65640 100644 --- a/diktat-rules/src/main/resources/diktat-analysis-huawei.yml +++ b/diktat-rules/src/main/resources/diktat-analysis-huawei.yml @@ -312,6 +312,8 @@ ignorePropertyDeclaration: "false" # Is ignore local variable ignoreLocalVariableDeclaration: "false" + # Is ignore value parameter + ignoreValueParameter: "true" # Is ignore constant ignoreConstantDeclaration: "true" # Is ignore property in companion object diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/MagicNumberRuleWarnTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/MagicNumberRuleWarnTest.kt index eddea55859..baffac256c 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/MagicNumberRuleWarnTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/MagicNumberRuleWarnTest.kt @@ -20,6 +20,7 @@ class MagicNumberRuleWarnTest : LintTestBase(::MagicNumberRule) { "ignoreHashCodeFunction" to "true", "ignorePropertyDeclaration" to "true", "ignoreLocalVariableDeclaration" to "true", + "ignoreValueParameter" to "false", "ignoreConstantDeclaration" to "true", "ignoreCompanionObjectPropertyDeclaration" to "true", "ignoreEnums" to "true", @@ -142,4 +143,42 @@ class MagicNumberRuleWarnTest : LintTestBase(::MagicNumberRule) { """.trimMargin(), rulesConfigList = rulesConfigMagicNumber ) } + + @Test + @Tag(WarningNames.MAGIC_NUMBER) + fun `check value parameter`() { + lintMethod( + """ + class TomlDecoder( + var elementsCount: Int = 100 + ) + """.trimMargin(), + ) + } + + @Test + @Tag(WarningNames.MAGIC_NUMBER) + fun `check value parameter with config`() { + lintMethod( + """ + class TomlDecoder( + var elementsCount: Int = 100 + ) + """.trimMargin(), + LintError(2, 46, ruleId, "${MAGIC_NUMBER.warnText()} 100", false), + rulesConfigList = rulesConfigMagicNumber + ) + } + + @Test + @Tag(WarningNames.MAGIC_NUMBER) + fun `check value parameter in function with config`() { + lintMethod( + """ + fun TomlDecoder(elementsCount: Int = 100) {} + """.trimMargin(), + LintError(1, 54, ruleId, "${MAGIC_NUMBER.warnText()} 100", false), + rulesConfigList = rulesConfigMagicNumber + ) + } } diff --git a/examples/maven/diktat-analysis.yml b/examples/maven/diktat-analysis.yml index 3f953a53ed..f11ea46c37 100644 --- a/examples/maven/diktat-analysis.yml +++ b/examples/maven/diktat-analysis.yml @@ -308,6 +308,8 @@ ignorePropertyDeclaration: "false" # Is ignore local variable ignoreLocalVariableDeclaration: "false" + # Is ignore value parameter + ignoreValueParameter: "true" # Is ignore constant ignoreConstantDeclaration: "true" # Is ignore property in companion object From 6de6a62cd3eb8e94f596c4145aff5f602c53d6d3 Mon Sep 17 00:00:00 2001 From: Peter Trifanov Date: Tue, 11 May 2021 18:09:59 +0300 Subject: [PATCH 2/4] Fix NPE in KdocFormatting rule (#876) ### What's done: * Updated logic * Added tests --- .../rules/chapter2/kdoc/KdocFormatting.kt | 40 +++++++++---------- .../cqfn/diktat/ruleset/utils/AstNodeUtils.kt | 13 ++++++ .../cqfn/diktat/ruleset/utils/KdocUtils.kt | 18 +++++++++ .../diktat/ruleset/smoke/DiktatSmokeTest.kt | 6 +++ .../KdocFormattingMultilineTagsExpected.kt | 22 ++++++++++ .../kotlin/KdocFormattingMultilineTagsTest.kt | 18 +++++++++ 6 files changed, 96 insertions(+), 21 deletions(-) create mode 100644 diktat-rules/src/test/resources/test/smoke/src/main/kotlin/KdocFormattingMultilineTagsExpected.kt create mode 100644 diktat-rules/src/test/resources/test/smoke/src/main/kotlin/KdocFormattingMultilineTagsTest.kt 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 0fabddb676..0425cbfaad 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 @@ -20,8 +20,10 @@ import org.cqfn.diktat.ruleset.utils.getAllChildrenWithType import org.cqfn.diktat.ruleset.utils.getFirstChildWithType import org.cqfn.diktat.ruleset.utils.getIdentifierName import org.cqfn.diktat.ruleset.utils.hasChildMatching +import org.cqfn.diktat.ruleset.utils.hasTrailingNewlineInTagBody import org.cqfn.diktat.ruleset.utils.kDocTags import org.cqfn.diktat.ruleset.utils.leaveOnlyOneNewLine +import org.cqfn.diktat.ruleset.utils.reversedChildren import com.pinterest.ktlint.core.ast.ElementType import com.pinterest.ktlint.core.ast.ElementType.KDOC @@ -39,7 +41,6 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.CompositeElement import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl import org.jetbrains.kotlin.com.intellij.psi.tree.IElementType -import org.jetbrains.kotlin.com.intellij.psi.tree.TokenSet import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag import org.jetbrains.kotlin.lexer.KtTokens @@ -238,11 +239,9 @@ class KdocFormatting(configRules: List) : DiktatRule( previousTag.addChild(treePrev.clone() as ASTNode, null) previousTag.addChild(this.clone() as ASTNode, null) } - ?: run { - firstBasicTag.node.applyToPrevSibling(KDOC_LEADING_ASTERISK) { - treeParent.addChild(treePrev.clone() as ASTNode, this) - treeParent.addChild(this.clone() as ASTNode, treePrev) - } + ?: firstBasicTag.node.applyToPrevSibling(KDOC_LEADING_ASTERISK) { + treeParent.addChild(treePrev.clone() as ASTNode, this) + treeParent.addChild(this.clone() as ASTNode, treePrev) } } else { firstBasicTag.node.apply { @@ -256,27 +255,26 @@ class KdocFormatting(configRules: List) : DiktatRule( } private fun checkEmptyLinesBetweenBasicTags(basicTags: List) { - val tagsWithRedundantEmptyLines = basicTags.dropLast(1).filterNot { tag -> + val tagsWithRedundantEmptyLines = basicTags.dropLast(1).filter { tag -> val nextWhiteSpace = tag.node.nextSibling { it.elementType == WHITE_SPACE } - val noEmptyKdocLines = tag - .node - .getChildren(TokenSet.create(KDOC_LEADING_ASTERISK)) - .filter { it.treeNext == null || it.treeNext.elementType == WHITE_SPACE } - .count() == 0 - nextWhiteSpace?.text?.count { it == '\n' } == 1 && noEmptyKdocLines + // either there is a trailing blank line in tag's body OR there are empty lines right after this tag + tag.hasTrailingNewlineInTagBody() || nextWhiteSpace?.text?.count { it == '\n' } != 1 } tagsWithRedundantEmptyLines.forEach { tag -> KDOC_NO_NEWLINES_BETWEEN_BASIC_TAGS.warnAndFix(configRules, emitWarn, isFixMode, "@${tag.name}", tag.startOffset, tag.node) { - tag.node.nextSibling { it.elementType == WHITE_SPACE }?.leaveOnlyOneNewLine() - // the first asterisk before tag is not included inside KDOC_TAG node - // we look for the second and take its previous which should be WHITE_SPACE with newline - tag - .node - .getAllChildrenWithType(KDOC_LEADING_ASTERISK) - .firstOrNull() - ?.let { tag.node.removeRange(it.treePrev, null) } + if (tag.hasTrailingNewlineInTagBody()) { + // if there is a blank line in tag's body, we remove it and everything after it, so that the next white space is kept in place + // we look for the last LEADING_ASTERISK and take its previous node which should be WHITE_SPACE with newline + tag.node.reversedChildren() + .takeWhile { it.elementType == WHITE_SPACE || it.elementType == KDOC_LEADING_ASTERISK } + .firstOrNull { it.elementType == KDOC_LEADING_ASTERISK } + ?.let { tag.node.removeRange(it.treePrev, null) } + } else { + // otherwise we remove redundant blank lines from white space node after tag + tag.node.nextSibling { it.elementType == WHITE_SPACE }?.leaveOnlyOneNewLine() + } } } } diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt index 6b6359f8b5..e1f292178e 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt @@ -115,6 +115,19 @@ fun ASTNode.isCorrect() = this.findAllDescendantsWithSpecificType(TokenType.ERRO fun ASTNode.getAllChildrenWithType(elementType: IElementType): List = this.getChildren(null).filter { it.elementType == elementType } +/** + * Generates a sequence of this ASTNode's children in reversed order + * + * @return a reevrsed sequence of children + */ +fun ASTNode.reversedChildren(): Sequence = sequence { + var node = lastChildNode + while (node != null) { + yield(node) + node = node.treePrev + } +} + /** * Replaces the [beforeNode] of type [WHITE_SPACE] with the node with specified [text] * diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/KdocUtils.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/KdocUtils.kt index 37ba57eb2a..177be2abf5 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/KdocUtils.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/KdocUtils.kt @@ -7,6 +7,7 @@ package org.cqfn.diktat.ruleset.utils import com.pinterest.ktlint.core.ast.ElementType import com.pinterest.ktlint.core.ast.ElementType.KDOC_SECTION import com.pinterest.ktlint.core.ast.ElementType.WHITE_SPACE +import com.pinterest.ktlint.core.ast.isWhiteSpaceWithNewline import com.pinterest.ktlint.core.ast.prevSibling import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.CompositeElement @@ -33,6 +34,23 @@ fun ASTNode.kDocTags(): List { fun Iterable.hasKnownKdocTag(knownTag: KDocKnownTag): Boolean = this.find { it.knownTag == knownTag } != null +/** + * Checks for trailing newlines in tag's body. Handles cases, when there is no leading asterisk on an empty line: + * ``` + * * @param param + * + * * @return + * ``` + * as well as usual simple cases. + * + * @return true if there is a trailing newline + */ +fun KDocTag.hasTrailingNewlineInTagBody() = node.lastChildNode.isWhiteSpaceWithNewline() || + node.reversedChildren() + .takeWhile { it.elementType == WHITE_SPACE || it.elementType == ElementType.KDOC_LEADING_ASTERISK } + .firstOrNull { it.elementType == ElementType.KDOC_LEADING_ASTERISK } + ?.takeIf { it.treeNext == null || it.treeNext.elementType == WHITE_SPACE } != null + /** * This method inserts a new tag into KDoc before specified another tag, aligning it with the rest of this KDoc * diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/smoke/DiktatSmokeTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/smoke/DiktatSmokeTest.kt index a766625e9c..90cbdd62b3 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/smoke/DiktatSmokeTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/smoke/DiktatSmokeTest.kt @@ -259,6 +259,12 @@ class DiktatSmokeTest : FixTestBase("test/smoke/src/main/kotlin", ) } + @Test + @Tag("DiktatRuleSetProvider") + fun `regression - should correctly handle tags with empty lines`() { + fixAndCompare("KdocFormattingMultilineTagsExpected.kt", "KdocFormattingMultilineTagsTest.kt") + } + companion object { private const val DEFAULT_CONFIG_PATH = "../diktat-analysis.yml" private val unfixedLintErrors: MutableList = mutableListOf() diff --git a/diktat-rules/src/test/resources/test/smoke/src/main/kotlin/KdocFormattingMultilineTagsExpected.kt b/diktat-rules/src/test/resources/test/smoke/src/main/kotlin/KdocFormattingMultilineTagsExpected.kt new file mode 100644 index 0000000000..d62b70bbe7 --- /dev/null +++ b/diktat-rules/src/test/resources/test/smoke/src/main/kotlin/KdocFormattingMultilineTagsExpected.kt @@ -0,0 +1,22 @@ +package org.cqfn.diktat + +/** + * @param bar lorem ipsum + * + * dolor sit amet + * @return + */ +fun foo1(bar: Bar): Baz { + // placeholder +} + +/** + * @param bar lorem ipsum + * + * dolor sit amet + * @return + */ +fun foo2(bar: Bar): Baz { + // placeholder +} + diff --git a/diktat-rules/src/test/resources/test/smoke/src/main/kotlin/KdocFormattingMultilineTagsTest.kt b/diktat-rules/src/test/resources/test/smoke/src/main/kotlin/KdocFormattingMultilineTagsTest.kt new file mode 100644 index 0000000000..820e8a3c1d --- /dev/null +++ b/diktat-rules/src/test/resources/test/smoke/src/main/kotlin/KdocFormattingMultilineTagsTest.kt @@ -0,0 +1,18 @@ +/** + * @param bar lorem ipsum + * + * dolor sit amet + */ +fun foo1(bar: Bar): Baz { + // placeholder +} + +/** + * @param bar lorem ipsum + * + * dolor sit amet + * + */ +fun foo2(bar: Bar): Baz { + // placeholder +} From fd9b54ff9870d97509685f16e0e99b019f14e4b9 Mon Sep 17 00:00:00 2001 From: Alexander Tsay <48321920+aktsay6@users.noreply.github.com> Date: Wed, 12 May 2021 11:34:14 +0300 Subject: [PATCH 3/4] Bugfix. Not all types of nodes for annotation Suppress are considered (#878) ### What's done: * Fixed bug --- .../cqfn/diktat/ruleset/utils/AstNodeUtils.kt | 3 +- .../utils/SuppressAnnotatedExpressionTest.kt | 51 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/SuppressAnnotatedExpressionTest.kt diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt index e1f292178e..75041aaa24 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/utils/AstNodeUtils.kt @@ -15,6 +15,7 @@ import org.cqfn.diktat.ruleset.rules.chapter1.PackageNaming import com.pinterest.ktlint.core.KtLint import com.pinterest.ktlint.core.ast.ElementType +import com.pinterest.ktlint.core.ast.ElementType.ANNOTATED_EXPRESSION import com.pinterest.ktlint.core.ast.ElementType.ANNOTATION_ENTRY import com.pinterest.ktlint.core.ast.ElementType.BLOCK_COMMENT import com.pinterest.ktlint.core.ast.ElementType.CONST_KEYWORD @@ -503,7 +504,7 @@ fun ASTNode?.isAccessibleOutside(): Boolean = */ fun ASTNode.hasSuppress(warningName: String) = parent({ node -> val annotationNode = if (node.elementType != FILE) { - node.findChildByType(MODIFIER_LIST) + node.findChildByType(MODIFIER_LIST) ?: node.findChildByType(ANNOTATED_EXPRESSION) } else { node.findChildByType(FILE_ANNOTATION_LIST) } diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/SuppressAnnotatedExpressionTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/SuppressAnnotatedExpressionTest.kt new file mode 100644 index 0000000000..70e9e35140 --- /dev/null +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/utils/SuppressAnnotatedExpressionTest.kt @@ -0,0 +1,51 @@ +package org.cqfn.diktat.ruleset.utils + +import org.cqfn.diktat.ruleset.constants.Warnings +import org.cqfn.diktat.ruleset.rules.DIKTAT_RULE_SET_ID +import org.cqfn.diktat.ruleset.rules.chapter3.CollapseIfStatementsRule +import org.cqfn.diktat.util.LintTestBase + +import com.pinterest.ktlint.core.LintError +import org.junit.jupiter.api.Test + +class SuppressAnnotatedExpressionTest : LintTestBase(::CollapseIfStatementsRule) { + private val ruleId: String = "$DIKTAT_RULE_SET_ID:collapse-if" + + @Test + fun `should lint errors without suppress`() { + val code = + """ + |fun foo() { + | if (true) { + | if (true) { + | if (true) { + | + | } + | } + | } + |} + """.trimMargin() + lintMethod(code, + LintError(3, 8, ruleId, "${Warnings.COLLAPSE_IF_STATEMENTS.warnText()} avoid using redundant nested if-statements", true), + LintError(4, 12, ruleId, "${Warnings.COLLAPSE_IF_STATEMENTS.warnText()} avoid using redundant nested if-statements", true) + ) + } + + @Test + fun `should suppress annotated expressions`() { + val code = + """ + |fun foo() { + | if (true) { + | @Suppress("COLLAPSE_IF_STATEMENTS") + | if (true) { + | if (true) { + | + | } + | } + | } + |} + """.trimMargin() + lintMethod(code) + } +} From 2b17b3163d8540682d2b69ac3132315d00e7bf80 Mon Sep 17 00:00:00 2001 From: Denis Kumar Date: Wed, 12 May 2021 11:57:41 +0300 Subject: [PATCH 4/4] Disable Magic Number in test (#879) * Disable Magic Number in test ### What's done: Added option Added test --- diktat-analysis.yml | 2 ++ .../ruleset/rules/chapter3/MagicNumberRule.kt | 14 +++++++++- .../main/resources/diktat-analysis-huawei.yml | 2 ++ .../src/main/resources/diktat-analysis.yml | 2 ++ .../chapter3/MagicNumberRuleWarnTest.kt | 26 +++++++++++++++++++ 5 files changed, 45 insertions(+), 1 deletion(-) diff --git a/diktat-analysis.yml b/diktat-analysis.yml index 14bfcb612c..1f107ac579 100644 --- a/diktat-analysis.yml +++ b/diktat-analysis.yml @@ -304,6 +304,8 @@ - name: MAGIC_NUMBER enabled: true configuration: + # Ignore numbers from test + ignoreTest: "true" # Ignore numbers ignoreNumbers: "-1, 1, 0, 2" # Is ignore override hashCode function diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/MagicNumberRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/MagicNumberRule.kt index 643362eb52..549fd4d8e4 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/MagicNumberRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/MagicNumberRule.kt @@ -2,6 +2,7 @@ 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.getCommonConfiguration import org.cqfn.diktat.common.config.rules.getRuleConfig import org.cqfn.diktat.ruleset.constants.Warnings.MAGIC_NUMBER import org.cqfn.diktat.ruleset.rules.DiktatRule @@ -37,9 +38,14 @@ class MagicNumberRule(configRules: List) : DiktatRule( configRules.getRuleConfig(MAGIC_NUMBER)?.configuration ?: emptyMap() ) } + @Suppress("COLLAPSE_IF_STATEMENTS") override fun logic(node: ASTNode) { + val filePath = node.getRootNode().getFilePath() + val config = configRules.getCommonConfiguration() if (node.elementType == INTEGER_CONSTANT || node.elementType == FLOAT_CONSTANT) { - checkNumber(node, configuration) + if (!isLocatedInTest(filePath.splitPathToDirs(), config.testAnchors) || !configuration.isIgnoreTest) { + checkNumber(node, configuration) + } } } @@ -76,6 +82,11 @@ class MagicNumberRule(configRules: List) : DiktatRule( * [RuleConfiguration] for configuration */ class MagicNumberConfiguration(config: Map) : RuleConfiguration(config) { + /** + * Flag to ignore numbers from test + */ + val isIgnoreTest = config["ignoreTest"]?.toBoolean() ?: IGNORE_TEST + /** * List of ignored numbers */ @@ -95,6 +106,7 @@ class MagicNumberRule(configRules: List) : DiktatRule( } companion object { + const val IGNORE_TEST = true val ignoreNumbersList = listOf("-1", "1", "0", "2") val mapConfiguration = mapOf( "ignoreHashCodeFunction" to true, diff --git a/diktat-rules/src/main/resources/diktat-analysis-huawei.yml b/diktat-rules/src/main/resources/diktat-analysis-huawei.yml index 9354b65640..7ea3341699 100644 --- a/diktat-rules/src/main/resources/diktat-analysis-huawei.yml +++ b/diktat-rules/src/main/resources/diktat-analysis-huawei.yml @@ -304,6 +304,8 @@ - name: MAGIC_NUMBER enabled: true configuration: + # Ignore numbers from test + ignoreTest: "true" # Ignore numbers ignoreNumbers: "-1, 1, 0, 2" # Is ignore override hashCode function diff --git a/diktat-rules/src/main/resources/diktat-analysis.yml b/diktat-rules/src/main/resources/diktat-analysis.yml index 3f953a53ed..b6a1f62d55 100644 --- a/diktat-rules/src/main/resources/diktat-analysis.yml +++ b/diktat-rules/src/main/resources/diktat-analysis.yml @@ -300,6 +300,8 @@ - name: MAGIC_NUMBER enabled: true configuration: + # Ignore numbers from test + ignoreTest: "true" # Ignore numbers ignoreNumbers: "-1, 1, 0, 2" # Is ignore override hashCode function diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/MagicNumberRuleWarnTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/MagicNumberRuleWarnTest.kt index baffac256c..91ee368201 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/MagicNumberRuleWarnTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/MagicNumberRuleWarnTest.kt @@ -181,4 +181,30 @@ class MagicNumberRuleWarnTest : LintTestBase(::MagicNumberRule) { rulesConfigList = rulesConfigMagicNumber ) } + + @Test + @Tag(WarningNames.MAGIC_NUMBER) + fun `check ignore numbers in test`() { + lintMethod( + """ + |fun f1oo() { + | val m = -1 + | val a: Byte = 4 + | val b = 0xff + |} + | + |enum class A(b:Int) { + | A(-240), + | B(50), + | C(3), + |} + |@Override + |fun hashCode(): Int { + | return 32 + |} + """.trimMargin(), + fileName = "src/test/kotlin/org/cqfn/diktat/test/hehe/MagicNumberTest.kt", + rulesConfigList = rulesConfigIgnoreNumbersMagicNumber, + ) + } }