Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KDoc check property in class #598

Merged
merged 10 commits into from
Dec 7, 2020
3 changes: 3 additions & 0 deletions diktat-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,9 @@
# Checks that property in constructor doesn't contains comment
- name: KDOC_NO_CONSTRUCTOR_PROPERTY
enabled: true
# Checks that property in KDoc present in class
- name: KDOC_EXTRA_PROPERTY
enabled: true
# Checks that KDoc in constructor has property tag but with comment inside constructor
- name: KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT
enabled: true
Expand Down
2 changes: 2 additions & 0 deletions diktat-rules/src/main/kotlin/generated/WarningNames.kt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ public object WarningNames {

public const val KDOC_NO_CONSTRUCTOR_PROPERTY: String = "KDOC_NO_CONSTRUCTOR_PROPERTY"

public const val KDOC_EXTRA_PROPERTY: String = "KDOC_EXTRA_PROPERTY"

public const val KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT: String =
"KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ enum class Warnings(val canBeAutoCorrected: Boolean, val ruleId: String, private
KDOC_NO_EMPTY_TAGS(false, "2.2.1", "no empty descriptions in tag blocks are allowed"),
KDOC_NO_DEPRECATED_TAG(true, "2.1.3", "KDoc doesn't support @deprecated tag, use @Deprecated annotation instead"),
KDOC_NO_CONSTRUCTOR_PROPERTY(true, "2.1.1", "all properties from the primary constructor should be documented in a @property tag in KDoc"),
KDOC_EXTRA_PROPERTY(false, "2.1.1", "There is property in KDos which is not present in the class"),
kentr0w marked this conversation as resolved.
Show resolved Hide resolved
KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT(true, "2.1.1", "replace comment before property with @property tag in class KDoc"),
HEADER_WRONG_FORMAT(true, "2.2.1", "file header comments should be properly formatted"),
HEADER_MISSING_OR_WRONG_COPYRIGHT(true, "2.2.1", "file header comment must include copyright information inside a block comment"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ import com.pinterest.ktlint.core.ast.ElementType.MODIFIER_LIST
import com.pinterest.ktlint.core.ast.ElementType.PRIMARY_CONSTRUCTOR
import com.pinterest.ktlint.core.ast.ElementType.PROPERTY
import com.pinterest.ktlint.core.ast.ElementType.VALUE_PARAMETER
import com.pinterest.ktlint.core.ast.ElementType.VALUE_PARAMETER_LIST
import com.pinterest.ktlint.core.ast.ElementType.VAL_KEYWORD
import com.pinterest.ktlint.core.ast.ElementType.VAR_KEYWORD
import com.pinterest.ktlint.core.ast.ElementType.WHITE_SPACE
import com.pinterest.ktlint.core.ast.parent
import org.cqfn.diktat.ruleset.constants.Warnings
import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_EXTRA_PROPERTY
import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_NO_CONSTRUCTOR_PROPERTY
import org.cqfn.diktat.ruleset.constants.Warnings.KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT
import org.cqfn.diktat.ruleset.constants.Warnings.MISSING_KDOC_TOP_LEVEL
Expand All @@ -47,7 +49,7 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl
import org.jetbrains.kotlin.com.intellij.psi.tree.TokenSet
import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtParameterList
import org.jetbrains.kotlin.psi.psiUtil.parents

/**
Expand Down Expand Up @@ -80,13 +82,27 @@ class KdocComments(private val configRules: List<RulesConfig>) : Rule("kdoc-comm
FILE -> checkTopLevelDoc(node)
CLASS -> checkClassElements(node)
VALUE_PARAMETER -> checkValueParameter(node)
VALUE_PARAMETER_LIST -> checkParameterList(node)
kentr0w marked this conversation as resolved.
Show resolved Hide resolved
else -> {
// this is a generated else block
}
}
}
}

private fun checkParameterList(node: ASTNode) {
val kdocBeforeClass = node.parent({ it.elementType == CLASS })?.findChildByType(KDOC) ?: return
val propertiesInKdoc = kdocBeforeClass.kDocTags()?.filter { it.knownTag == KDocKnownTag.PROPERTY}?.mapNotNull {it.getSubjectName()}
val propertyNames = (node.psi as KtParameterList).parameters.filter {
it.node.getFirstChildWithType(MODIFIER_LIST).isAccessibleOutside() }
kentr0w marked this conversation as resolved.
Show resolved Hide resolved
.mapNotNull { it.nameIdentifier?.text }
propertiesInKdoc?.let { kdocProperties ->
kentr0w marked this conversation as resolved.
Show resolved Hide resolved
kentr0w marked this conversation as resolved.
Show resolved Hide resolved
(kdocProperties - propertyNames).forEach {
KDOC_EXTRA_PROPERTY.warn(configRules, emitWarn, isFixMode, it, kdocBeforeClass.startOffset, node)
}
}
}

@Suppress("UnsafeCallOnNullableType", "TOO_LONG_FUNCTION")
private fun checkValueParameter(node: ASTNode) {
if (node.parents().none { it.elementType == PRIMARY_CONSTRUCTOR } ||
Expand Down
3 changes: 3 additions & 0 deletions diktat-rules/src/main/resources/diktat-analysis-huawei.yml
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,9 @@
# Checks that property in constructor doesn't contains comment
- name: KDOC_NO_CONSTRUCTOR_PROPERTY
enabled: true
# Checks that property in KDoc present in class
- name: KDOC_EXTRA_PROPERTY
enabled: true
# Checks that KDoc in constructor has property tag but with comment inside constructor
- name: KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT
enabled: true
Expand Down
3 changes: 3 additions & 0 deletions diktat-rules/src/main/resources/diktat-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,9 @@
# Checks that KDoc in constructor has property tag
- name: KDOC_NO_CONSTRUCTOR_PROPERTY
enabled: true
# Checks that property in KDoc present in class
- name: KDOC_EXTRA_PROPERTY
enabled: true
# Checks that KDoc in constructor has property tag but with comment inside constructor
- name: KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT
enabled: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ class KdocCommentsWarnTest : LintTestBase(::KdocComments) {
}

@Test
@Tag(WarningNames.KDOC_NO_CONSTRUCTOR_PROPERTY)
@Tags(Tag(WarningNames.KDOC_NO_CONSTRUCTOR_PROPERTY), Tag(WarningNames.KDOC_EXTRA_PROPERTY))
fun `no property kdoc`() {
lintMethod(
"""
Expand All @@ -416,6 +416,7 @@ class KdocCommentsWarnTest : LintTestBase(::KdocComments) {
| ) {
|}
""".trimMargin(),
LintError(1,1, ruleId, "${KDOC_EXTRA_PROPERTY.warnText()} Name", false),
LintError(5, 4, ruleId, "${KDOC_NO_CONSTRUCTOR_PROPERTY.warnText()} add <name> to KDoc", true)
)
}
Expand All @@ -435,4 +436,23 @@ class KdocCommentsWarnTest : LintTestBase(::KdocComments) {
LintError(2, 4, ruleId, "${KDOC_NO_CONSTRUCTOR_PROPERTY.warnText()} add <name> to KDoc", true)
)
}

@Test
@Tag(WarningNames.KDOC_EXTRA_PROPERTY)
fun `extra property in kdoc`() {
lintMethod(
"""
|/**
| * @property name bla
| * @property kek
| */
|class Example (
| val name: String,
| private val surname: String
| ) {
|}
""".trimMargin(),
LintError(1,1, ruleId, "${KDOC_EXTRA_PROPERTY.warnText()} kek", false)
)
}
}
1 change: 1 addition & 0 deletions info/available-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
| 2 | 2.3 | KDOC_NO_EMPTY_TAGS | Check: warns if KDoc tags have empty content | no | ||
| 2 | 2.3 | KDOC_NO_DEPRECATED_TAG | Check: warns if `@deprecated` is used in KDoc<br>Fix: adds `@Deprecated` annotation with message, removes tag | yes | |Annotation's `replaceWith` field can be filled too|
| 2 | 2.3 | KDOC_NO_CONSTRUCTOR_PROPERTY | Check: warns if there is no property tag inside KDoc before constructor | yes | -|
| 2 | 2.3 | KDOC_EXTRA_PROPERTY | Check: warns if there is property which doesn't provide in class | no | - | - |
kentr0w marked this conversation as resolved.
Show resolved Hide resolved
| 2 | 2.3 | KDOC_NO_CONSTRUCTOR_PROPERTY_WITH_COMMENT | Check: warns if there is comment before property in constructor | yes | -|
| 2 | 2.5 | KDOC_TRIVIAL_KDOC_ON_FUNCTION | Check: warns if KDoc contains single line with words 'return', 'get' or 'set' | no | - |
| 2 | 2.4 | HEADER_WRONG_FORMAT | Checks: warns if there is no newline after header KDoc<br>Fix: adds newline | yes | |Check if header is on the very top of file. It's hard to determine when it's not.|
Expand Down