Skip to content

Commit

Permalink
Use resolveKDocTextLink to resolve sample links
Browse files Browse the repository at this point in the history
  • Loading branch information
IgnatBeresnev committed Oct 31, 2023
1 parent 147b928 commit 92aa97a
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ internal fun KtAnalysisSession.getKDocDocumentationFrom(symbol: KtSymbol, logger

parseFromKDocTag(
kDocTag = kDocContent.contentTag,
externalDri = { link -> resolveKDocLink(link).ifUnresolved { logger.logUnresolvedLink(link.getLinkText(), kdocLocation) } },
externalDri = { link -> resolveKDocLinkDRI(link).ifUnresolved { logger.logUnresolvedLink(link.getLinkText(), kdocLocation) } },
kdocLocation = kdocLocation
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import org.jetbrains.dokka.analysis.kotlin.symbols.translators.getDRIFromSymbol
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.utilities.DokkaLogger
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink
Expand All @@ -34,7 +35,23 @@ internal inline fun DRI?.ifUnresolved(action: () -> Unit): DRI? = this ?: run {
*
* @return [DRI] or null if the [link] is unresolved
*/
internal fun KtAnalysisSession.resolveKDocTextLink(link: String, context: PsiElement? = null): DRI? {
internal fun KtAnalysisSession.resolveKDocTextLinkDRI(link: String, context: PsiElement? = null): DRI? {
val kDocLink = createKDocLink(link, context)
return kDocLink?.let { resolveKDocLinkDRI(it) }
}

/**
* If the [link] is ambiguous, i.e. leads to more than one declaration,
* it returns deterministically any declaration.
*
* @return [KtSymbol] or null if the [link] is unresolved
*/
internal fun KtAnalysisSession.resolveKDocTextLinkSymbol(link: String, context: PsiElement? = null): KtSymbol? {
val kDocLink = createKDocLink(link, context)
return kDocLink?.let { resolveToSymbol(it) }
}

private fun KtAnalysisSession.createKDocLink(link: String, context: PsiElement? = null): KDocLink? {
val psiFactory = context?.let { KtPsiFactory.contextual(it) } ?: KtPsiFactory(this.useSiteModule.project)
val kDoc = psiFactory.createComment(
"""
Expand All @@ -43,8 +60,8 @@ internal fun KtAnalysisSession.resolveKDocTextLink(link: String, context: PsiEle
*/
""".trimIndent()
) as? KDoc
val kDocLink = kDoc?.getDefaultSection()?.children?.filterIsInstance<KDocLink>()?.singleOrNull()
return kDocLink?.let { resolveKDocLink(it) }

return kDoc?.getDefaultSection()?.children?.filterIsInstance<KDocLink>()?.singleOrNull()
}

/**
Expand All @@ -53,9 +70,13 @@ internal fun KtAnalysisSession.resolveKDocTextLink(link: String, context: PsiEle
*
* @return [DRI] or null if the [link] is unresolved
*/
internal fun KtAnalysisSession.resolveKDocLink(link: KDocLink): DRI? {
val lastNameSegment = link.children.filterIsInstance<KDocName>().lastOrNull()
val linkedSymbol = lastNameSegment?.mainReference?.resolveToSymbols()?.firstOrNull()
internal fun KtAnalysisSession.resolveKDocLinkDRI(link: KDocLink): DRI? {
val linkedSymbol = resolveToSymbol(link)
return if (linkedSymbol == null) null
else getDRIFromSymbol(linkedSymbol)
}

private fun KtAnalysisSession.resolveToSymbol(kDocLink: KDocLink): KtSymbol? {
val lastNameSegment = kDocLink.children.filterIsInstance<KDocName>().lastOrNull()
return lastNameSegment?.mainReference?.resolveToSymbols()?.firstOrNull()
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ internal fun KtAnalysisSession.getGeneratedKDocDocumentationFrom(symbol: KtSymbo
private fun KtAnalysisSession.loadTemplate(filePath: String): DocumentationNode? {
val kdoc = loadContent(filePath) ?: return null
val externalDriProvider = { link: String ->
resolveKDocTextLink(link)
resolveKDocTextLinkDRI(link)
}

val parser = MarkdownParser(externalDriProvider, filePath)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import org.jetbrains.dokka.analysis.java.parsers.DocCommentParser
import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.*
import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.logUnresolvedLink
import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.parseFromKDocTag
import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.resolveKDocLink
import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.resolveKDocLinkDRI
import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.SymbolsAnalysisPlugin
import org.jetbrains.dokka.model.doc.DocumentationNode
import org.jetbrains.dokka.plugability.DokkaContext
Expand Down Expand Up @@ -42,7 +42,7 @@ internal class KotlinDocCommentParser(
return analyze(kotlinAnalysis[sourceSet].mainModule) {
parseFromKDocTag(
kDocTag = element.comment,
externalDri = { link -> resolveKDocLink(link).ifUnresolved { context.logger.logUnresolvedLink(link.getLinkText(), elementName) } },
externalDri = { link -> resolveKDocLinkDRI(link).ifUnresolved { context.logger.logUnresolvedLink(link.getLinkText(), elementName) } },
kdocLocation = null,
parseWithChildren = parseWithChildren
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.logUnresolvedLink
import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.KotlinAnalysis
import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.moduledocs.ModuleAndPackageDocumentation.Classifier.Module
import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.moduledocs.ModuleAndPackageDocumentation.Classifier.Package
import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.resolveKDocTextLink
import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.resolveKDocTextLinkDRI
import org.jetbrains.dokka.analysis.markdown.jb.MarkdownParser
import org.jetbrains.dokka.model.doc.DocumentationNode
import org.jetbrains.dokka.utilities.DokkaLogger
Expand Down Expand Up @@ -47,7 +47,7 @@ internal fun ModuleAndPackageDocumentationParsingContext(
MarkdownParser(
externalDri = { link ->
analyze(analysisContext.mainModule) {
resolveKDocTextLink(
resolveKDocTextLinkDRI(
link,
contextPsi
).ifUnresolved {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,18 @@ import com.intellij.psi.PsiElement
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.plugin
import org.jetbrains.dokka.plugability.querySingle
import org.jetbrains.dokka.analysis.kotlin.sample.SampleAnalysisEnvironment
import org.jetbrains.dokka.analysis.kotlin.sample.SampleAnalysisEnvironmentCreator
import org.jetbrains.dokka.analysis.kotlin.sample.SampleSnippet
import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.resolveKDocTextLinkSymbol
import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.KotlinAnalysis
import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.SamplesKotlinAnalysis
import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.SymbolsAnalysisPlugin
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.plugin
import org.jetbrains.dokka.plugability.querySingle
import org.jetbrains.dokka.utilities.DokkaLogger
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtBlockExpression
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
import org.jetbrains.kotlin.psi.KtFile
Expand Down Expand Up @@ -79,13 +78,7 @@ private class SymbolSampleAnalysisEnvironment(
private fun findPsiElement(sourceSet: DokkaSourceSet, fqLink: String): PsiElement? {
val analysisContext = kotlinAnalysis[sourceSet]
return analyze(analysisContext.mainModule) {
// TODO the logic below is incorrect as it assumes the samples can only link to top-level functions.
// TODO should be corrected to be able to work with functions inside classes. See Descriptor's impl.
val isRootPackage = !fqLink.contains('.')
val supposedFunctionName = if (isRootPackage) fqLink else fqLink.substringAfterLast(".")
val supposedPackageName = if (isRootPackage) "" else fqLink.substringBeforeLast(".")

getTopLevelCallableSymbols(FqName(supposedPackageName), Name.identifier(supposedFunctionName)).firstOrNull()?.psi
resolveKDocTextLinkSymbol(fqLink)?.psi
}
}

Expand Down

0 comments on commit 92aa97a

Please sign in to comment.