• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.jetbrains.dokka
2 
3 import com.intellij.psi.PsiDocumentManager
4 import com.intellij.psi.PsiElement
5 import com.intellij.psi.PsiNameIdentifierOwner
6 import org.jetbrains.dokka.DokkaConfiguration.SourceLinkDefinition
7 import org.jetbrains.kotlin.psi.psiUtil.startOffset
8 import java.io.File
9 
10 
appendSourceLinknull11 fun DocumentationNode.appendSourceLink(psi: PsiElement?, sourceLinks: List<SourceLinkDefinition>) {
12     val path = psi?.containingFile?.virtualFile?.path ?: return
13 
14     val target = if (psi is PsiNameIdentifierOwner) psi.nameIdentifier else psi
15     val absPath = File(path).absolutePath
16     val linkDef = sourceLinks.firstOrNull { absPath.startsWith(it.path) }
17     if (linkDef != null) {
18         var url = linkDef.url + path.substring(linkDef.path.length)
19         if (linkDef.lineSuffix != null) {
20             val line = target?.lineNumber()
21             if (line != null) {
22                 url += linkDef.lineSuffix + line.toString()
23             }
24         }
25         append(DocumentationNode(url, Content.Empty, NodeKind.SourceUrl),
26                 RefKind.Detail);
27     }
28 
29     if (target != null) {
30         append(DocumentationNode(target.sourcePosition(), Content.Empty, NodeKind.SourcePosition), RefKind.Detail)
31     }
32 }
33 
sourcePositionnull34 private fun PsiElement.sourcePosition(): String {
35     val path = containingFile.virtualFile.path
36     val lineNumber = lineNumber()
37     val columnNumber = columnNumber()
38 
39     return when {
40         lineNumber == null -> path
41         columnNumber == null -> "$path:$lineNumber"
42         else -> "$path:$lineNumber:$columnNumber"
43     }
44 }
45 
lineNumbernull46 fun PsiElement.lineNumber(): Int? {
47     val doc = PsiDocumentManager.getInstance(project).getDocument(containingFile)
48     // IJ uses 0-based line-numbers; external source browsers use 1-based
49     return doc?.getLineNumber(textRange.startOffset)?.plus(1)
50 }
51 
columnNumbernull52 fun PsiElement.columnNumber(): Int? {
53     val doc = PsiDocumentManager.getInstance(project).getDocument(containingFile) ?: return null
54     val lineNumber = doc.getLineNumber(textRange.startOffset)
55     return startOffset - doc.getLineStartOffset(lineNumber)
56 }