Skip to content

Commit

Permalink
Do not find javadoc for non-JVM source set (#3346)
Browse files Browse the repository at this point in the history
* Add test

* Do not find javadoc for non-JVM source set

* [K2] Add javadoc parser for external documentable Provider
  • Loading branch information
vmishenev authored Nov 22, 2023
1 parent 04623bf commit 610b552
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.intellij.psi.PsiNamedElement
import com.intellij.psi.util.PsiLiteralUtil.*
import kotlinx.coroutines.*
import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
import org.jetbrains.dokka.Platform
import org.jetbrains.dokka.analysis.java.JavaAnalysisPlugin
import org.jetbrains.dokka.analysis.java.parsers.JavadocParser
import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.CompilerDescriptorAnalysisPlugin
Expand Down Expand Up @@ -98,11 +99,13 @@ internal class DefaultDescriptorToDocumentableTranslator(
.mapNotNull { analysisContext.resolveSession.getPackageFragment(it) }
.toList()

val javadocParser = JavadocParser(
docCommentParsers = context.plugin<JavaAnalysisPlugin>().query { docCommentParsers },
docCommentFinder = context.plugin<JavaAnalysisPlugin>().docCommentFinder
)

val javadocParser =
if (sourceSet.analysisPlatform == Platform.jvm)
JavadocParser(
docCommentParsers = context.plugin<JavaAnalysisPlugin>().query { docCommentParsers },
docCommentFinder = context.plugin<JavaAnalysisPlugin>().docCommentFinder
)
else null

return DokkaDescriptorVisitor(sourceSet, kdocFinder, kotlinAnalysis[sourceSet], context.logger, javadocParser).run {
packageFragments.parallelMap {
Expand All @@ -128,10 +131,13 @@ internal class DefaultDescriptorToDocumentableTranslator(
override fun translateClassDescriptor(descriptor: ClassDescriptor, sourceSet: DokkaSourceSet): DClasslike {
val driInfo = DRI.from(descriptor.parents.first()).withEmptyInfo()

val javadocParser = JavadocParser(
docCommentParsers = context.plugin<JavaAnalysisPlugin>().query { docCommentParsers },
docCommentFinder = context.plugin<JavaAnalysisPlugin>().docCommentFinder
)
val javadocParser =
if (sourceSet.analysisPlatform == Platform.jvm)
JavadocParser(
docCommentParsers = context.plugin<JavaAnalysisPlugin>().query { docCommentParsers },
docCommentFinder = context.plugin<JavaAnalysisPlugin>().docCommentFinder
)
else null

return newSingleThreadContext("Generating documentable model of classlike").use { coroutineContext -> // see https://github.com/Kotlin/dokka/issues/3151
runBlocking(coroutineContext) {
Expand All @@ -149,12 +155,15 @@ internal data class DRIWithPlatformInfo(

internal fun DRI.withEmptyInfo() = DRIWithPlatformInfo(this, emptyMap())

/**
* @param javadocParser can be null for non JVM platform
*/
private class DokkaDescriptorVisitor(
private val sourceSet: DokkaSourceSet,
private val kDocFinder: KDocFinder,
private val analysisContext: AnalysisContext,
private val logger: DokkaLogger,
private val javadocParser: JavadocParser
private val javadocParser: JavadocParser? = null
) {
private val syntheticDocProvider = SyntheticDescriptorDocumentationProvider(kDocFinder, sourceSet)

Expand Down Expand Up @@ -1080,16 +1089,16 @@ private class DokkaDescriptorVisitor(
else it
}
)
} ?: getJavaDocs())?.takeIf { it.children.isNotEmpty() }
} ?: javadocParser?.getJavaDocs(this))?.takeIf { it.children.isNotEmpty() }
}

private fun DeclarationDescriptor.getJavaDocs(): DocumentationNode? {
val overriddenDescriptors = (this as? CallableDescriptor)?.overriddenDescriptors ?: emptyList()
val allDescriptors = overriddenDescriptors + listOf(this)
private fun JavadocParser.getJavaDocs(declarationDescriptor: DeclarationDescriptor): DocumentationNode? {
val overriddenDescriptors = (declarationDescriptor as? CallableDescriptor)?.overriddenDescriptors ?: emptyList()
val allDescriptors = overriddenDescriptors + listOf(declarationDescriptor)
return allDescriptors
.mapNotNull { it.findPsi() as? PsiNamedElement }
.firstOrNull()
?.let { javadocParser.parseDocumentation(it) }
?.let { parseDocumentation(it) }
}

private suspend fun ClassDescriptor.companion(dri: DRIWithPlatformInfo): DObject? = companionObjectDescriptor?.let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
package org.jetbrains.dokka.analysis.kotlin.symbols.services

import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
import org.jetbrains.dokka.Platform
import org.jetbrains.dokka.analysis.java.JavaAnalysisPlugin
import org.jetbrains.dokka.analysis.java.parsers.JavadocParser
import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.SymbolsAnalysisPlugin
import org.jetbrains.dokka.analysis.kotlin.symbols.translators.DokkaSymbolVisitor
import org.jetbrains.dokka.analysis.kotlin.symbols.translators.getClassIdFromDRI
Expand All @@ -17,6 +20,7 @@ import org.jetbrains.dokka.plugability.querySingle
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
import org.jetbrains.dokka.analysis.kotlin.internal.ExternalDocumentablesProvider
import org.jetbrains.dokka.plugability.query

internal class SymbolExternalDocumentablesProvider(val context: DokkaContext) : ExternalDocumentablesProvider {
private val kotlinAnalysis = context.plugin<SymbolsAnalysisPlugin>().querySingle { kotlinAnalysis }
Expand All @@ -26,7 +30,14 @@ internal class SymbolExternalDocumentablesProvider(val context: DokkaContext) :

return analyze(kotlinAnalysis.getModule(sourceSet)) {
val symbol = getClassOrObjectSymbolByClassId(classId) as? KtNamedClassOrObjectSymbol?: return@analyze null
val translator = DokkaSymbolVisitor(sourceSet, sourceSet.displayName, kotlinAnalysis, logger = context.logger)
val javadocParser =
if (sourceSet.analysisPlatform == Platform.jvm)
JavadocParser(
docCommentParsers = context.plugin<JavaAnalysisPlugin>().query { docCommentParsers },
docCommentFinder = context.plugin<JavaAnalysisPlugin>().docCommentFinder
)
else null
val translator = DokkaSymbolVisitor(sourceSet, sourceSet.displayName, kotlinAnalysis, logger = context.logger, javadocParser)

val parentDRI = symbol.getContainingSymbol()?.let { getDRIFromSymbol(it) } ?: /* top level */ DRI(dri.packageName)
with(translator) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package org.jetbrains.dokka.analysis.kotlin.symbols.translators
import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.*
import com.intellij.psi.util.PsiLiteralUtil
import org.jetbrains.dokka.DokkaConfiguration
import org.jetbrains.dokka.Platform
import org.jetbrains.dokka.analysis.java.JavaAnalysisPlugin
import org.jetbrains.dokka.analysis.java.parsers.JavadocParser
import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.getGeneratedKDocDocumentationFrom
Expand Down Expand Up @@ -65,7 +66,7 @@ internal class DefaultSymbolToDocumentableTranslator(context: DokkaContext) : As
moduleName = context.configuration.moduleName,
analysisContext = analysisContext,
logger = context.logger,
javadocParser = javadocParser
javadocParser = if(sourceSet.analysisPlatform == Platform.jvm) javadocParser else null
).visitModule()
}
}
Expand All @@ -79,6 +80,8 @@ internal fun <T : Bound> T.wrapWithVariance(variance: org.jetbrains.kotlin.types

/**
* Maps [KtSymbol] to Documentable model [Documentable]
*
* @param javadocParser can be null for non JVM platform
*/
internal class DokkaSymbolVisitor(
private val sourceSet: DokkaConfiguration.DokkaSourceSet,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

package model

import org.jetbrains.dokka.Platform
import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.links.PointingToDeclaration
Expand All @@ -26,6 +27,48 @@ class MultiLanguageInheritanceTest : BaseAbstractTest() {
}
}

@Test
fun `should not try to find javadoc for non JVM source set`() {
// Bug #3209 is actual for Dokka K1
// Technical note: `KtPropertyAccessor`, i.e. `<get-withHintType>`, is not KtCallableDeclaration so `findKDoc` returns null
// Meanwhile, `getJavaDocs()` for KtPropertyAccessor tries to unexpectedly parse the KDoc documentation of property, i.e. `withHintType`

val nonJvmConfiguration = dokkaConfiguration {
suppressObviousFunctions = false
sourceSets {
sourceSet {
analysisPlatform = Platform.common.key
sourceRoots = listOf("src/main/kotlin")
}
}
}

testInline(
"""
|/src/main/kotlin/sample/Parent.kt
|package sample
|
|/**
| * Sample description from parent
| */
|interface Parent {
| /**
| * Sample description from parent
| */
| val withHintType: String
|}
|
|/src/main/kotlin/sample/Child.kt
|package sample
|public class Child : Parent {
| override val withHintType: String
| get() = ""
|}
""".trimIndent(),
nonJvmConfiguration
) { }
}

@Test
fun `from java to kotlin`() {
testInline(
Expand Down

0 comments on commit 610b552

Please sign in to comment.