Add option for OutdatedDocumentation to allow param in constructor pr… (#4453)

This commit is contained in:
Matej Drobnič
2022-01-07 12:51:57 +01:00
committed by GitHub
parent 06698889d5
commit b274fea74f
3 changed files with 90 additions and 6 deletions

View File

@@ -66,6 +66,7 @@ comments:
active: false
matchTypeParameters: true
matchDeclarationsOrder: true
allowParamOnConstructorProperties: false
UndocumentedPublicClass:
active: false
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']

View File

@@ -76,6 +76,9 @@ class OutdatedDocumentation(config: Config = Config.empty) : Rule(config) {
@Configuration("if the order of declarations should be preserved")
private val matchDeclarationsOrder: Boolean by config(true)
@Configuration("if we allow constructor parameters to be marked as @param instead of @property")
private val allowParamOnConstructorProperties: Boolean by config(false)
override fun visitClass(klass: KtClass) {
super.visitClass(klass)
reportIfDocumentationIsOutdated(klass) { getClassDeclarations(klass) }
@@ -119,7 +122,15 @@ class OutdatedDocumentation(config: Config = Config.empty) : Rule(config) {
private fun getDeclarationsForValueParameters(valueParameters: List<KtParameter>): List<Declaration> {
return valueParameters.mapNotNull {
it.name?.let { name ->
val type = if (it.isPropertyParameter()) DeclarationType.PROPERTY else DeclarationType.PARAM
val type = if (it.isPropertyParameter()) {
if (allowParamOnConstructorProperties) {
DeclarationType.ANY
} else {
DeclarationType.PROPERTY
}
} else {
DeclarationType.PARAM
}
Declaration(name, type)
}
}
@@ -166,11 +177,21 @@ class OutdatedDocumentation(config: Config = Config.empty) : Rule(config) {
}
private fun declarationsMatch(doc: List<Declaration>, element: List<Declaration>): Boolean {
return if (matchDeclarationsOrder) {
doc == element
} else {
doc.sortedBy { it.name } == element.sortedBy { it.name }
if (doc.size != element.size) {
return false
}
val zippedElements = if (matchDeclarationsOrder) {
doc.zip(element)
} else {
doc.sortedBy { it.name }.zip(element.sortedBy { it.name })
}
return zippedElements.all { (doc, element) -> declarationMatches(doc, element) }
}
private fun declarationMatches(doc: Declaration, element: Declaration): Boolean {
return element.name == doc.name && (element.type == DeclarationType.ANY || element.type == doc.type)
}
private fun reportCodeSmell(element: KtNamedDeclaration) {
@@ -193,6 +214,6 @@ class OutdatedDocumentation(config: Config = Config.empty) : Rule(config) {
)
enum class DeclarationType {
PARAM, PROPERTY
PARAM, PROPERTY, ANY
}
}

View File

@@ -364,5 +364,67 @@ class OutdatedDocumentationSpec : Spek({
assertThat(configuredSubject.compileAndLint(incorrectDeclarationsOrderWithType)).isEmpty()
}
}
describe("configuration allowParamOnConstructorProperties") {
val configuredSubject by memoized {
OutdatedDocumentation(TestConfig(mapOf("allowParamOnConstructorProperties" to "true")))
}
it("should not report when property is documented as param") {
val propertyAsParam = """
/**
* @param someParam Description of param
* @param someProp Description of property
*/
class MyClass(someParam: String, val someProp: String)
"""
assertThat(configuredSubject.compileAndLint(propertyAsParam)).isEmpty()
}
it("should not report when property is documented as property") {
val propertyAsParam = """
/**
* @param someParam Description of param
* @property someProp Description of property
*/
class MyClass(someParam: String, val someProp: String)
"""
assertThat(configuredSubject.compileAndLint(propertyAsParam)).isEmpty()
}
}
describe("configuration matchDeclarationsOrder and allowParamOnConstructorProperties") {
val configuredSubject by memoized {
OutdatedDocumentation(
TestConfig(
mapOf(
"matchDeclarationsOrder" to "false",
"allowParamOnConstructorProperties" to "true"
)
)
)
}
it("should not report when property is documented as param") {
val propertyAsParam = """
/**
* @param someParam Description of param
* @param someProp Description of property
*/
class MyClass(someParam: String, val someProp: String)
"""
assertThat(configuredSubject.compileAndLint(propertyAsParam)).isEmpty()
}
it("should not report when property is documented as property") {
val propertyAsParam = """
/**
* @param someParam Description of param
* @property someProp Description of property
*/
class MyClass(someParam: String, val someProp: String)
"""
assertThat(configuredSubject.compileAndLint(propertyAsParam)).isEmpty()
}
}
}
})