Repository: analysis-dev/diktat (kotlin)

Issue:
Kdoc fixer false-negative: not generating a Kdoc for several public functions 
diktat 1.0.0-RC

```
    fun hasNoChildren() = children.size == 0
    fun getFirstChild() = children.elementAtOrNull(0)
```


```
/**
 * @return
 */
fun hasNoChildren() = children.size == 0
// <------ where is a Kdoc?
fun getFirstChild() = children.elementAtOrNull(0)
```

Pull request:
### What's done:
* fixed bug in WRONG_NEWLINES
* now don't ask @return on function with name same last reference Expression
Closes #965

Patch:
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 eeaf68b944..6bca693f84 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
@@ -56,6 +56,7 @@ import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag
 import org.jetbrains.kotlin.psi.KtCallExpression
 import org.jetbrains.kotlin.psi.KtCatchClause
 import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
+import org.jetbrains.kotlin.psi.KtFunction
 import org.jetbrains.kotlin.psi.KtThrowExpression
 import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
 import org.jetbrains.kotlin.psi.psiUtil.referenceExpression
@@ -118,7 +119,7 @@ class KdocMethods(configRules: List<RulesConfig>) : DiktatRule(
         // if no tag failed, we have too little information to suggest KDoc - it would just be empty
         if (kdoc == null && anyTagFailed) {
             addKdocTemplate(node, name, missingParameters, explicitlyThrownExceptions, returnCheckFailed)
-        } else if (kdoc == null) {
+        } else if (kdoc == null && !isReferenceExpressionWithSameName(node, kdocTags)) {
             MISSING_KDOC_ON_FUNCTION.warn(configRules, emitWarn, false, name, node.startOffset, node)
         } else {
             if (paramCheckFailed) {
@@ -146,6 +147,14 @@ class KdocMethods(configRules: List<RulesConfig>) : DiktatRule(
         }
     }
 
+    private fun isReferenceExpressionWithSameName(node: ASTNode, kdocTags: Collection<KDocTag>?): Boolean {
+        val lastDotQualifiedExpression = node.findChildByType(DOT_QUALIFIED_EXPRESSION)?.psi
+            ?.let { (it as KtDotQualifiedExpression).selectorExpression?.text?.substringBefore('(') }
+        val funName = (node.psi as KtFunction).name
+        return funName == lastDotQualifiedExpression
+    }
+
+    @Suppress("WRONG_NEWLINES")
     private fun hasReturnCheckFailed(node: ASTNode, kdocTags: Collection<KDocTag>?): Boolean {
         if (node.isSingleLineGetterOrSetter()) {
             return false
@@ -156,8 +165,10 @@ class KdocMethods(configRules: List<RulesConfig>) : DiktatRule(
         val hasExplicitNotUnitReturnType = explicitReturnType != null && explicitReturnType.text != "Unit"
         val hasExplicitUnitReturnType = explicitReturnType != null && explicitReturnType.text == "Unit"
         val isFunWithExpressionBody = node.hasChildOfType(EQ)
+        val isReferenceExpressionWithSameName = node.findAllDescendantsWithSpecificType(REFERENCE_EXPRESSION).map { it.text }.contains((node.psi as KtFunction).name)
         val hasReturnKdoc = kdocTags != null && kdocTags.hasKnownKdocTag(KDocKnownTag.RETURN)
-        return (hasExplicitNotUnitReturnType || isFunWithExpressionBody && !hasExplicitUnitReturnType && hasNotExpressionBodyTypes) && !hasReturnKdoc
+        return (hasExplicitNotUnitReturnType || isFunWithExpressionBody && !hasExplicitUnitReturnType && hasNotExpressionBodyTypes)
+        && !hasReturnKdoc && !isReferenceExpressionWithSameName
     }
 
     private fun getExplicitlyThrownExceptions(node: ASTNode): Set<String> {
diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/DataClassesRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/DataClassesRule.kt
index 6bc07f5f01..51ab593aca 100644
--- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/DataClassesRule.kt
+++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter6/classes/DataClassesRule.kt
@@ -10,11 +10,9 @@ import com.pinterest.ktlint.core.ast.ElementType.BLOCK
 import com.pinterest.ktlint.core.ast.ElementType.CLASS
 import com.pinterest.ktlint.core.ast.ElementType.CLASS_BODY
 import com.pinterest.ktlint.core.ast.ElementType.CLASS_INITIALIZER
-import com.pinterest.ktlint.core.ast.ElementType.DATA_KEYWORD
 import com.pinterest.ktlint.core.ast.ElementType.ENUM_KEYWORD
 import com.pinterest.ktlint.core.ast.ElementType.FUN
 import com.pinterest.ktlint.core.ast.ElementType.INNER_KEYWORD
-import com.pinterest.ktlint.core.ast.ElementType.INTERFACE_KEYWORD
 import com.pinterest.ktlint.core.ast.ElementType.MODIFIER_LIST
 import com.pinterest.ktlint.core.ast.ElementType.OPEN_KEYWORD
 import com.pinterest.ktlint.core.ast.ElementType.PRIMARY_CONSTRUCTOR


Test patch:
diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/KdocMethodsTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/KdocMethodsTest.kt
index b7f3135db6..e46f8070b9 100644
--- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/KdocMethodsTest.kt
+++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter2/KdocMethodsTest.kt
@@ -381,6 +381,17 @@ class KdocMethodsTest : LintTestBase(::KdocMethods) {
         )
     }
 
+    @Test
+    @Tag(WarningNames.MISSING_KDOC_ON_FUNCTION)
+    fun `KDoc shouldn't be for function with name as method`() {
+        lintMethod(
+            """
+                    |@GetMapping("/projects")
+                    |fun getProjects() = projectService.getProjects(x.prop())
+                """.trimMargin(),
+        )
+    }
+
     @Test
     @Tag(WarningNames.MISSING_KDOC_ON_FUNCTION)
     fun `KDoc shouldn't trigger on actual methods`() {
diff --git a/diktat-rules/src/test/resources/test/paragraph2/kdoc/package/src/main/kotlin/org/cqfn/diktat/kdoc/methods/MissingKdocOnFunctionExpected.kt b/diktat-rules/src/test/resources/test/paragraph2/kdoc/package/src/main/kotlin/org/cqfn/diktat/kdoc/methods/MissingKdocOnFunctionExpected.kt
index db817c5226..d695009561 100644
--- a/diktat-rules/src/test/resources/test/paragraph2/kdoc/package/src/main/kotlin/org/cqfn/diktat/kdoc/methods/MissingKdocOnFunctionExpected.kt
+++ b/diktat-rules/src/test/resources/test/paragraph2/kdoc/package/src/main/kotlin/org/cqfn/diktat/kdoc/methods/MissingKdocOnFunctionExpected.kt
@@ -10,4 +10,7 @@ fun hasNoChildren() = children.size == 0
  * @return
  */
 fun getFirstChild() = children.elementAtOrNull(0)
+
+    @GetMapping("/projects")
+    fun getProjects() = projectService.getProjects()
 }
\ No newline at end of file
diff --git a/diktat-rules/src/test/resources/test/paragraph2/kdoc/package/src/main/kotlin/org/cqfn/diktat/kdoc/methods/MissingKdocOnFunctionTest.kt b/diktat-rules/src/test/resources/test/paragraph2/kdoc/package/src/main/kotlin/org/cqfn/diktat/kdoc/methods/MissingKdocOnFunctionTest.kt
index b782d8cb1a..a603211e4c 100644
--- a/diktat-rules/src/test/resources/test/paragraph2/kdoc/package/src/main/kotlin/org/cqfn/diktat/kdoc/methods/MissingKdocOnFunctionTest.kt
+++ b/diktat-rules/src/test/resources/test/paragraph2/kdoc/package/src/main/kotlin/org/cqfn/diktat/kdoc/methods/MissingKdocOnFunctionTest.kt
@@ -4,4 +4,7 @@ class Example {
     fun hasNoChildren() = children.size == 0
 
     fun getFirstChild() = children.elementAtOrNull(0)
+
+    @GetMapping("/projects")
+    fun getProjects() = projectService.getProjects()
 }
\ No newline at end of file