Repository: analysis-dev/diktat (kotlin)

Issue:
FileStructure rule doesn't fix incorrect order of kdoc and package directive
## Describe the bug
Consider the following code
```kotlin
package test.paragraph3.top_level

/**
 * Header Kdoc
 */

import org.cqfn.diktat.bar

class A {}
```
## Expected behavior
```kotlin
/**
 * Header Kdoc
 */

package test.paragraph3.top_level

import org.cqfn.diktat.bar

class A {}
```
## Observed behavior
**Nothing changed**

-----------
Note: This test is already created in diKTat and called `TopLevelWithHeaderKdocTest.kt`, but for now disabled

Pull request description:
### What's done:
* Improve way of header KDOC detection: If kdoc located between package directive and imports list, is also should be moved to the top level
* Add test

Patch:
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 d750f74768..00ab8e5310 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
@@ -145,7 +145,12 @@ class FileStructureRule(configRules: List<RulesConfig>) : DiktatRule(
             ?.takeIf { blockCommentNode ->
                 copyrightWords.any { blockCommentNode.text.contains(it, ignoreCase = true) }
             }
+        // firstCodeNode could be:
+        // * package directive - in this case we looking for kdoc before package directive
+        // and if it doesn't exist, additionally looking for kdoc before imports list
+        // * imports list or actual code - if there is no kdoc before it, suppose that it is absent in file
         var headerKdoc = firstCodeNode.prevSibling { it.elementType == KDOC }
+            ?: if (firstCodeNode == packageDirectiveNode) importsList?.prevSibling { it.elementType == KDOC } else null
         // Annotations with target`file` can only be placed before `package` directive.
         var fileAnnotations = node.findChildByType(FILE_ANNOTATION_LIST)
         // We also collect all other elements that are placed on top of the file.


Test patch:
diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/FileStructureRuleFixTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/FileStructureRuleFixTest.kt
index 62b12ccca4..666ab66488 100644
--- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/FileStructureRuleFixTest.kt
+++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/FileStructureRuleFixTest.kt
@@ -23,6 +23,12 @@ class FileStructureRuleFixTest : FixTestBase("test/paragraph3/file_structure", :
         fixAndCompare("CopyrightCommentPositionExpected.kt", "CopyrightCommentPositionTest.kt")
     }
 
+    @Test
+    @Tag(WarningNames.FILE_INCORRECT_BLOCKS_ORDER)
+    fun `should move header kdoc before package directive`() {
+        fixAndCompare("HeaderKdocAfterPackageExpected.kt", "HeaderKdocAfterPackageTest.kt")
+    }
+
     @Test
     @Tag(WarningNames.FILE_NO_BLANK_LINE_BETWEEN_BLOCKS)
     fun `should insert blank lines between code blocks`() {
diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/files/TopLevelOrderRuleFixTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/files/TopLevelOrderRuleFixTest.kt
index e58c846aa6..b3789ba210 100644
--- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/files/TopLevelOrderRuleFixTest.kt
+++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter3/files/TopLevelOrderRuleFixTest.kt
@@ -20,12 +20,4 @@ class TopLevelOrderRuleFixTest : FixTestBase("test/paragraph3/top_level", ::TopL
     fun `should fix top level order with comment`() {
         fixAndCompare("TopLevelWithCommentExpected.kt", "TopLevelWithCommentTest.kt")
     }
-
-    // FixMe: should be considered this case (swapped order of kdoc and package directive)
-    @Disabled("Isn't working yet, because KDoc is bound to class declaration here. Also, should be moved to FileStructureRuleFixTest.")
-    @Test
-    @Tag(WarningNames.TOP_LEVEL_ORDER)
-    fun `should fix top level order with header kdoc`() {
-        fixAndCompare("TopLevelWithHeaderKdocExpected.kt", "TopLevelWithHeaderKdocTest.kt")
-    }
 }
diff --git a/diktat-rules/src/test/resources/test/paragraph3/file_structure/HeaderKdocAfterPackageExpected.kt b/diktat-rules/src/test/resources/test/paragraph3/file_structure/HeaderKdocAfterPackageExpected.kt
new file mode 100644
index 0000000000..23f2fda01a
--- /dev/null
+++ b/diktat-rules/src/test/resources/test/paragraph3/file_structure/HeaderKdocAfterPackageExpected.kt
@@ -0,0 +1,11 @@
+/**
+ * Header Kdoc
+ */
+
+package test.paragraph3.file_structure
+
+import org.cqfn.diktat.Bar
+
+class A {
+    val a = Bar()
+}
diff --git a/diktat-rules/src/test/resources/test/paragraph3/file_structure/HeaderKdocAfterPackageTest.kt b/diktat-rules/src/test/resources/test/paragraph3/file_structure/HeaderKdocAfterPackageTest.kt
new file mode 100644
index 0000000000..ff5979f216
--- /dev/null
+++ b/diktat-rules/src/test/resources/test/paragraph3/file_structure/HeaderKdocAfterPackageTest.kt
@@ -0,0 +1,11 @@
+package test.paragraph3.file_structure
+
+/**
+ * Header Kdoc
+ */
+
+import org.cqfn.diktat.Bar
+
+class A {
+    val a = Bar()
+}
diff --git a/diktat-rules/src/test/resources/test/paragraph3/top_level/TopLevelWithHeaderKdocExpected.kt b/diktat-rules/src/test/resources/test/paragraph3/top_level/TopLevelWithHeaderKdocExpected.kt
deleted file mode 100644
index 82534d239f..0000000000
--- a/diktat-rules/src/test/resources/test/paragraph3/top_level/TopLevelWithHeaderKdocExpected.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * Header Kdoc
- */
-
-package test.paragraph3.top_level
-
-import org.cqfn.diktat.bar
-
-class A {}
diff --git a/diktat-rules/src/test/resources/test/paragraph3/top_level/TopLevelWithHeaderKdocTest.kt b/diktat-rules/src/test/resources/test/paragraph3/top_level/TopLevelWithHeaderKdocTest.kt
deleted file mode 100644
index f7613bf749..0000000000
--- a/diktat-rules/src/test/resources/test/paragraph3/top_level/TopLevelWithHeaderKdocTest.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package test.paragraph3.top_level
-
-/**
- * Header Kdoc
- */
-
-import org.cqfn.diktat.bar
-
-class A {}