diff options
Diffstat (limited to 'src/Kotlin/ContentBuilder.kt')
-rw-r--r-- | src/Kotlin/ContentBuilder.kt | 69 |
1 files changed, 62 insertions, 7 deletions
diff --git a/src/Kotlin/ContentBuilder.kt b/src/Kotlin/ContentBuilder.kt index b7290b58..635fc74f 100644 --- a/src/Kotlin/ContentBuilder.kt +++ b/src/Kotlin/ContentBuilder.kt @@ -2,15 +2,20 @@ package org.jetbrains.dokka import org.jetbrains.markdown.MarkdownElementTypes import java.util.ArrayDeque +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor +import org.jetbrains.jet.lang.resolve.name.Name +import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils +import org.jetbrains.jet.lang.resolve.scopes.JetScope +import org.jetbrains.jet.lang.resolve.name.FqName -public fun MarkdownTree.toContent(): Content { +public fun DocumentationBuilder.buildContent(tree: MarkdownTree, descriptor: DeclarationDescriptor): Content { val nodeStack = ArrayDeque<ContentNode>() nodeStack.push(Content()) - visit {(node, text, processChildren) -> + tree.visit {(node, text, processChildren) -> val parent = nodeStack.peek()!! val nodeType = node.getTokenType() - val nodeText = getNodeText(node) + val nodeText = tree.getNodeText(node) when (nodeType) { MarkdownElementTypes.BULLET_LIST -> { nodeStack.push(ContentList()) @@ -39,20 +44,32 @@ public fun MarkdownTree.toContent(): Content { processChildren() parent.append(nodeStack.pop()) } + MarkdownElementTypes.CODE -> { + nodeStack.push(ContentCode()) + processChildren() + parent.append(nodeStack.pop()) + } MarkdownElementTypes.ANONYMOUS_SECTION -> { nodeStack.push(ContentSection("")) processChildren() parent.append(nodeStack.pop()) } + MarkdownElementTypes.DIRECTIVE -> { + val name = tree.findChildByType(node, MarkdownElementTypes.DIRECTIVE_NAME)?.let { tree.getNodeText(it) } ?: "" + val params = tree.findChildByType(node, MarkdownElementTypes.DIRECTIVE_PARAMS)?.let { tree.getNodeText(it) } ?: "" + when (name) { + "code" -> parent.append(functionBody(descriptor, params)) + } + } MarkdownElementTypes.NAMED_SECTION -> { - val label = findChildByType(node, MarkdownElementTypes.SECTION_NAME)?.let { getNodeText(it) } ?: "" + val label = tree.findChildByType(node, MarkdownElementTypes.SECTION_NAME)?.let { tree.getNodeText(it) } ?: "" nodeStack.push(ContentSection(label)) processChildren() 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 target = tree.findChildByType(node, MarkdownElementTypes.TARGET)?.let { tree.getNodeText(it) } ?: "" + val href = tree.findChildByType(node, MarkdownElementTypes.HREF)?.let { tree.getNodeText(it) } val link = if (href != null) ContentExternalLink(href) else ContentExternalLink(target) link.append(ContentText(target)) parent.append(link) @@ -71,7 +88,7 @@ public fun MarkdownTree.toContent(): Content { processChildren() } MarkdownElementTypes.PARA -> { - nodeStack.push(ContentBlock()) + nodeStack.push(ContentParagraph()) processChildren() parent.append(nodeStack.pop()) } @@ -84,3 +101,41 @@ public fun MarkdownTree.toContent(): Content { } +fun DocumentationBuilder.functionBody(descriptor: DeclarationDescriptor, functionName: String): ContentNode { + val scope = getResolutionScope(descriptor) + val rootPackage = session.getModuleDescriptor().getPackage(FqName.ROOT)!! + val rootScope = rootPackage.getMemberScope() + val symbol = resolveInScope(functionName, scope) ?: resolveInScope(functionName, rootScope) + if (symbol == null) + return ContentBlockCode().let() { it.append(ContentText("Unresolved: $functionName")); it } + val psiElement = DescriptorToSourceUtils.descriptorToDeclaration(symbol) + if (psiElement == null) + return ContentBlockCode().let() { it.append(ContentText("Source not found: $functionName")); it } + + return ContentBlockCode().let() { it.append(ContentText(psiElement.getText())); it } +} + +private fun DocumentationBuilder.resolveInScope(functionName: String, scope: JetScope): DeclarationDescriptor? { + var currentScope = scope + val parts = functionName.split('.') + var symbol: DeclarationDescriptor? = null + + for (part in parts) { + // short name + val symbolName = Name.guess(part) + val partSymbol = currentScope.getLocalVariable(symbolName) ?: + currentScope.getProperties(symbolName).firstOrNull() ?: + currentScope.getFunctions(symbolName).firstOrNull() ?: + currentScope.getClassifier(symbolName) ?: + currentScope.getPackage(symbolName) + + if (partSymbol == null) { + symbol = null + break + } + currentScope = getResolutionScope(partSymbol) + symbol = partSymbol + } + + return symbol +}
\ No newline at end of file |