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

Fix wrong docs on DProperty #1671

Merged
merged 1 commit into from
Dec 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions plugins/base/src/main/kotlin/parsers/MarkdownParser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -452,8 +452,9 @@ open class MarkdownParser(
if (link is DocumentationLink) link.dri else null
}

val allTags = listOf(kDocTag) + if(kDocTag.canHaveParent()) getAllKDocTags(findParent(kDocTag)) else emptyList()
DocumentationNode(
(listOf(kDocTag) + getAllKDocTags(findParent(kDocTag))).map {
allTags.map {
when (it.knownTag) {
null -> if (it.name == null) Description(parseStringToDocNode(it.getContent())) else CustomTagWrapper(
parseStringToDocNode(it.getContent()),
Expand Down Expand Up @@ -511,7 +512,9 @@ open class MarkdownParser(
fun DRI.fqName(): String? = "$packageName.$classNames".takeIf { packageName != null && classNames != null }

private fun findParent(kDoc: PsiElement): PsiElement =
if (kDoc is KDocSection) findParent(kDoc.parent) else kDoc
if (kDoc.canHaveParent()) findParent(kDoc.parent) else kDoc

private fun PsiElement.canHaveParent(): Boolean = this is KDocSection && knownTag != KDocKnownTag.PROPERTY

private fun getAllKDocTags(kDocImpl: PsiElement): List<KDocTag> =
kDocImpl.children.filterIsInstance<KDocTag>().filterNot { it is KDocSection } + kDocImpl.children.flatMap {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ private class DokkaDescriptorVisitor(
private suspend fun List<ClassDescriptor>.visitEnumEntries(parent: DRIWithPlatformInfo): List<DEnumEntry> =
coroutineScope { parallelMap { visitEnumEntryDescriptor(it, parent) } }

private suspend fun DeclarationDescriptor.resolveDescriptorData(): SourceSetDependent<DocumentationNode> =
private fun DeclarationDescriptor.resolveDescriptorData(): SourceSetDependent<DocumentationNode> =
getDocumentation()?.toSourceSetDependent() ?: emptyMap()


Expand Down Expand Up @@ -831,7 +831,7 @@ private class DokkaDescriptorVisitor(
org.jetbrains.kotlin.types.Variance.OUT_VARIANCE -> Covariance(this)
}

private suspend fun DeclarationDescriptor.getDocumentation() = findKDoc().let {
private fun DeclarationDescriptor.getDocumentation() = findKDoc().let {
MarkdownParser.parseFromKDocTag(
kDocTag = it,
externalDri = { link: String ->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
package content.properties

import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest
import org.jetbrains.dokka.model.DClass
import org.jetbrains.dokka.model.dfs
import org.jetbrains.dokka.model.doc.*
import org.jetbrains.dokka.pages.ClasslikePageNode
import org.jetbrains.dokka.pages.RootPageNode
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals

class ContentForClassWithParamsAndPropertiesTest : BaseAbstractTest() {
private val testConfiguration = dokkaConfiguration {
sourceSets {
sourceSet {
sourceRoots = listOf("src/")
analysisPlatform = "jvm"
}
}
}

@Test
fun `should work for a simple property`() {
propertyTest { rootPage ->
val node = rootPage.dfs { it.name == "LoadInitialParams" } as ClasslikePageNode
val actualDocsForPlaceholdersEnabled =
(node.documentable as DClass).constructors.first().parameters.find { it.name == "placeholdersEnabled" }
?.documentation?.entries?.first()?.value
assertEquals(DocumentationNode(listOf(docsForPlaceholdersEnabled)), actualDocsForPlaceholdersEnabled)
}
}

@Test
fun `should work for a simple with linebreak`() {
propertyTest { rootPage ->
val node = rootPage.dfs { it.name == "LoadInitialParams" } as ClasslikePageNode
val actualDocsForRequestedLoadSize =
(node.documentable as DClass).constructors.first().parameters.find { it.name == "requestedLoadSize" }
?.documentation?.entries?.first()?.value
assertEquals(DocumentationNode(listOf(docsForRequestedLoadSize)), actualDocsForRequestedLoadSize)
}
}

@Test
fun `should work with multiline property inline code`() {
propertyTest { rootPage ->
val node = rootPage.dfs { it.name == "LoadInitialParams" } as ClasslikePageNode

val actualDocsForRequestedInitialKey =
(node.documentable as DClass).constructors.first().parameters.find { it.name == "requestedInitialKey" }
?.documentation?.entries?.first()?.value
assertEquals(DocumentationNode(listOf(docsForRequestedInitialKey)), actualDocsForRequestedInitialKey)
}
}

@Test
fun `constructor should only the param and constructor tags`() {
propertyTest { rootPage ->
val constructorDocs = Description(
root = CustomDocTag(
children = listOf(
P(
children = listOf(
Text("Creates an empty group.")
)
)
),
emptyMap(), "MARKDOWN_FILE"
)
)
val node = rootPage.dfs { it.name == "LoadInitialParams" } as ClasslikePageNode

val actualDocs =
(node.documentable as DClass).constructors.first().documentation.entries.first().value
assertEquals(DocumentationNode(listOf(constructorDocs, docsForParam)), actualDocs)
}
}

@Test
fun `class should have all tags`() {
propertyTest { rootPage ->
val ownDescription = Description(
root = CustomDocTag(
children = listOf(
P(
children = listOf(
Text("Holder object for inputs to loadInitial.")
)
)
),
emptyMap(), "MARKDOWN_FILE"
)
)
val node = rootPage.dfs { it.name == "LoadInitialParams" } as ClasslikePageNode

val actualDocs =
(node.documentable as DClass).documentation.entries.first().value
assertEquals(
DocumentationNode(
listOf(
ownDescription,
docsForParam,
docsForRequestedInitialKey,
docsForRequestedLoadSize,
docsForPlaceholdersEnabled,
docsForConstructor
)
),
actualDocs
)
}
}

@Test
fun `property should also work with own docs that override the param tag`() {
propertyTest { rootPage ->
val ownDescription = Description(
root = CustomDocTag(
children = listOf(
P(
children = listOf(
Text("Own docs")
)
)
),
emptyMap(), "MARKDOWN_FILE"
)
)
val node = rootPage.dfs { it.name == "ItemKeyedDataSource" } as ClasslikePageNode

val actualDocs =
(node.documentable as DClass).properties.first().documentation.entries.first().value
assertEquals(
DocumentationNode(listOf(ownDescription)),
actualDocs
)
}
}


private fun propertyTest(block: (RootPageNode) -> Unit) {
testInline(
""" |/src/main/kotlin/test/source.kt
|package test
|/**
| * @property tested Docs from class
| */
|abstract class ItemKeyedDataSource<Key : Any, Value : Any> : DataSource<Key, Value>(ITEM_KEYED) {
| /**
| * Own docs
| */
| val tested = ""
|
| /**
| * Holder object for inputs to loadInitial.
| *
| * @param Key Type of data used to query Value types out of the DataSource.
| * @property requestedInitialKey Load items around this key, or at the beginning of the data set
| * if `null` is passed.
| *
| * Note that this key is generally a hint, and may be ignored if you want to always load from
| * the beginning.
| * @property requestedLoadSize Requested number of items to load.
| *
| * Note that this may be larger than available data.
| * @property placeholdersEnabled Defines whether placeholders are enabled, and whether the
| * loaded total count will be ignored.
| *
| * @constructor Creates an empty group.
| */
| open class LoadInitialParams<Key : Any>(
| @JvmField
| val requestedInitialKey: Key?,
| @JvmField
| val requestedLoadSize: Int,
| @JvmField
| val placeholdersEnabled: Boolean
| )
|}""".trimIndent(), testConfiguration
) {
pagesGenerationStage = block
}
}

private val docsForPlaceholdersEnabled = Property(
root = CustomDocTag(
listOf(
P(
children = listOf(
Text("Defines whether placeholders are enabled, and whether the loaded total count will be ignored.")
)
)
), emptyMap(), "MARKDOWN_FILE"
),
name = "placeholdersEnabled"
)

private val docsForRequestedInitialKey = Property(
root = CustomDocTag(
listOf(
P(
children = listOf(
Text("Load items around this key, or at the beginning of the data set if "),
CodeInline(
listOf(
Text("null")
)
),
Text(" is passed.")
),
params = emptyMap()
),
P(
children = listOf(
Text("Note that this key is generally a hint, and may be ignored if you want to always load from the beginning.")
)
)
), emptyMap(), "MARKDOWN_FILE"
),
name = "requestedInitialKey"
)

private val docsForRequestedLoadSize = Property(
root = CustomDocTag(
listOf(
P(
children = listOf(
Text("Requested number of items to load.")
)
),
P(
children = listOf(
Text("Note that this may be larger than available data.")
)
)
), emptyMap(), "MARKDOWN_FILE"
),
name = "requestedLoadSize"
)

private val docsForConstructor = Constructor(
root = CustomDocTag(
children = listOf(
P(
children = listOf(
Text("Creates an empty group.")
)
)
),
emptyMap(), "MARKDOWN_FILE"
)
)

private val docsForParam = Param(
root = CustomDocTag(
children = listOf(
P(
children = listOf(
Text("Type of data used to query Value types out of the DataSource.")
)
)
),
emptyMap(), "MARKDOWN_FILE"
),
name = "Key"
)
}