diff options
author | Ilya Ryzhenkov <orangy@jetbrains.com> | 2014-10-03 22:51:44 +0400 |
---|---|---|
committer | Ilya Ryzhenkov <orangy@jetbrains.com> | 2014-10-03 22:51:44 +0400 |
commit | 71cd87e239ba4ba846eb5da04e45a451b8a840cb (patch) | |
tree | a95a0c385c72b0ba20b2b775a460cc87bc51531c /src/Kotlin | |
parent | b642b7c35e63729303094483dc2d176ec5ce7a7d (diff) | |
download | dokka-71cd87e239ba4ba846eb5da04e45a451b8a840cb.tar.gz dokka-71cd87e239ba4ba846eb5da04e45a451b8a840cb.tar.bz2 dokka-71cd87e239ba4ba846eb5da04e45a451b8a840cb.zip |
Resolve links in docs.
Diffstat (limited to 'src/Kotlin')
-rw-r--r-- | src/Kotlin/ContentBuilder.kt | 30 | ||||
-rw-r--r-- | src/Kotlin/CrossReferences.kt | 44 | ||||
-rw-r--r-- | src/Kotlin/DocumentationContext.kt | 2 | ||||
-rw-r--r-- | src/Kotlin/ResolveReferences.kt | 83 |
4 files changed, 104 insertions, 55 deletions
diff --git a/src/Kotlin/ContentBuilder.kt b/src/Kotlin/ContentBuilder.kt index 78bd7eaf..389b2732 100644 --- a/src/Kotlin/ContentBuilder.kt +++ b/src/Kotlin/ContentBuilder.kt @@ -15,50 +15,60 @@ public fun MarkdownTree.toContent(): Content { MarkdownElementTypes.BULLET_LIST -> { nodeStack.push(ContentList()) processChildren() - parent.children.add(nodeStack.pop()) + parent.append(nodeStack.pop()) } MarkdownElementTypes.ORDERED_LIST -> { nodeStack.push(ContentList()) // TODO: add list kind processChildren() - parent.children.add(nodeStack.pop()) + parent.append(nodeStack.pop()) } MarkdownElementTypes.HORIZONTAL_RULE -> { } MarkdownElementTypes.LIST_BLOCK -> { nodeStack.push(ContentBlock()) processChildren() - parent.children.add(nodeStack.pop()) + parent.append(nodeStack.pop()) } MarkdownElementTypes.EMPH -> { nodeStack.push(ContentEmphasis()) processChildren() - parent.children.add(nodeStack.pop()) + parent.append(nodeStack.pop()) } MarkdownElementTypes.STRONG -> { nodeStack.push(ContentStrong()) processChildren() - parent.children.add(nodeStack.pop()) + parent.append(nodeStack.pop()) } MarkdownElementTypes.ANONYMOUS_SECTION -> { nodeStack.push(ContentSection("")) processChildren() - parent.children.add(nodeStack.pop()) + parent.append(nodeStack.pop()) } MarkdownElementTypes.NAMED_SECTION -> { val label = findChildByType(node, MarkdownElementTypes.SECTION_NAME)?.let { getNodeText(it) } ?: "" nodeStack.push(ContentSection(label)) processChildren() - parent.children.add(nodeStack.pop()) + parent.append(nodeStack.pop()) + } + MarkdownElementTypes.LINK -> { + val target = findChildByType(node, MarkdownElementTypes.TARGET)?.let { getNodeText(it) } ?: "" + val href = findChildByType(node, MarkdownElementTypes.HREF)?.let { getNodeText(it) } + val link = if (href != null) + ContentExternalLink(href) + else + ContentNameLink(target) + link.append(ContentText(target)) + parent.append(link) } MarkdownElementTypes.PLAIN_TEXT -> { nodeStack.push(ContentText(nodeText)) processChildren() - parent.children.add(nodeStack.pop()) + parent.append(nodeStack.pop()) } MarkdownElementTypes.END_LINE -> { nodeStack.push(ContentText(nodeText)) processChildren() - parent.children.add(nodeStack.pop()) + parent.append(nodeStack.pop()) } MarkdownElementTypes.BLANK_LINE -> { processChildren() @@ -66,7 +76,7 @@ public fun MarkdownTree.toContent(): Content { MarkdownElementTypes.PARA -> { nodeStack.push(ContentBlock()) processChildren() - parent.children.add(nodeStack.pop()) + parent.append(nodeStack.pop()) } else -> { processChildren() diff --git a/src/Kotlin/CrossReferences.kt b/src/Kotlin/CrossReferences.kt deleted file mode 100644 index c06b81d4..00000000 --- a/src/Kotlin/CrossReferences.kt +++ /dev/null @@ -1,44 +0,0 @@ -package org.jetbrains.dokka - -/** - * 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.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) - } - } - } - - for (child in node.members) { - buildCrossReferences(child) - } - for (child in node.details) { - buildCrossReferences(child) - } -} - diff --git a/src/Kotlin/DocumentationContext.kt b/src/Kotlin/DocumentationContext.kt index 1fada8b3..649543ac 100644 --- a/src/Kotlin/DocumentationContext.kt +++ b/src/Kotlin/DocumentationContext.kt @@ -54,7 +54,7 @@ fun BindingContext.createDocumentationModule(name: String, pkg!!.accept(DocumentationBuildingVisitor(this, options, visitor), documentationModule) } - context.buildCrossReferences(documentationModule) + context.resolveReferences(documentationModule) // TODO: Uncomment for resolve verification // checkResolveChildren(documentationModule) diff --git a/src/Kotlin/ResolveReferences.kt b/src/Kotlin/ResolveReferences.kt new file mode 100644 index 00000000..90e23ffb --- /dev/null +++ b/src/Kotlin/ResolveReferences.kt @@ -0,0 +1,83 @@ +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 ContentNameLink) { + val scope = getResolutionScope(node) + val symbolName = child.name + val symbol = + scope.getLocalVariable(Name.guess(symbolName)) ?: + scope.getProperties(Name.guess(symbolName)).firstOrNull() ?: + scope.getFunctions(Name.guess(symbolName)).firstOrNull() ?: + scope.getClassifier(Name.guess(symbolName)) + + if (symbol != null) { + val targetNode = descriptorToNode[symbol] + if (targetNode != null) { + // we have a doc node for the symbol + val index = content.children.indexOf(child) + content.children.remove(index) + val contentLink = ContentNodeLink(targetNode) + contentLink.children.add(ContentIdentifier(symbolName)) + //contentLink.children.addAll(child.children) + content.children.add(index, contentLink) + } else { + // we don't have a doc node for the symbol, render as identifier + val index = content.children.indexOf(child) + content.children.remove(index) + val contentLink = ContentIdentifier(symbolName) + contentLink.children.addAll(child.children) + content.children.add(index, contentLink) + } + } + } + resolveContentLinks(node, child) + } +}
\ No newline at end of file |