Repository: cqfn/diKTat
Pull request #974 (2021-07-09 14:55:49)

Improve way of header KDOC detection
### 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

codecov[bot]: # [Codecov](https://codecov.io/gh/cqfn/diKTat/pull/974?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cqfn) Report
> Merging [#974](https://codecov.io/gh/cqfn/diKTat/pull/974?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cqfn) (f9390fb) into [master](https://codecov.io/gh/cqfn/diKTat/commit/7eb4698c3799845bf953b106e09433b3557bd8b4?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cqfn) (7eb4698) will **increase** coverage by `0.02%`.
> The diff coverage is `100.00%`.

> :exclamation: Current head f9390fb differs from pull request most recent head 12afae1. Consider uploading reports for the commit 12afae1 to get more accurate results
[![Impacted file tree graph](https://codecov.io/gh/cqfn/diKTat/pull/974/graphs/tree.svg?width=650&height=150&src=pr&token=P2quRDffpt&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cqfn)](https://codecov.io/gh/cqfn/diKTat/pull/974?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cqfn)

```diff
@@             Coverage Diff              @@
##             master     #974      +/-   ##
============================================
+ Coverage     83.77%   83.79%   +0.02%     
- Complexity     2404     2408       +4     
============================================
  Files           101      101              
  Lines          6076     6078       +2     
  Branches       1798     1799       +1     
============================================
+ Hits           5090     5093       +3     
  Misses          269      269              
+ Partials        717      716       -1     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `83.79% <100.00%> (+0.02%)` | :arrow_up: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cqfn#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/cqfn/diKTat/pull/974?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cqfn) | Coverage Δ | |
|---|---|---|
| [.../ruleset/rules/chapter3/files/FileStructureRule.kt](https://codecov.io/gh/cqfn/diKTat/pull/974/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cqfn#diff-ZGlrdGF0LXJ1bGVzL3NyYy9tYWluL2tvdGxpbi9vcmcvY3Fmbi9kaWt0YXQvcnVsZXNldC9ydWxlcy9jaGFwdGVyMy9maWxlcy9GaWxlU3RydWN0dXJlUnVsZS5rdA==) | `83.73% <100.00%> (+0.70%)` | :arrow_up: |
| [.../ruleset/rules/chapter3/files/TopLevelOrderRule.kt](https://codecov.io/gh/cqfn/diKTat/pull/974/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cqfn#diff-ZGlrdGF0LXJ1bGVzL3NyYy9tYWluL2tvdGxpbi9vcmcvY3Fmbi9kaWt0YXQvcnVsZXNldC9ydWxlcy9jaGFwdGVyMy9maWxlcy9Ub3BMZXZlbE9yZGVyUnVsZS5rdA==) | `97.87% <100.00%> (+0.04%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/cqfn/diKTat/pull/974?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cqfn).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cqfn)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/cqfn/diKTat/pull/974?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cqfn). Last update [7eb4698...12afae1](https://codecov.io/gh/cqfn/diKTat/pull/974?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cqfn). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cqfn).


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 d750f747..00ab8e53 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 62b12ccc..666ab664 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 e58c846a..b3789ba2 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 00000000..23f2fda0
--- /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 00000000..ff5979f2
--- /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 82534d23..00000000
--- 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 f7613bf7..00000000
--- 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 {}