aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Kotlin/DocumentationBuilder.kt2
-rw-r--r--src/Kotlin/DocumentationBuildingVisitor.kt127
-rw-r--r--src/Kotlin/DocumentationContext.kt60
-rw-r--r--src/Kotlin/DocumentationNodeBuilder.kt207
-rw-r--r--src/Kotlin/ResolveReferences.kt75
5 files changed, 2 insertions, 469 deletions
diff --git a/src/Kotlin/DocumentationBuilder.kt b/src/Kotlin/DocumentationBuilder.kt
index 211697cd..d8162c44 100644
--- a/src/Kotlin/DocumentationBuilder.kt
+++ b/src/Kotlin/DocumentationBuilder.kt
@@ -12,6 +12,8 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope
import org.jetbrains.jet.lang.psi.JetFile
import org.jetbrains.jet.lang.resolve.name.FqName
+public data class DocumentationOptions(val includeNonPublic: Boolean = false)
+
class DocumentationBuilder(val context: BindingContext, val options: DocumentationOptions) {
val descriptorToNode = hashMapOf<DeclarationDescriptor, DocumentationNode>()
val nodeToDescriptor = hashMapOf<DocumentationNode, DeclarationDescriptor>()
diff --git a/src/Kotlin/DocumentationBuildingVisitor.kt b/src/Kotlin/DocumentationBuildingVisitor.kt
deleted file mode 100644
index 81ac2430..00000000
--- a/src/Kotlin/DocumentationBuildingVisitor.kt
+++ /dev/null
@@ -1,127 +0,0 @@
-package org.jetbrains.dokka
-
-import org.jetbrains.jet.lang.descriptors.*
-import org.jetbrains.jet.lang.resolve.name.*
-import org.jetbrains.jet.lang.resolve.*
-
-public data class DocumentationOptions(val includeNonPublic: Boolean = false)
-
-class DocumentationBuildingVisitor(val context: BindingContext,
- val options: DocumentationOptions,
- private val worker: DeclarationDescriptorVisitor<DocumentationNode, DocumentationNode>)
-: DeclarationDescriptorVisitor<DocumentationNode, DocumentationNode> {
-
- val visibleToDocumentation = setOf(Visibilities.INTERNAL, Visibilities.PROTECTED, Visibilities.PUBLIC)
-
- private fun visitChildren(descriptors: Collection<DeclarationDescriptor>, data: DocumentationNode) {
- for (descriptor in descriptors) {
- visitChild(descriptor, data)
- }
- }
-
- private fun visitChild(descriptor: DeclarationDescriptor?, data: DocumentationNode) {
- if (descriptor != null && descriptor.isUserCode()) {
- if (options.includeNonPublic
- || descriptor !is MemberDescriptor
- || descriptor.getVisibility() in visibleToDocumentation) {
- descriptor.accept(this, data)
- }
- }
- }
-
- private fun createDocumentation(descriptor: DeclarationDescriptor, data: DocumentationNode): DocumentationNode {
- return descriptor.accept(worker, data)
- }
-
- private fun processCallable(descriptor: CallableDescriptor, data: DocumentationNode): DocumentationNode {
- val node = createDocumentation(descriptor, data)
- visitChildren(descriptor.getTypeParameters(), node)
- visitChild(descriptor.getExtensionReceiverParameter(), node)
- visitChildren(descriptor.getValueParameters(), node)
- return node
- }
-
- public override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor?, data: DocumentationNode?): DocumentationNode? {
- val node = createDocumentation(descriptor!!, data!!)
- visitChildren(descriptor.getMemberScope().getAllDescriptors(), node)
- return node
- }
-
- public override fun visitPackageViewDescriptor(descriptor: PackageViewDescriptor?, data: DocumentationNode?): DocumentationNode? {
- val node = createDocumentation(descriptor!!, data!!)
- visitChildren(descriptor.getMemberScope().getAllDescriptors(), node)
- return node
- }
-
- public override fun visitVariableDescriptor(descriptor: VariableDescriptor?, data: DocumentationNode?): DocumentationNode? {
- val node = processCallable(descriptor!!, data!!)
- return node
- }
-
- public override fun visitPropertyDescriptor(descriptor: PropertyDescriptor?, data: DocumentationNode?): DocumentationNode? {
- val node = processCallable(descriptor!!, data!!)
- visitChild(descriptor.getGetter(), node)
- visitChild(descriptor.getSetter(), node)
- return node
- }
-
- public override fun visitFunctionDescriptor(descriptor: FunctionDescriptor?, data: DocumentationNode?): DocumentationNode? {
- val node = processCallable(descriptor!!, data!!)
- return node
- }
-
- public override fun visitTypeParameterDescriptor(descriptor: TypeParameterDescriptor?, data: DocumentationNode?): DocumentationNode? {
- val node = createDocumentation(descriptor!!, data!!)
- return node
- }
-
- public override fun visitClassDescriptor(descriptor: ClassDescriptor?, data: DocumentationNode?): DocumentationNode? {
- val node = createDocumentation(descriptor!!, data!!)
- if (descriptor.getKind() != ClassKind.OBJECT) {
- // do not go inside object for class object and constructors, they are generated
- visitChildren(descriptor.getTypeConstructor().getParameters(), node)
- visitChildren(descriptor.getConstructors(), node)
- visitChild(descriptor.getClassObjectDescriptor(), node)
- }
- visitChildren(descriptor.getDefaultType().getMemberScope().getAllDescriptors(), node)
- return node
- }
-
- public override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: DocumentationNode): DocumentationNode {
- val node = createDocumentation(descriptor, data)
- visitChild(descriptor.getPackage(FqName.ROOT), node)
- return node
- }
-
- public override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor?, data: DocumentationNode?): DocumentationNode? {
- val node = createDocumentation(descriptor!!, data!!)
- visitChildren(descriptor.getValueParameters(), node)
- return node
- }
-
- public override fun visitScriptDescriptor(scriptDescriptor: ScriptDescriptor?, data: DocumentationNode?): DocumentationNode? {
- val classDescriptor = scriptDescriptor!!.getClassDescriptor()
- val node = visitClassDescriptor(classDescriptor, data)
- return node
- }
-
- public override fun visitValueParameterDescriptor(descriptor: ValueParameterDescriptor?, data: DocumentationNode?): DocumentationNode? {
- val node = visitVariableDescriptor(descriptor!!, data)
- return node
- }
-
- public override fun visitPropertyGetterDescriptor(descriptor: PropertyGetterDescriptor?, data: DocumentationNode?): DocumentationNode? {
- val node = visitFunctionDescriptor(descriptor!!, data)
- return node
- }
-
- public override fun visitPropertySetterDescriptor(descriptor: PropertySetterDescriptor?, data: DocumentationNode?): DocumentationNode? {
- val node = visitFunctionDescriptor(descriptor!!, data)
- return node
- }
-
- public override fun visitReceiverParameterDescriptor(descriptor: ReceiverParameterDescriptor?, data: DocumentationNode?): DocumentationNode? {
- val node = createDocumentation(descriptor!!, data!!)
- return node
- }
-}
diff --git a/src/Kotlin/DocumentationContext.kt b/src/Kotlin/DocumentationContext.kt
deleted file mode 100644
index b13f08ea..00000000
--- a/src/Kotlin/DocumentationContext.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-package org.jetbrains.dokka
-
-import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
-import org.jetbrains.jet.lang.resolve.BindingContext
-import org.jetbrains.jet.lang.resolve.scopes.JetScope
-import org.jetbrains.jet.lang.descriptors.ModuleDescriptor
-import org.jetbrains.jet.lang.resolve.name.FqName
-
-/**
- * Context for documentation generation.
- *
- * Holds information about relations between [nodes](DocumentationNode) and [descriptors](DeclarationDescriptor) during documentation generation
- *
- * $bindingContext: symbol resolution context
- */
-public class DocumentationContext(val bindingContext: BindingContext) {
- val descriptorToNode = hashMapOf<DeclarationDescriptor, DocumentationNode>()
- val nodeToDescriptor = hashMapOf<DocumentationNode, DeclarationDescriptor>()
-
- val relations = hashMapOf<DocumentationNode, DeclarationDescriptor>()
-
- fun attach(node: DocumentationNode, descriptor: DeclarationDescriptor) {
- relations.put(node, descriptor)
- }
-
- fun register(descriptor: DeclarationDescriptor, node: DocumentationNode) {
- descriptorToNode.put(descriptor, node)
- nodeToDescriptor.put(node, descriptor)
- }
-
- fun getResolutionScope(node: DocumentationNode): JetScope {
- val descriptor = nodeToDescriptor[node] ?: throw IllegalArgumentException("Node is not known to this context")
- return bindingContext.getResolutionScope(descriptor)
- }
-
- fun parseDocumentation(descriptor: DeclarationDescriptor): Content {
- val docText = bindingContext.getDocumentationElements(descriptor).map { it.extractText() }.join("\n")
- val tree = MarkdownProcessor.parse(docText)
- //println(tree.toTestString())
- val content = tree.toContent()
- return content
- }
-}
-
-fun BindingContext.createDocumentationModule(name: String,
- module: ModuleDescriptor,
- packages: Set<FqName>,
- options: DocumentationOptions = DocumentationOptions()): DocumentationModule {
- val documentationModule = DocumentationModule(name)
- val builder = DocumentationBuilder(this, options)
- with(builder) {
- for (packageName in packages) {
- val pkg = module.getPackage(packageName)
- if (pkg != null)
- documentationModule.appendChild(pkg, DocumentationReference.Kind.Member)
- }
- }
- builder.resolveReferences(documentationModule)
- return documentationModule
-}
diff --git a/src/Kotlin/DocumentationNodeBuilder.kt b/src/Kotlin/DocumentationNodeBuilder.kt
deleted file mode 100644
index a2686b00..00000000
--- a/src/Kotlin/DocumentationNodeBuilder.kt
+++ /dev/null
@@ -1,207 +0,0 @@
-package org.jetbrains.dokka
-
-import org.jetbrains.jet.lang.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies
-import org.jetbrains.jet.lang.descriptors.MemberDescriptor
-import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
-import org.jetbrains.jet.lang.types.JetType
-import org.jetbrains.jet.lang.descriptors.Named
-import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor
-import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor
-import org.jetbrains.jet.lang.descriptors.ClassDescriptor
-import org.jetbrains.jet.lang.descriptors.FunctionDescriptor
-import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
-import org.jetbrains.jet.lang.descriptors.PropertyDescriptor
-import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor
-import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor
-import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor
-import org.jetbrains.jet.lang.descriptors.ClassKind
-import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
-import org.jetbrains.jet.lang.types.TypeProjection
-import org.jetbrains.jet.lang.types.Variance
-import org.jetbrains.dokka.DocumentationNode.Kind
-
-class DocumentationNodeBuilder(val context: DocumentationContext) : DeclarationDescriptorVisitorEmptyBodies<DocumentationNode, DocumentationNode>() {
-
- fun reference(from: DocumentationNode, to: DocumentationNode, kind: DocumentationReference.Kind) {
- from.addReferenceTo(to, kind)
- when (kind) {
- DocumentationReference.Kind.Detail -> to.addReferenceTo(from, DocumentationReference.Kind.Owner)
- DocumentationReference.Kind.Member -> to.addReferenceTo(from, DocumentationReference.Kind.Owner)
- DocumentationReference.Kind.Owner -> to.addReferenceTo(from, DocumentationReference.Kind.Member)
- }
- }
-
- fun addModality(descriptor: MemberDescriptor, data: DocumentationNode) {
- val modifier = descriptor.getModality().name().toLowerCase()
- val node = DocumentationNode(modifier, Content.Empty, DocumentationNode.Kind.Modifier)
- reference(data, node, DocumentationReference.Kind.Detail)
- }
-
- fun addVisibility(descriptor: MemberDescriptor, data: DocumentationNode) {
- val modifier = descriptor.getVisibility().toString()
- val node = DocumentationNode(modifier, Content.Empty, DocumentationNode.Kind.Modifier)
- reference(data, node, DocumentationReference.Kind.Detail)
- }
-
- fun addSupertypes(descriptor: ClassDescriptor, data: DocumentationNode) {
- val superTypes = descriptor.getTypeConstructor().getSupertypes()
- for (superType in superTypes) {
- if (superType.toString() != "Any")
- addType(superType, data, DocumentationNode.Kind.Supertype)
- }
- }
-
- fun addProjection(projection: TypeProjection, data: DocumentationNode, kind: DocumentationNode.Kind = DocumentationNode.Kind.Type) {
- val prefix = when (projection.getProjectionKind()) {
- Variance.IN_VARIANCE -> "in "
- Variance.OUT_VARIANCE -> "out "
- else -> ""
- }
- addType(projection.getType(), data, kind, prefix)
- }
-
- fun addType(jetType: JetType?, data: DocumentationNode, kind: DocumentationNode.Kind = DocumentationNode.Kind.Type, prefix : String = "") {
- if (jetType == null)
- return
- val classifierDescriptor = jetType.getConstructor().getDeclarationDescriptor()
- val name = when (classifierDescriptor) {
- is Named -> prefix + classifierDescriptor.getName().asString() + if (jetType.isNullable()) "?" else ""
- else -> "<anonymous>"
- }
- val node = DocumentationNode(name, Content.Empty, kind)
- if (classifierDescriptor != null)
- context.attach(node, classifierDescriptor)
-
- reference(data, node, DocumentationReference.Kind.Detail)
- for (typeArgument in jetType.getArguments())
- addProjection(typeArgument, node)
- }
-
- override fun visitDeclarationDescriptor(descriptor: DeclarationDescriptor?, data: DocumentationNode?): DocumentationNode? {
- descriptor!!
- val doc = context.parseDocumentation(descriptor)
- val node = DocumentationNode(descriptor.getName().asString(), doc, DocumentationNode.Kind.Unknown)
- reference(data!!, node, DocumentationReference.Kind.Member)
- context.register(descriptor, node)
- return node
- }
-
- override fun visitReceiverParameterDescriptor(descriptor: ReceiverParameterDescriptor?, data: DocumentationNode?): DocumentationNode? {
- descriptor!!
- val node = DocumentationNode(descriptor.getName().asString(), Content.Empty, DocumentationNode.Kind.Receiver)
- reference(data!!, node, DocumentationReference.Kind.Detail)
-
- addType(descriptor.getType(), node)
-
- return node
- }
-
- override fun visitValueParameterDescriptor(descriptor: ValueParameterDescriptor?, data: DocumentationNode?): DocumentationNode? {
- descriptor!!
- val doc = context.parseDocumentation(descriptor)
- val node = DocumentationNode(descriptor.getName().asString(), doc, DocumentationNode.Kind.Parameter)
- reference(data!!, node, DocumentationReference.Kind.Detail)
-
- addType(descriptor.getType(), node)
-
- return node
- }
-
- override fun visitClassDescriptor(descriptor: ClassDescriptor?, data: DocumentationNode?): DocumentationNode? {
- descriptor!!
- val doc = context.parseDocumentation(descriptor)
- val node = DocumentationNode(descriptor.getName().asString(), doc, when (descriptor.getKind()) {
- ClassKind.OBJECT -> Kind.Object
- ClassKind.CLASS_OBJECT -> Kind.Object
- ClassKind.TRAIT -> Kind.Interface
- ClassKind.ENUM_CLASS -> Kind.Enum
- ClassKind.ENUM_ENTRY -> Kind.EnumItem
- else -> Kind.Class
- })
- reference(data!!, node, DocumentationReference.Kind.Member)
- addModality(descriptor, node)
- addVisibility(descriptor, node)
- addSupertypes(descriptor, node)
- context.register(descriptor, node)
- return node
- }
-
- override fun visitFunctionDescriptor(descriptor: FunctionDescriptor?, data: DocumentationNode?): DocumentationNode? {
- descriptor!!
- val doc = context.parseDocumentation(descriptor)
- val node = DocumentationNode(descriptor.getName().asString(), doc, DocumentationNode.Kind.Function)
- reference(data!!, node, DocumentationReference.Kind.Member)
-
- addType(descriptor.getReturnType(), node)
- addModality(descriptor, node)
- addVisibility(descriptor, node)
- context.register(descriptor, node)
- return node
- }
-
- override fun visitTypeParameterDescriptor(descriptor: TypeParameterDescriptor?, data: DocumentationNode?): DocumentationNode? {
- descriptor!!
- val doc = context.parseDocumentation(descriptor)
- val name = descriptor.getName().asString()
- val prefix = when (descriptor.getVariance()) {
- Variance.IN_VARIANCE -> "in "
- Variance.OUT_VARIANCE -> "out "
- else -> ""
- }
-
- val node = DocumentationNode(prefix + name, doc, DocumentationNode.Kind.TypeParameter)
- reference(data!!, node, DocumentationReference.Kind.Detail)
- val builtIns = KotlinBuiltIns.getInstance()
- for (constraint in descriptor.getUpperBounds()) {
- if (constraint == builtIns.getDefaultBound())
- continue
- val constraintNode = DocumentationNode(constraint.toString(), Content.Empty, DocumentationNode.Kind.UpperBound)
- reference(node, constraintNode, DocumentationReference.Kind.Detail)
- }
- for (constraint in descriptor.getLowerBounds()) {
- if (builtIns.isNothing(constraint))
- continue
- val constraintNode = DocumentationNode(constraint.toString(), Content.Empty, DocumentationNode.Kind.LowerBound)
- reference(node, constraintNode, DocumentationReference.Kind.Detail)
- }
- return node
- }
-
- override fun visitPropertyDescriptor(descriptor: PropertyDescriptor?, data: DocumentationNode?): DocumentationNode? {
- descriptor!!
- val doc = context.parseDocumentation(descriptor)
- val node = DocumentationNode(descriptor.getName().asString(), doc, DocumentationNode.Kind.Property)
- reference(data!!, node, DocumentationReference.Kind.Member)
-
- addType(descriptor.getType(), node)
- addModality(descriptor, node)
- addVisibility(descriptor, node)
- context.register(descriptor, node)
- return node
- }
-
- override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor?, data: DocumentationNode?): DocumentationNode? {
- descriptor!!
- val doc = context.parseDocumentation(descriptor)
- val node = DocumentationNode("<init>", doc, DocumentationNode.Kind.Constructor)
- reference(data!!, node, DocumentationReference.Kind.Member)
-
- addVisibility(descriptor, node)
- context.register(descriptor, node)
- return node
- }
-
- override fun visitPackageViewDescriptor(descriptor: PackageViewDescriptor?, data: DocumentationNode?): DocumentationNode? {
- descriptor!!
- val node = DocumentationNode(descriptor.getFqName().asString(), Content.Empty, DocumentationNode.Kind.Package)
- reference(data!!, node, DocumentationReference.Kind.Member)
- return node
- }
-
- override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor?, data: DocumentationNode?): DocumentationNode? {
- descriptor!!
- val node = DocumentationNode(descriptor.fqName.asString(), Content.Empty, DocumentationNode.Kind.Package)
- reference(data!!, node, DocumentationReference.Kind.Member)
- return node
- }
-} \ No newline at end of file
diff --git a/src/Kotlin/ResolveReferences.kt b/src/Kotlin/ResolveReferences.kt
deleted file mode 100644
index 1349c69e..00000000
--- a/src/Kotlin/ResolveReferences.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.jetbrains.dokka
-
-import org.jetbrains.jet.lang.resolve.name.Name
-
-/**
- * Generates cross-references for documentation such as extensions for a type, inheritors, etc
- *
- * $receiver: [DocumentationContext] for node/descriptor resolutions
- * $node: [DocumentationNode] to visit
- */
-public fun DocumentationContext.resolveReferences(node: DocumentationNode) {
- node.details(DocumentationNode.Kind.Receiver).forEach { detail ->
- val receiverType = detail.detail(DocumentationNode.Kind.Type)
- val descriptor = relations[receiverType]
- if (descriptor != null) {
- val typeNode = descriptorToNode[descriptor]
- // if typeNode is null, extension is to external type like in a library
- // should we create dummy node here?
- typeNode?.addReferenceTo(node, DocumentationReference.Kind.Extension)
- }
- }
- node.details(DocumentationNode.Kind.Supertype).forEach { detail ->
- val descriptor = relations[detail]
- if (descriptor != null) {
- val typeNode = descriptorToNode[descriptor]
- typeNode?.addReferenceTo(node, DocumentationReference.Kind.Inheritor)
- }
- }
- node.details.forEach { detail ->
- val descriptor = relations[detail]
- if (descriptor != null) {
- val typeNode = descriptorToNode[descriptor]
- if (typeNode != null) {
- detail.addReferenceTo(typeNode, DocumentationReference.Kind.Link)
- }
- }
- }
-
- resolveContentLinks(node, node.doc)
-
- for (child in node.members) {
- resolveReferences(child)
- }
- for (child in node.details) {
- resolveReferences(child)
- }
-}
-
-fun DocumentationContext.resolveContentLinks(node: DocumentationNode, content: ContentNode) {
- val snapshot = content.children.toList()
- for (child in snapshot) {
- if (child is ContentExternalLink) {
- val referenceText = child.href
- if (Name.isValidIdentifier(referenceText)) {
- val scope = getResolutionScope(node)
- val symbolName = Name.guess(referenceText)
- val symbol = scope.getLocalVariable(symbolName) ?:
- scope.getProperties(symbolName).firstOrNull() ?:
- scope.getFunctions(symbolName).firstOrNull() ?:
- scope.getClassifier(symbolName)
-
- if (symbol != null) {
- val targetNode = descriptorToNode[symbol]
- val contentLink = if (targetNode != null) ContentNodeLink(targetNode) else ContentExternalLink("#")
-
- val index = content.children.indexOf(child)
- content.children.remove(index)
- contentLink.children.addAll(child.children)
- content.children.add(index, contentLink)
- }
- }
- }
- resolveContentLinks(node, child)
- }
-} \ No newline at end of file