Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.plugin
import org.jetbrains.dokka.plugability.querySingle
import org.jetbrains.dokka.analysis.kotlin.internal.InternalKotlinAnalysisPlugin
import org.jetbrains.dokka.model.doc.Description
import org.jetbrains.dokka.model.doc.DocumentationNode
import org.jetbrains.dokka.model.doc.Property

public val jvmNameProvider: JvmNameProvider = JvmNameProvider()
internal const val OBJECT_INSTANCE_NAME = "INSTANCE"
Expand All @@ -32,6 +35,33 @@ internal val DProperty.isJvmField: Boolean
internal val DFunction.isJvmStatic: Boolean
get() = jvmStatic() != null

/**
* Converts any `@property` tags into descriptions for the Java accessors
*/
private fun transformAccessorDocs(docs: SourceSetDependent<DocumentationNode>): SourceSetDependent<DocumentationNode> {
return docs.mapValues { (_, node) ->
node.copy(
children = node.children.map { tag ->
if (tag is Property) {
Description(tag.root)
} else {
tag
}
}
)
}
}

internal val DProperty.documentedGetter: DFunction?
get() = getter?.copy(
documentation = transformAccessorDocs(getter?.documentation?.takeIf { it.isNotEmpty() } ?: documentation)
)

internal val DProperty.documentedSetter: DFunction?
get() = setter?.copy(
documentation = transformAccessorDocs(setter?.documentation?.takeIf { it.isNotEmpty() } ?: documentation)
)

private fun DProperty.hasModifier(modifier: ExtraModifiers.KotlinOnlyModifiers): Boolean =
extra[AdditionalModifiers]
?.content
Expand Down Expand Up @@ -306,7 +336,7 @@ public class KotlinToJavaConverter(
internal fun DClass.functionsInJava(): List<DFunction> =
properties
.filter { !it.isJvmField && !it.hasJvmSynthetic() }
.flatMap { property -> listOfNotNull(property.getter, property.setter) }
.flatMap { property -> listOfNotNull(property.documentedGetter, property.documentedSetter) }
.plus(functions)
.plus(companion.staticFunctionsForJava())
.filterNot { it.hasJvmSynthetic() }
Expand Down Expand Up @@ -370,7 +400,7 @@ public class KotlinToJavaConverter(
.plus(
properties
.filter { !it.isJvmField && !it.hasJvmSynthetic() }
.flatMap { listOf(it.getter, it.setter) }
.flatMap { listOf(it.documentedGetter, it.documentedSetter) }
)
.filterNotNull()
.filterNot { it.hasJvmSynthetic() }
Expand All @@ -396,7 +426,7 @@ public class KotlinToJavaConverter(
properties
.filterNot { it in excludedProps }
.filter { !it.isJvmField && !it.isConst && !it.isLateInit && !it.hasJvmSynthetic() }
.flatMap { listOf(it.getter, it.setter) }
.flatMap { listOf(it.documentedGetter, it.documentedSetter) }
)
.filterNotNull()
.filterNot { it in excludedFunctions }
Expand Down Expand Up @@ -436,7 +466,7 @@ public class KotlinToJavaConverter(
.plus(
properties
.filter { it.jvmField() == null && !it.hasJvmSynthetic() }
.flatMap { listOf(it.getter, it.setter) }
.flatMap { listOf(it.documentedGetter, it.documentedSetter) }
)
.filterNotNull()
.filterNot { it.hasJvmSynthetic() }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

package kotlinAsJavaPlugin

import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest
import org.jetbrains.dokka.model.Documentable
import org.jetbrains.dokka.model.doc.DocTag
import org.jetbrains.dokka.model.doc.Text
import kotlin.test.*

class PropertyTest : BaseAbstractTest() {
val configuration = dokkaConfiguration {
sourceSets {
sourceSet {
sourceRoots = listOf("src/")
classpath += jvmStdlibPath!!
}
}
}

@Test
fun `property accessors should inherit doc`(){
testInline(
"""
|/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
|package kotlinAsJavaPlugin
|class MyClass {
| /**
| * Some doc
| */
| var property: String = TODO()
|}
""".trimMargin(),
configuration,
) {
documentablesTransformationStage = { module ->
val classLike = module.packages.flatMap { it.classlikes }.first()
val getter = classLike.functions.firstOrNull { it.name == "getProperty" }
val setter = classLike.functions.firstOrNull { it.name == "setProperty" }
assertNotNull(getter)
assertNotNull(setter)

assertEquals("Some doc", getter.docText)
assertEquals("Some doc", setter.docText)
}
}

testInline(
"""
|/src/main/kotlin/kotlinAsJavaPlugin/sample.kt
|package kotlinAsJavaPlugin
|/**
|* @property property Some doc
|*/
|class MyClass {
| var property: String = TODO()
|}
""".trimMargin(),
configuration,
) {
documentablesTransformationStage = { module ->
val classLike = module.packages.flatMap { it.classlikes }.first()
val getter = classLike.functions.firstOrNull { it.name == "getProperty" }
val setter = classLike.functions.firstOrNull { it.name == "setProperty" }
assertNotNull(getter)
assertNotNull(setter)

assertEquals("Some doc", getter.docText)
assertEquals("Some doc", setter.docText)
}
}
}
}

private val Documentable.docText: String
get() = this.documentation.values
.flatMap { it.children }
.map { it.root }
.joinToString("") { it.text }

private val DocTag.text: String
get() = if (this is Text) body else children.joinToString("") { it.text }
Loading