diff --git a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/chapter2/kdoc/KdocMethods.kt b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/chapter2/kdoc/KdocMethods.kt index fba546c99d..e0970b4ce3 100644 --- a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/chapter2/kdoc/KdocMethods.kt +++ b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/chapter2/kdoc/KdocMethods.kt @@ -53,6 +53,7 @@ import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens.COLON import org.jetbrains.kotlin.lexer.KtTokens.EQ +import org.jetbrains.kotlin.lexer.KtTokens.WHITE_SPACE import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtCatchClause import org.jetbrains.kotlin.psi.KtDotQualifiedExpression @@ -106,11 +107,10 @@ class KdocMethods(configRules: List) : DiktatRule( val explicitlyThrownExceptions = getExplicitlyThrownExceptions(node) + getRethrownExceptions(node) val missingExceptions = explicitlyThrownExceptions - .minus(kdocTags + .minus((kdocTags ?.filter { it.knownTag == KDocKnownTag.THROWS } - ?.mapNotNull { it.getSubjectName() } - ?.toSet() ?: emptySet(), - ) + ?.mapNotNull { it.getSubjectLinkName() } + ?.toSet() ?: emptySet()).toSet()) val paramCheckFailed = (missingParameters.isNotEmpty() && !node.isSingleLineGetterOrSetter()) || kDocMissingParameters.isNotEmpty() val returnCheckFailed = hasReturnCheckFailed(node, kdocTags) @@ -135,14 +135,21 @@ class KdocMethods(configRules: List) : DiktatRule( } } + private fun KDocTag.getSubjectLinkName(): String? = + node.getChildren(null) + .dropWhile { it.elementType == KDocTokens.TAG_NAME } + .dropWhile { it.elementType == WHITE_SPACE } + .firstOrNull { it.elementType == KDocTokens.MARKDOWN_LINK } + ?.text + @Suppress("TYPE_ALIAS") private fun getMissingParameters(node: ASTNode, kdocTags: Collection?): Pair, List> { val parameterNames = node.parameterNames() - val kdocParamList = kdocTags?.filter { it.knownTag == KDocKnownTag.PARAM && it.getSubjectName() != null } + val kdocParamList = kdocTags?.filter { it.knownTag == KDocKnownTag.PARAM && it.getSubjectLinkName() != null } return if (parameterNames.isEmpty()) { Pair(emptyList(), kdocParamList ?: emptyList()) - } else if (kdocParamList != null && kdocParamList.isNotEmpty()) { - Pair(parameterNames.minus(kdocParamList.map { it.getSubjectName() }), kdocParamList.filter { it.getSubjectName() !in parameterNames }) + } else if (!kdocParamList.isNullOrEmpty()) { + Pair(parameterNames.minus(kdocParamList.map { it.getSubjectLinkName() }.toSet()), kdocParamList.filter { it.getSubjectLinkName() !in parameterNames }) } else { Pair(parameterNames.toList(), emptyList()) } @@ -217,7 +224,7 @@ class KdocMethods(configRules: List) : DiktatRule( ) { kdocMissingParameters.forEach { KDOC_WITHOUT_PARAM_TAG.warn(configRules, emitWarn, - "${it.getSubjectName()} param isn't present in argument list", it.node.startOffset, + "${ it.getSubjectLinkName() } param isn't present in argument list", it.node.startOffset, it.node) } if (missingParameters.isNotEmpty()) { @@ -229,7 +236,7 @@ class KdocMethods(configRules: List) : DiktatRule( kdoc?.insertTagBefore(beforeTag?.node) { addChild(LeafPsiElement(KDocTokens.TAG_NAME, "@param")) addChild(PsiWhiteSpaceImpl(" ")) - addChild(LeafPsiElement(KDocTokens.TEXT, it)) + addChild(LeafPsiElement(KDocTokens.MARKDOWN_LINK, it)) } } } @@ -260,8 +267,8 @@ class KdocMethods(configRules: List) : DiktatRule( missingExceptions.forEach { kdoc?.insertTagBefore(null) { addChild(LeafPsiElement(KDocTokens.TAG_NAME, "@throws")) - addChild(LeafPsiElement(KDocTokens.TEXT, " ")) - addChild(LeafPsiElement(KDocTokens.TEXT, it)) + addChild(PsiWhiteSpaceImpl(" ")) + addChild(LeafPsiElement(KDocTokens.MARKDOWN_LINK, it)) } } } diff --git a/diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/chapter2/KdocMethodsFixTest.kt b/diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/chapter2/KdocMethodsFixTest.kt index 2332b6c5cb..d5fade6004 100644 --- a/diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/chapter2/KdocMethodsFixTest.kt +++ b/diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/chapter2/KdocMethodsFixTest.kt @@ -4,7 +4,6 @@ import com.saveourtool.diktat.ruleset.rules.chapter2.kdoc.KdocMethods import com.saveourtool.diktat.util.FixTestBase import generated.WarningNames -import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Tags import org.junit.jupiter.api.Test @@ -37,7 +36,6 @@ class KdocMethodsFixTest : FixTestBase("test/paragraph2/kdoc/package/src/main/ko @Test @Tag(WarningNames.KDOC_WITHOUT_PARAM_TAG) - @Disabled("https://github.com/saveourtool/diktat/issues/1737") fun `@param tag should be added to existing KDoc`() { fixAndCompare("ParamTagInsertionExpected.kt", "ParamTagInsertionTested.kt") } @@ -50,7 +48,6 @@ class KdocMethodsFixTest : FixTestBase("test/paragraph2/kdoc/package/src/main/ko @Test @Tag(WarningNames.KDOC_WITHOUT_THROWS_TAG) - @Disabled("https://github.com/saveourtool/diktat/issues/1737") fun `@throws tag should be added to existing KDoc`() { fixAndCompare("ThrowsTagInsertionExpected.kt", "ThrowsTagInsertionTested.kt") } @@ -61,7 +58,6 @@ class KdocMethodsFixTest : FixTestBase("test/paragraph2/kdoc/package/src/main/ko Tag(WarningNames.KDOC_WITHOUT_RETURN_TAG), Tag(WarningNames.KDOC_WITHOUT_THROWS_TAG) ) - @Disabled("https://github.com/saveourtool/diktat/issues/1737") fun `KdocMethods rule should reformat code (full example)`() { fixAndCompare("KdocMethodsFullExpected.kt", "KdocMethodsFullTested.kt") }