Skip to content

Commit c8183f8

Browse files
committed
Enhance logging for unresolved KDoc links
Print location in an IDE-recognizable format
1 parent 31c9c24 commit c8183f8

File tree

5 files changed

+62
-6
lines changed

5 files changed

+62
-6
lines changed

dokka-subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/KDocProvider.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package org.jetbrains.dokka.analysis.kotlin.symbols.kdoc
77
import com.intellij.psi.PsiNamedElement
88
import org.jetbrains.dokka.DokkaConfiguration
99
import org.jetbrains.dokka.analysis.java.parsers.JavadocParser
10+
import org.jetbrains.dokka.analysis.kotlin.symbols.utils.getLocation
1011
import org.jetbrains.dokka.model.doc.DocumentationNode
1112
import org.jetbrains.dokka.utilities.DokkaLogger
1213
import org.jetbrains.kotlin.analysis.api.KaNonPublicApi
@@ -62,7 +63,7 @@ internal fun KaSession.getKDocDocumentationFrom(
6263

6364
parseFromKDocTag(
6465
kDocTag = kDocContent.primaryTag,
65-
externalDri = { resolveKDocLink(it, kdocLocation, logger, sourceSet) },
66+
externalDri = { resolveKDocLink(it, getLocation(it) ?: kdocLocation, logger, sourceSet) },
6667
kdocLocation = kdocLocation
6768
)
6869
}

dokka-subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/java/KotlinDocCommentParser.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import org.jetbrains.dokka.analysis.java.parsers.DocCommentParser
1111
import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.parseFromKDocTag
1212
import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.resolveKDocLink
1313
import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.SymbolsAnalysisPlugin
14+
import org.jetbrains.dokka.analysis.kotlin.symbols.utils.getLocation
1415
import org.jetbrains.dokka.model.doc.DocumentationNode
1516
import org.jetbrains.dokka.plugability.DokkaContext
1617
import org.jetbrains.dokka.plugability.plugin
@@ -40,7 +41,7 @@ internal class KotlinDocCommentParser(
4041
return analyze(kotlinAnalysis.getModule(sourceSet)) {
4142
parseFromKDocTag(
4243
kDocTag = element.comment,
43-
externalDri = { resolveKDocLink(it, elementName, context.logger, sourceSet) },
44+
externalDri = { resolveKDocLink(it, getLocation(it) ?: elementName, context.logger, sourceSet) },
4445
kdocLocation = null,
4546
parseWithChildren = parseWithChildren
4647
)

dokka-subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/TranslatorError.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,22 @@ internal inline fun <R> KaSession.withExceptionCatcher(symbol: KaSymbol, action:
1616
} catch (e: TranslatorError) {
1717
throw e
1818
} catch (e: Throwable) {
19-
val file = try {
19+
val filePath = try {
2020
symbol.psi?.containingFile?.virtualFile?.path
2121
} catch (e: Throwable) {
2222
"[$e]"
2323
}
24-
val textRange = try {
25-
symbol.psi?.textRange.toString()
24+
val lineSuffix = try {
25+
val offset = symbol.psi?.textOffset
26+
val fileDocument = symbol.psi?.containingFile?.fileDocument
27+
val lineNumber = offset?.let { fileDocument?.getLineNumber(it) }
28+
if (lineNumber != null) ":${lineNumber + 1}"
29+
else ""
2630
} catch (e: Throwable) {
2731
"[$e]"
2832
}
2933
throw TranslatorError(
30-
"Error in translating of symbol (${(symbol as? KaNamedSymbol)?.name}) $symbol in file: $file, $textRange",
34+
"Error in translating of symbol (${(symbol as? KaNamedSymbol)?.name}) $symbol in file:///$filePath$lineSuffix",
3135
e
3236
)
3337
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright 2014-2026 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package org.jetbrains.dokka.analysis.kotlin.symbols.utils
6+
7+
import com.intellij.psi.PsiElement
8+
9+
/**
10+
* @return a string in the format `file://file.kt:<line>:<column>`,
11+
* or `null` if [psiElement] is not from a source file
12+
*/
13+
internal fun getLocation(psiElement: PsiElement): String? {
14+
val filePath = psiElement.containingFile?.virtualFile?.path ?: return null
15+
val offset = psiElement.textOffset
16+
val fileDocument = psiElement.containingFile?.fileDocument
17+
val lineNumber = fileDocument?.getLineNumber(offset)
18+
19+
return if (lineNumber != null) {
20+
val column = offset - fileDocument.getLineStartOffset(lineNumber)
21+
"file:///$filePath:${lineNumber + 1}:${column + 1}"
22+
} else
23+
"file:///$filePath"
24+
}

dokka-subprojects/plugin-base/src/test/kotlin/markdown/LinkTest.kt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1730,6 +1730,32 @@ class LinkTest : BaseAbstractTest() {
17301730
}
17311731
}
17321732

1733+
@Test
1734+
fun `should warn about unresolved links`() {
1735+
testInline(
1736+
"""
1737+
|/src/main/kotlin/Testing.kt
1738+
|
1739+
|/**
1740+
|* [property] is unresolved
1741+
| */
1742+
|fun usage() = 0
1743+
|}
1744+
""".trimMargin(),
1745+
configuration
1746+
) {
1747+
documentablesMergingStage = { m ->
1748+
val warn = logger.warnMessages.first()
1749+
val path = m.sourceSets.first().sourceRoots.first().path
1750+
1751+
assertEquals(
1752+
"Couldn't resolve link: [property] in file:///PATH/main/kotlin/Testing.kt:2:3 (root/main)",
1753+
warn.replace(path, "PATH")
1754+
)
1755+
}
1756+
}
1757+
}
1758+
17331759
private fun DModule.getLinkDRIFrom(name: String): DRI? {
17341760
val doc = this.dfs { it.name == name }?.documentation?.values?.single()
17351761
?: throw IllegalStateException("Can't find documentation for declaration '$name'")

0 commit comments

Comments
 (0)