aboutsummaryrefslogtreecommitdiff
path: root/src/Kotlin/DocumentationBuilder.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/Kotlin/DocumentationBuilder.kt')
-rw-r--r--src/Kotlin/DocumentationBuilder.kt74
1 files changed, 65 insertions, 9 deletions
diff --git a/src/Kotlin/DocumentationBuilder.kt b/src/Kotlin/DocumentationBuilder.kt
index b5b079de..7dc4075b 100644
--- a/src/Kotlin/DocumentationBuilder.kt
+++ b/src/Kotlin/DocumentationBuilder.kt
@@ -1,7 +1,9 @@
package org.jetbrains.dokka
-import com.intellij.openapi.project.Project
import com.intellij.openapi.util.text.StringUtil
+import com.intellij.psi.PsiDocCommentOwner
+import com.intellij.psi.PsiJavaFile
+import com.intellij.psi.PsiNamedElement
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.dokka.DocumentationNode.Kind
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
@@ -9,6 +11,8 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor
+import org.jetbrains.kotlin.idea.caches.resolve.KotlinCacheService
+import org.jetbrains.kotlin.idea.caches.resolve.getModuleInfo
import org.jetbrains.kotlin.idea.kdoc.KDocFinder
import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
@@ -16,6 +20,9 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection
import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag
import org.jetbrains.kotlin.lexer.KtTokens
+import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
+import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
+import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtModifierListOwner
import org.jetbrains.kotlin.psi.KtParameter
@@ -25,6 +32,8 @@ import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.TypedCompileTimeConstant
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.isDocumentedAnnotation
+import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver
+import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.resolve.source.getPsi
@@ -55,7 +64,7 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade,
val session: ResolveSession,
val options: DocumentationOptions,
val refGraph: NodeReferenceGraph,
- val logger: DokkaLogger) {
+ val logger: DokkaLogger) : JavaDocumentationBuilder {
val visibleToDocumentation = setOf(Visibilities.PROTECTED, Visibilities.PUBLIC)
val boringBuiltinClasses = setOf(
"kotlin.Unit", "kotlin.Byte", "kotlin.Short", "kotlin.Int", "kotlin.Long", "kotlin.Char", "kotlin.Boolean",
@@ -65,7 +74,14 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade,
KtTokens.OPEN_KEYWORD, KtTokens.FINAL_KEYWORD, KtTokens.ABSTRACT_KEYWORD, KtTokens.SEALED_KEYWORD,
KtTokens.OVERRIDE_KEYWORD)
- fun parseDocumentation(descriptor: DeclarationDescriptor): Content {
+
+ fun parseDocumentation(descriptor: DeclarationDescriptor): Content = parseDocumentationAndDetails(descriptor).first
+
+ fun parseDocumentationAndDetails(descriptor: DeclarationDescriptor): Pair<Content, (DocumentationNode) -> Unit> {
+ if (descriptor is JavaClassDescriptor || descriptor is JavaCallableMemberDescriptor) {
+ return parseJavadoc(descriptor)
+ }
+
val kdoc = KDocFinder.findKDoc(descriptor) ?: findStdlibKDoc(descriptor)
if (kdoc == null) {
if (options.reportUndocumented && !descriptor.isDeprecated() &&
@@ -73,7 +89,7 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade,
descriptor !is PropertyAccessorDescriptor) {
logger.warn("No documentation for ${descriptor.signatureWithSourceLocation()}")
}
- return Content.Empty
+ return Content.Empty to { node -> }
}
var kdocText = kdoc.getContent()
// workaround for code fence parsing problem in IJ markdown parser
@@ -100,7 +116,7 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade,
}
}
}
- return content
+ return content to { node -> }
}
/**
@@ -132,6 +148,20 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade,
return null
}
+ fun parseJavadoc(descriptor: DeclarationDescriptor): Pair<Content, (DocumentationNode) -> Unit> {
+ val psi = ((descriptor as? DeclarationDescriptorWithSource)?.source as? PsiSourceElement)?.psi
+ if (psi is PsiDocCommentOwner) {
+ val parseResult = JavadocParser(refGraph).parseDocumentation(psi as PsiNamedElement)
+ return parseResult.content to { node ->
+ parseResult.deprecatedContent?.let {
+ val deprecationNode = DocumentationNode("", it, DocumentationNode.Kind.Modifier)
+ node.append(deprecationNode, DocumentationReference.Kind.Deprecation)
+ }
+ }
+ }
+ return Content.Empty to { node -> }
+ }
+
fun DeclarationDescriptor.signature(): String = when(this) {
is ClassDescriptor, is PackageFragmentDescriptor -> DescriptorUtils.getFqName(this).asString()
is PropertyDescriptor -> containingDeclaration.signature() + "#" + name + receiverSignature()
@@ -246,8 +276,9 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade,
}
fun <T> DocumentationNode(descriptor: T, kind: Kind): DocumentationNode where T : DeclarationDescriptor, T : Named {
- val doc = parseDocumentation(descriptor)
+ val (doc, callback) = parseDocumentationAndDetails(descriptor)
val node = DocumentationNode(descriptor.name.asString(), doc, kind).withModifiers(descriptor)
+ callback(node)
return node
}
@@ -274,7 +305,7 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade,
}
fun DocumentationNode.appendVisibility(descriptor: DeclarationDescriptorWithVisibility) {
- val modifier = descriptor.visibility.toString()
+ val modifier = descriptor.visibility.normalize().displayName
appendTextNode(modifier, DocumentationNode.Kind.Modifier)
}
@@ -393,18 +424,20 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade,
(!options.skipDeprecated || !isDeprecated())
}
- fun DocumentationNode.appendMembers(descriptors: Iterable<DeclarationDescriptor>) {
- descriptors.forEach { descriptor ->
+ fun DocumentationNode.appendMembers(descriptors: Iterable<DeclarationDescriptor>): List<DocumentationNode> {
+ val nodes = descriptors.map { descriptor ->
if (descriptor is CallableMemberDescriptor && descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
val baseDescriptor = descriptor.overriddenDescriptors.firstOrNull()
if (baseDescriptor != null) {
link(this, baseDescriptor, DocumentationReference.Kind.InheritedMember)
}
+ null
}
else {
appendChild(descriptor, DocumentationReference.Kind.Member)
}
}
+ return nodes.filterNotNull()
}
fun DocumentationNode.appendInPageChildren(descriptors: Iterable<DeclarationDescriptor>, kind: DocumentationReference.Kind) {
@@ -464,6 +497,9 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade,
}
val members = defaultType.memberScope.getAllDescriptors().filter { it != companionObjectDescriptor }
node.appendMembers(members)
+ node.appendMembers(staticScope.getDescriptors()).forEach {
+ it.appendTextNode("static", Kind.Modifier)
+ }
val companionObjectDescriptor = companionObjectDescriptor
if (companionObjectDescriptor != null) {
node.appendMembers(companionObjectDescriptor.defaultType.memberScope.getAllDescriptors())
@@ -583,6 +619,9 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade,
}
node.appendAnnotations(this)
node.appendModifiers(this)
+ if (varargElementType != null && node.details(Kind.Modifier).none { it.name == "vararg" }) {
+ node.appendTextNode("vararg", Kind.Modifier)
+ }
register(this, node)
return node
}
@@ -678,6 +717,23 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade,
}
}
}
+
+ override fun appendFile(file: PsiJavaFile, module: DocumentationModule, packageContent: Map<String, Content>) {
+ val packageNode = module.findOrCreatePackageNode(file.packageName, packageContent)
+
+ file.classes.forEach {
+ val javaDescriptorResolver = KotlinCacheService.getInstance(file.project).getProjectService(JvmPlatform,
+ it.getModuleInfo(), javaClass<JavaDescriptorResolver>())
+
+ val descriptor = javaDescriptorResolver.resolveClass(JavaClassImpl(it))
+ if (descriptor == null) {
+ logger.warn("Cannot find descriptor for Java class ${it.qualifiedName}")
+ }
+ else {
+ packageNode.appendChild(descriptor, DocumentationReference.Kind.Member)
+ }
+ }
+ }
}
private fun AnnotationDescriptor.isDocumented(): Boolean {