diff options
author | Ilya Ryzhenkov <orangy@jetbrains.com> | 2014-10-03 15:57:16 +0400 |
---|---|---|
committer | Ilya Ryzhenkov <orangy@jetbrains.com> | 2014-10-03 15:57:16 +0400 |
commit | a52e1d543d22fdacf87ec00988b753d2d1107c1d (patch) | |
tree | 0b27f4aa91494d715044af79dead49c6e4f3fc00 /src | |
parent | e93b629e4b2fa70330d94b8cb77f3ae34d1a9960 (diff) | |
download | dokka-a52e1d543d22fdacf87ec00988b753d2d1107c1d.tar.gz dokka-a52e1d543d22fdacf87ec00988b753d2d1107c1d.tar.bz2 dokka-a52e1d543d22fdacf87ec00988b753d2d1107c1d.zip |
Work on cross-references.
Diffstat (limited to 'src')
-rw-r--r-- | src/Analysis/CompilerAPI.kt | 4 | ||||
-rw-r--r-- | src/Formats/StructuredFormatService.kt | 50 | ||||
-rw-r--r-- | src/Kotlin/CrossReferences.kt | 37 | ||||
-rw-r--r-- | src/Kotlin/DocumentationBuildingVisitor.kt | 2 | ||||
-rw-r--r-- | src/Kotlin/DocumentationContext.kt | 15 | ||||
-rw-r--r-- | src/Kotlin/DocumentationNodeBuilder.kt | 18 | ||||
-rw-r--r-- | src/Model/DocumentationNode.kt | 2 | ||||
-rw-r--r-- | src/Model/DocumentationReference.kt | 1 | ||||
-rw-r--r-- | src/Processing/CrossReferences.kt | 12 | ||||
-rw-r--r-- | src/main.kt | 6 |
10 files changed, 96 insertions, 51 deletions
diff --git a/src/Analysis/CompilerAPI.kt b/src/Analysis/CompilerAPI.kt index 032076e5..03d4dde6 100644 --- a/src/Analysis/CompilerAPI.kt +++ b/src/Analysis/CompilerAPI.kt @@ -80,7 +80,7 @@ public fun getFunctionInnerScope(outerScope: JetScope, descriptor: FunctionDescr val redeclarationHandler = RedeclarationHandler.DO_NOTHING val functionScope = WritableScopeImpl(outerScope, descriptor, redeclarationHandler, "Function ${descriptor.getName()} scope") - val receiver = descriptor.getReceiverParameter() + val receiver = descriptor.getExtensionReceiverParameter() if (receiver != null) { functionScope.setImplicitReceiver(receiver) } @@ -99,7 +99,7 @@ public fun getPropertyInnerScope(outerScope: JetScope, descriptor: PropertyDescr val redeclarationHandler = RedeclarationHandler.DO_NOTHING val propertyScope = WritableScopeImpl(outerScope, descriptor, redeclarationHandler, "Property ${descriptor.getName()} scope") - val receiver = descriptor.getReceiverParameter() + val receiver = descriptor.getExtensionReceiverParameter() if (receiver != null) { propertyScope.setImplicitReceiver(receiver) } diff --git a/src/Formats/StructuredFormatService.kt b/src/Formats/StructuredFormatService.kt index 40feaf21..f2fb9b41 100644 --- a/src/Formats/StructuredFormatService.kt +++ b/src/Formats/StructuredFormatService.kt @@ -103,30 +103,36 @@ public abstract class StructuredFormatService(val locationService: LocationServi } for (node in nodes) { - if (node.members.any()) { - appendHeader(to, "Members", 3) + appendSection("Members", node.members, node, to) + appendSection("Extensions", node.extensions, node, to) + appendSection("Links", node.links, node, to) + } + } - val children = node.members.sortBy { it.name } - val membersMap = children.groupBy { link(node, it) } + private fun StructuredFormatService.appendSection(caption: String, nodes: List<DocumentationNode>, node: DocumentationNode, to: StringBuilder) { + if (nodes.any()) { + appendHeader(to, caption, 3) - appendTable(to) { - appendTableBody(to) { - for ((location, members) in membersMap) { - appendTableRow(to) { - appendTableCell(to) { - appendText(to, formatLink(location)) - } - appendTableCell(to) { - val breakdownBySummary = members.groupBy { it.doc.summary } - for ((summary, items) in breakdownBySummary) { - val signatures = items.map { formatCode("${languageService.render(it)}") } - for (signature in signatures) { - appendText(to, signature) - } - - if (!summary.isEmpty()) { - appendText(to, formatText(summary)) - } + val children = nodes.sortBy { it.name } + val membersMap = children.groupBy { link(node, it) } + + appendTable(to) { + appendTableBody(to) { + for ((location, members) in membersMap) { + appendTableRow(to) { + appendTableCell(to) { + appendText(to, formatLink(location)) + } + appendTableCell(to) { + val breakdownBySummary = members.groupBy { it.doc.summary } + for ((summary, items) in breakdownBySummary) { + val signatures = items.map { formatCode("${languageService.render(it)}") } + for (signature in signatures) { + appendText(to, signature) + } + + if (!summary.isEmpty()) { + appendText(to, formatText(summary)) } } } diff --git a/src/Kotlin/CrossReferences.kt b/src/Kotlin/CrossReferences.kt new file mode 100644 index 00000000..7504cebc --- /dev/null +++ b/src/Kotlin/CrossReferences.kt @@ -0,0 +1,37 @@ +package org.jetbrains.dokka + +import org.jetbrains.jet.lang.descriptors.ClassKind + +/** + * Generates cross-references for documentation such as extensions for a type + * + * $receiver: [DocumentationContext] for node/descriptor resolutions + * $node: [DocumentationNode] to visit + */ +public fun DocumentationContext.buildCrossReferences(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.Type).forEach { detail -> + val descriptor = relations[detail] + if (descriptor != null) { + val typeNode = descriptorToNode[descriptor] + if (typeNode != null) { + // if typeNode is null, type is external to module + detail.addReferenceTo(typeNode, DocumentationReference.Kind.Link) + } + } + } + + for (member in node.members) { + buildCrossReferences(member) + } +} + diff --git a/src/Kotlin/DocumentationBuildingVisitor.kt b/src/Kotlin/DocumentationBuildingVisitor.kt index 5654903b..754ef8ef 100644 --- a/src/Kotlin/DocumentationBuildingVisitor.kt +++ b/src/Kotlin/DocumentationBuildingVisitor.kt @@ -32,7 +32,7 @@ class DocumentationBuildingVisitor(val context: BindingContext, private fun processCallable(descriptor: CallableDescriptor, data: DocumentationNode): DocumentationNode { val node = createDocumentation(descriptor, data) visitChildren(descriptor.getTypeParameters(), node) - visitChild(descriptor.getReceiverParameter(), node) + visitChild(descriptor.getExtensionReceiverParameter(), node) visitChildren(descriptor.getValueParameters(), node) return node } diff --git a/src/Kotlin/DocumentationContext.kt b/src/Kotlin/DocumentationContext.kt index ec9e748f..1fada8b3 100644 --- a/src/Kotlin/DocumentationContext.kt +++ b/src/Kotlin/DocumentationContext.kt @@ -6,10 +6,23 @@ 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 and descriptors 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) @@ -41,6 +54,8 @@ fun BindingContext.createDocumentationModule(name: String, pkg!!.accept(DocumentationBuildingVisitor(this, options, visitor), documentationModule) } + context.buildCrossReferences(documentationModule) + // TODO: Uncomment for resolve verification // checkResolveChildren(documentationModule) return documentationModule diff --git a/src/Kotlin/DocumentationNodeBuilder.kt b/src/Kotlin/DocumentationNodeBuilder.kt index 535f037f..66f71bf6 100644 --- a/src/Kotlin/DocumentationNodeBuilder.kt +++ b/src/Kotlin/DocumentationNodeBuilder.kt @@ -21,10 +21,11 @@ class DocumentationNodeBuilder(val context: DocumentationContext) : DeclarationD fun reference(from: DocumentationNode, to: DocumentationNode, kind: DocumentationReference.Kind) { from.addReferenceTo(to, kind) - if (kind == DocumentationReference.Kind.Link) - to.addReferenceTo(from, DocumentationReference.Kind.Link) - else - to.addReferenceTo(from, DocumentationReference.Kind.Owner) + 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) { @@ -42,15 +43,16 @@ class DocumentationNodeBuilder(val context: DocumentationContext) : DeclarationD fun addType(descriptor: DeclarationDescriptor, t: JetType?, data: DocumentationNode) { if (t == null) return - val typeConstructor = t.getConstructor() - val classifierDescriptor = typeConstructor.getDeclarationDescriptor() + val classifierDescriptor = t.getConstructor().getDeclarationDescriptor() val name = when (classifierDescriptor) { is Named -> classifierDescriptor.getName().asString() else -> "<anonymous>" } val node = DocumentationNode(name, Content.Empty, DocumentationNode.Kind.Type) - reference(data, node, DocumentationReference.Kind.Detail) + if (classifierDescriptor != null) + context.attach(node, classifierDescriptor) + reference(data, node, DocumentationReference.Kind.Detail) for (param in t.getArguments()) addType(descriptor, param.getType(), node) } @@ -59,7 +61,7 @@ class DocumentationNodeBuilder(val context: DocumentationContext) : DeclarationD descriptor!! val doc = context.parseDocumentation(descriptor) val node = DocumentationNode(descriptor.getName().asString(), doc, DocumentationNode.Kind.Unknown) - reference(data!!, node, DocumentationReference.Kind.Link) + reference(data!!, node, DocumentationReference.Kind.Member) context.register(descriptor, node) return node } diff --git a/src/Model/DocumentationNode.kt b/src/Model/DocumentationNode.kt index 198e549b..cb6a13db 100644 --- a/src/Model/DocumentationNode.kt +++ b/src/Model/DocumentationNode.kt @@ -14,6 +14,8 @@ public open class DocumentationNode(val name: String, get() = references(DocumentationReference.Kind.Detail).map { it.to } public val members: List<DocumentationNode> get() = references(DocumentationReference.Kind.Member).map { it.to } + public val extensions: List<DocumentationNode> + get() = references(DocumentationReference.Kind.Extension).map { it.to } public val links: List<DocumentationNode> get() = references(DocumentationReference.Kind.Link).map { it.to } diff --git a/src/Model/DocumentationReference.kt b/src/Model/DocumentationReference.kt index 41cca8db..fdc29b9e 100644 --- a/src/Model/DocumentationReference.kt +++ b/src/Model/DocumentationReference.kt @@ -6,6 +6,7 @@ public data class DocumentationReference(val from: DocumentationNode, val to: Do Member Detail Link + Extension Override } } diff --git a/src/Processing/CrossReferences.kt b/src/Processing/CrossReferences.kt deleted file mode 100644 index 9f21da6e..00000000 --- a/src/Processing/CrossReferences.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.jetbrains.dokka - -public fun DocumentationNode.buildCrossReferences() { - for (member in members) { - member.buildCrossReferences() - member.details(DocumentationNode.Kind.Receiver).forEach { detail -> - - - } - } -} - diff --git a/src/main.kt b/src/main.kt index a541831d..409e030a 100644 --- a/src/main.kt +++ b/src/main.kt @@ -59,12 +59,6 @@ public fun main(args: Array<String>) { val timeAnalyse = System.currentTimeMillis() - startAnalyse println("done in ${timeAnalyse / 1000} secs") - print("Processing cross references... ") - val startProcessing = System.currentTimeMillis() - documentation.buildCrossReferences() - val timeProcessing = System.currentTimeMillis() - startProcessing - println("done in ${timeProcessing / 1000} secs") - val startBuild = System.currentTimeMillis() val signatureGenerator = KotlinLanguageService() val locationService = FoldersLocationService(arguments.outputDir) |