Repository: analysis-dev/diktat (kotlin)

Issue:
Not all types of nodes for annotation Suppress are considered
When we check whether the node has a parent annotated with `@Suppress`,
we finding the type `MODIFIER_LIST`.

However, in this example, the actual type of node is `ANNOTATED_EXPRESSION`


```kotlin
fun foo () {
     if (true) {
         @Suppress("COLLAPSE_IF_STATEMENTS") 
         if (true) {
             if (true) {
                 doSomething()
             }    
         }
     }    
}
```

Thus, the warning for the last `if` will be still remain. And only for second `if` warning will be suppressed.

Pull request description:
### What's done:
  * Fixed bug

This pull request closes #824

Patch:
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)
     }


Test patch:
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)
+    }
+}