diff --git a/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt index 0bb4a732ef..27428fc6e0 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt @@ -2,6 +2,7 @@ package org.jetbrains.dokka.base.transformers.pages.sourcelinks import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiElement +import com.intellij.psi.PsiIdentifier import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.analysis.DescriptorDocumentableSource @@ -16,6 +17,8 @@ import org.jetbrains.dokka.plugability.plugin import org.jetbrains.dokka.plugability.querySingle import org.jetbrains.dokka.transformers.pages.PageTransformer import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.psiUtil.getChildOfType import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.kotlin.utils.addToStdlib.cast import java.io.File @@ -92,8 +95,10 @@ class SourceLinksTransformer(val context: DokkaContext) : PageTransformer { } private fun PsiElement.lineNumber(): Int? { + val ktIdentifierTextRange = this.node?.findChildByType(KtTokens.IDENTIFIER)?.textRange + val javaIdentifierTextRange = this.getChildOfType()?.textRange // synthetic and some light methods might return null - val textRange = textRange ?: return null + val textRange = ktIdentifierTextRange ?: javaIdentifierTextRange ?: textRange ?: return null val doc = PsiDocumentManager.getInstance(project).getDocument(containingFile) // IJ uses 0-based line-numbers; external source browsers use 1-based diff --git a/plugins/base/src/test/kotlin/enums/JavaEnumsTest.kt b/plugins/base/src/test/kotlin/enums/JavaEnumsTest.kt index e8b9e92b00..b3d56d2ea7 100644 --- a/plugins/base/src/test/kotlin/enums/JavaEnumsTest.kt +++ b/plugins/base/src/test/kotlin/enums/JavaEnumsTest.kt @@ -47,6 +47,9 @@ class JavaEnumsTest : BaseAbstractTest() { |/src/main/java/basic/JavaEnum.java |package testpackage | + |/** + |* doc + |*/ |public enum JavaEnum { | ONE, TWO, THREE |} @@ -62,7 +65,7 @@ class JavaEnumsTest : BaseAbstractTest() { assertEquals( - "https://github.com/user/repo/tree/master/src/main/java/basic/JavaEnum.java#L3", + "https://github.com/user/repo/tree/master/src/main/java/basic/JavaEnum.java#L6", sourceLink ) } diff --git a/plugins/base/src/test/kotlin/enums/KotlinEnumsTest.kt b/plugins/base/src/test/kotlin/enums/KotlinEnumsTest.kt index 655a8b827c..58cb3f9f39 100644 --- a/plugins/base/src/test/kotlin/enums/KotlinEnumsTest.kt +++ b/plugins/base/src/test/kotlin/enums/KotlinEnumsTest.kt @@ -398,6 +398,9 @@ class KotlinEnumsTest : BaseAbstractTest() { |/src/main/kotlin/basic/KotlinEnum.kt |package testpackage | + |/** + |* Doc + |*/ |enum class KotlinEnum { | ONE, TWO, THREE |} @@ -412,7 +415,7 @@ class KotlinEnumsTest : BaseAbstractTest() { .attr("href") assertEquals( - "https://github.com/user/repo/tree/master/src/main/kotlin/basic/KotlinEnum.kt#L3", + "https://github.com/user/repo/tree/master/src/main/kotlin/basic/KotlinEnum.kt#L6", sourceLink ) } diff --git a/plugins/base/src/test/kotlin/transformers/SourceLinkTransformerTest.kt b/plugins/base/src/test/kotlin/transformers/SourceLinkTransformerTest.kt new file mode 100644 index 0000000000..81b4db6910 --- /dev/null +++ b/plugins/base/src/test/kotlin/transformers/SourceLinkTransformerTest.kt @@ -0,0 +1,67 @@ +package transformers + +import org.jetbrains.dokka.SourceLinkDefinitionImpl +import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest +import org.junit.jupiter.api.Test +import signatures.renderedContent +import utils.TestOutputWriterPlugin +import java.net.URL +import kotlin.test.assertEquals +import org.jsoup.nodes.Element + +class SourceLinkTransformerTest : BaseAbstractTest() { + + private fun Element.getSourceLink() = select(".symbol .floating-right") + .select("a[href]") + .attr("href") + + @Test + fun `source link should lead to name`() { + val configuration = dokkaConfiguration { + sourceSets { + sourceSet { + sourceRoots = listOf("src/") + sourceLinks = listOf( + SourceLinkDefinitionImpl( + localDirectory = "src/main/kotlin", + remoteUrl = URL("https://github.com/user/repo/tree/master/src/main/kotlin"), + remoteLineSuffix = "#L" + ) + ) + } + } + } + + val writerPlugin = TestOutputWriterPlugin() + + testInline( + """ + |/src/main/kotlin/basic/Deprecated.kt + |package testpackage + | + |/** + |* Marks the annotated declaration as deprecated. ... + |*/ + |@Target(CLASS, FUNCTION, PROPERTY, ANNOTATION_CLASS, CONSTRUCTOR, PROPERTY_SETTER, PROPERTY_GETTER, TYPEALIAS) + |@MustBeDocumented + |public annotation class Deprecated( + | val message: String, + | val replaceWith: ReplaceWith = ReplaceWith(""), + | val level: DeprecationLevel = DeprecationLevel.WARNING + |) + """.trimMargin(), + configuration, + pluginOverrides = listOf(writerPlugin) + ) { + renderingStage = { _, _ -> + val page = writerPlugin.writer.renderedContent("root/testpackage/-deprecated/index.html") + val sourceLink = page.getSourceLink() + + assertEquals( + "https://github.com/user/repo/tree/master/src/main/kotlin/basic/Deprecated.kt#L8", + sourceLink + ) + } + } + } +} \ No newline at end of file