kdoc: link to generated html source from kdoc

This commit is contained in:
Stepan Koltsov
2012-06-25 23:55:30 +04:00
parent caddc84950
commit be1b9a011b
5 changed files with 65 additions and 34 deletions
@@ -0,0 +1,18 @@
package org.jetbrains.kotlin.doc
import java.util.List
import java.util.Map
import java.util.HashMap
fun <A, K, V> List<A>.toHashMap(f: (A) -> #(K, V)): Map<K, V> {
val r = HashMap<K, V>()
for (item in this) {
val entry = f(item)
r.put(entry._1, entry._2)
}
return r
}
fun <K, V> List<V>.toHashMapMappingToKey(f: (V) -> K): Map<K, V> = toHashMap { v -> #(f(v), v) }
@@ -32,7 +32,7 @@ class Html2CompilerPlugin(private val compilerArguments: KDocArguments) : Doclet
docOutputRoot = File(docOutputDir)
}
private val srcOutputRoot = File(docOutputRoot, "src")
private val srcOutputRoot = File(docOutputRoot, "src-html")
private val sourceDirs: List<File> =
compilerArguments
@@ -4,6 +4,7 @@ import kotlin.*
import kotlin.util.*
import org.jetbrains.kotlin.doc.KDocConfig
import org.jetbrains.kotlin.doc.*
import org.jetbrains.kotlin.doc.highlighter.SyntaxHighligher
import java.util.*
@@ -212,6 +213,37 @@ class KModel(val context: BindingContext, val config: KDocConfig, val sourceDirs
private val readMeDirsScanned = HashSet<String>()
val sourcesInfo: List<SourceInfo>
;{
val normalizedSourceDirs: List<String> =
sourceDirs.map { file -> file.getCanonicalPath()!! }
private fun relativePath(psiFile: PsiFile): String {
val file = File((psiFile.getVirtualFile() as CoreLocalVirtualFile).getPath()).getCanonicalFile()!!
val filePath = file.getPath()!!
for (sourceDirPath in normalizedSourceDirs) {
if (filePath.startsWith(sourceDirPath) && filePath.length() > sourceDirPath.length()) {
return filePath.substring(sourceDirPath.length + 1)
}
}
throw Exception("$file is not a child of any source roots $normalizedSourceDirs")
}
sourcesInfo = sources.map { source ->
val relativePath = relativePath(source)
val htmlPath = relativePath.replaceFirst("\\.kt$", "") + ".html"
SourceInfo(source, relativePath, htmlPath)
}
}
private val sourceInfoByFile = sourcesInfo.toHashMapMappingToKey<JetFile, SourceInfo> { sourceInfo -> sourceInfo.psi }
fun sourceInfoByFile(file: JetFile) = sourceInfoByFile.get(file)!!
;{
/** Loads the model from the given set of source files */
val allNamespaces = HashSet<NamespaceDescriptor>()
@@ -241,29 +273,6 @@ class KModel(val context: BindingContext, val config: KDocConfig, val sourceDirs
}
val sourcesInfo: List<SourceInfo>
;{
val normalizedSourceDirs: List<String> =
sourceDirs.map { file -> file.getCanonicalPath()!! }
private fun relativePath(psiFile: PsiFile): String {
val file = File((psiFile.getVirtualFile() as CoreLocalVirtualFile).getPath()).getCanonicalFile()!!
val filePath = file.getPath()!!
for (sourceDirPath in normalizedSourceDirs) {
if (filePath.startsWith(sourceDirPath) && filePath.length() > sourceDirPath.length()) {
return filePath.substring(sourceDirPath.length + 1)
}
}
throw Exception("$file is not a child of any source roots $normalizedSourceDirs")
}
sourcesInfo = sources.map { source ->
val relativePath = relativePath(source)
val htmlPath = relativePath.replaceFirst("\\.kt$", "") + ".html"
SourceInfo(source, relativePath, htmlPath)
}
}
/**
@@ -492,7 +501,7 @@ class KModel(val context: BindingContext, val config: KDocConfig, val sourceDirs
}
protected fun getPsiElement(descriptor: DeclarationDescriptor): PsiElement? {
fun getPsiElement(descriptor: DeclarationDescriptor): PsiElement? {
return try {
BindingContextUtils.descriptorToDeclaration(context, descriptor)
} catch (e: Throwable) {
@@ -963,7 +972,10 @@ class KPackage(model: KModel, val descriptor: NamespaceDescriptor,
var created = false
val klass = classMap.getOrPut(name) {
created = true
KClass(this, descriptor)
val psiFile = model.getPsiElement(descriptor)?.getContainingFile()
val jetFile = psiFile as? JetFile
val sourceInfo = if (jetFile != null) model.sourceInfoByFile(jetFile) else null
KClass(this, descriptor, sourceInfo)
}
if (created) {
// sometimes we may have source files for a package in different source directories
@@ -1068,7 +1080,8 @@ class KType(val jetType: JetType, model: KModel, val klass: KClass?, val argumen
class KClass(
val pkg: KPackage,
val descriptor: ClassDescriptor)
val descriptor: ClassDescriptor,
val sourceInfo: SourceInfo?)
: KClassOrPackage(pkg.model, descriptor), Comparable<KClass>
{
val simpleName = descriptor.getName().getName()
@@ -72,8 +72,8 @@ abstract class KDocTemplate() : TextTemplate() {
return klass.sourceLink()
} else {
val pkg = klass.pkg
return if (!pkg.useExternalLink) {
"${pkg.nameAsRelativePath}src-html/${klass.nameAsPath}.html#line.${klass.sourceLine}"
return if (klass.sourceInfo != null) {
"${pkg.nameAsRelativePath}src-html/${klass.sourceInfo.htmlPath}.html#line.${klass.sourceLine}"
} else {
href(klass)
}
@@ -86,8 +86,8 @@ abstract class KDocTemplate() : TextTemplate() {
val owner = f.owner
return if (owner is KClass) {
val pkg = owner.pkg
if (!pkg.useExternalLink) {
"${rootHref(pkg)}src-html/${owner.simpleName}.html#line.${f.sourceLine}"
if (owner.sourceInfo != null) {
"${rootHref(pkg)}src-html/${owner.sourceInfo.htmlPath}.html#line.${f.sourceLine}"
} else {
href(f)
}
@@ -109,8 +109,8 @@ abstract class KDocTemplate() : TextTemplate() {
val owner = f.owner
return if (owner is KClass) {
val pkg = owner.pkg
if (!pkg.useExternalLink) {
"${rootHref(pkg)}src-html/${owner.simpleName}.html#line.${f.sourceLine}"
if (owner.sourceInfo != null) {
"${rootHref(pkg)}src-html/${owner.sourceInfo.htmlPath}#line.${f.sourceLine}"
} else {
href(f)
}
@@ -284,4 +284,4 @@ abstract class PackageTemplateSupport(open val pkg: KPackage) : KDocTemplate() {
println(link(a))
}
}
}
}