From af81d5a311125fc30dcf9c14fc9bd9c8680e532b Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Tue, 8 Nov 2016 20:21:15 +0300 Subject: Now all sample blocks in kotlin-website wrapped in
...
And small refactoring --- .../kotlin/Formats/KotlinWebsiteFormatService.kt | 26 ++++++++++++++-------- .../main/kotlin/Formats/StructuredFormatService.kt | 20 ++++++++++++----- .../kotlin/Kotlin/DescriptorDocumentationParser.kt | 22 +++++++++--------- core/src/main/kotlin/Model/Content.kt | 3 ++- core/testdata/format/website/overloadGroup.md | 2 +- core/testdata/format/website/sample.md | 6 ++++- 6 files changed, 52 insertions(+), 27 deletions(-) (limited to 'core') diff --git a/core/src/main/kotlin/Formats/KotlinWebsiteFormatService.kt b/core/src/main/kotlin/Formats/KotlinWebsiteFormatService.kt index bc9358ac..edae9976 100644 --- a/core/src/main/kotlin/Formats/KotlinWebsiteFormatService.kt +++ b/core/src/main/kotlin/Formats/KotlinWebsiteFormatService.kt @@ -30,11 +30,13 @@ class KotlinWebsiteOutputBuilder(to: StringBuilder, override fun appendStrikethrough(body: () -> Unit) = wrapInTag("s", body) - private fun div(to: StringBuilder, cssClass: String, block: () -> Unit) { - to.append("
") - insideDiv++ + private fun div(to: StringBuilder, cssClass: String, markdown: Boolean = false, block: () -> Unit) { + to.append("
") + if (!markdown) insideDiv++ block() - insideDiv-- + if (!markdown) insideDiv-- to.append("
\n") } @@ -51,12 +53,18 @@ class KotlinWebsiteOutputBuilder(to: StringBuilder, } } + override fun appendSampleBlockCode(language: String, body: () -> Unit) { + div(to, "sample", true) { + appendBlockCode(language, body) + } + } + override fun appendAsOverloadGroup(to: StringBuilder, block: () -> Unit) { - to.append("
") - ensureParagraph() - block() - ensureParagraph() - to.append("
") + div(to, "overload-group", true) { + ensureParagraph() + block() + ensureParagraph() + } } override fun appendLink(href: String, body: () -> Unit) = wrap("", "", body) diff --git a/core/src/main/kotlin/Formats/StructuredFormatService.kt b/core/src/main/kotlin/Formats/StructuredFormatService.kt index f24c9c2d..3bd06130 100644 --- a/core/src/main/kotlin/Formats/StructuredFormatService.kt +++ b/core/src/main/kotlin/Formats/StructuredFormatService.kt @@ -47,6 +47,7 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, protected abstract fun ensureParagraph() + open fun appendSampleBlockCode(language: String, body: () -> Unit) = appendBlockCode(language, body) abstract fun appendBlockCode(language: String, body: () -> Unit) abstract fun appendHeader(level: Int = 1, body: () -> Unit) abstract fun appendParagraph(body: () -> Unit) @@ -143,13 +144,22 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, } } - is ContentBlockCode -> appendBlockCode(content.language) { - for ((index, contentNode) in content.children.withIndex()) { - appendContent(contentNode) - if (index < content.children.size - 1) { - to.append("\n") + is ContentBlockSampleCode, is ContentBlockCode -> { + content as ContentBlockCode + fun appendBlockCodeContent() { + for ((index, contentNode) in content.children.withIndex()) { + appendContent(contentNode) + if (index < content.children.size - 1) { + to.append("\n") + } } } + when (content) { + is ContentBlockSampleCode -> + appendSampleBlockCode(content.language, ::appendBlockCodeContent) + is ContentBlockCode -> + appendBlockCode(content.language, ::appendBlockCodeContent) + } } is ContentHeading -> appendHeader(content.level) { appendContent(content.children) } is ContentBlock -> appendContent(content.children) diff --git a/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt b/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt index 941d071d..2fc268e8 100644 --- a/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt +++ b/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.kdoc.findKDoc import org.jetbrains.kotlin.idea.kdoc.getKDocLinkResolutionScope import org.jetbrains.kotlin.incremental.components.NoLookupLocation +import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor @@ -60,10 +61,10 @@ class DescriptorDocumentationParser if (kdoc is KDocSection) { val tags = kdoc.getTags() tags.forEach { - when (it.name) { - "sample" -> + when (it.knownTag) { + KDocKnownTag.SAMPLE -> content.append(functionBody(descriptor, it.getSubjectName())) - "see" -> + KDocKnownTag.SEE -> content.addTagToSeeAlso(descriptor, it) else -> { val section = content.addSection(javadocSectionDisplayName(it.name), it.getSubjectName()) @@ -147,7 +148,7 @@ class DescriptorDocumentationParser private fun functionBody(descriptor: DeclarationDescriptor, functionName: String?): ContentNode { if (functionName == null) { logger.warn("Missing function name in @sample in ${descriptor.signature()}") - return ContentBlockCode().let() { it.append(ContentText("Missing function name in @sample")); it } + return ContentBlockSampleCode().let { it.append(ContentText("//Missing function name in @sample")); it } } val scope = getKDocLinkResolutionScope(resolutionFacade, descriptor) val rootPackage = resolutionFacade.moduleDescriptor.getPackage(FqName.ROOT) @@ -155,16 +156,16 @@ class DescriptorDocumentationParser val symbol = resolveInScope(functionName, scope) ?: resolveInScope(functionName, rootScope) if (symbol == null) { logger.warn("Unresolved function $functionName in @sample in ${descriptor.signature()}") - return ContentBlockCode().let() { it.append(ContentText("Unresolved: $functionName")); it } + return ContentBlockSampleCode().let { it.append(ContentText("//Unresolved: $functionName")); it } } val psiElement = DescriptorToSourceUtils.descriptorToDeclaration(symbol) if (psiElement == null) { logger.warn("Can't find source for function $functionName in @sample in ${descriptor.signature()}") - return ContentBlockCode().let() { it.append(ContentText("Source not found: $functionName")); it } + return ContentBlockSampleCode().let { it.append(ContentText("//Source not found: $functionName")); it } } val text = when (psiElement) { - is KtDeclarationWithBody -> ContentBlockCode().let() { + is KtDeclarationWithBody -> ContentBlockCode().let { val bodyExpression = psiElement.bodyExpression when (bodyExpression) { is KtBlockExpression -> bodyExpression.text.removeSurrounding("{", "}") @@ -174,10 +175,10 @@ class DescriptorDocumentationParser else -> psiElement.text } - val lines = text.trimEnd().split("\n".toRegex()).toTypedArray().filterNot { it.length == 0 } - val indent = lines.map { it.takeWhile { it.isWhitespace() }.count() }.min() ?: 0 + val lines = text.trimEnd().split("\n".toRegex()).toTypedArray().filterNot(String::isEmpty) + val indent = lines.map { it.takeWhile(Char::isWhitespace).count() }.min() ?: 0 val finalText = lines.map { it.drop(indent) }.joinToString("\n") - return ContentBlockCode("kotlin").let() { it.append(ContentText(finalText)); it } + return ContentBlockSampleCode().let { it.append(ContentText(finalText)); it } } private fun resolveInScope(functionName: String, scope: ResolutionScope): DeclarationDescriptor? { @@ -197,6 +198,7 @@ class DescriptorDocumentationParser symbol = null break } + @Suppress("IfThenToElvis") currentScope = if (partSymbol is ClassDescriptor) partSymbol.defaultType.memberScope else if (partSymbol is PackageViewDescriptor) diff --git a/core/src/main/kotlin/Model/Content.kt b/core/src/main/kotlin/Model/Content.kt index 0a38a524..fcf94c12 100644 --- a/core/src/main/kotlin/Model/Content.kt +++ b/core/src/main/kotlin/Model/Content.kt @@ -82,7 +82,8 @@ class ContentEmphasis() : ContentBlock() class ContentStrong() : ContentBlock() class ContentStrikethrough() : ContentBlock() class ContentCode() : ContentBlock() -class ContentBlockCode(val language: String = "") : ContentBlock() +open class ContentBlockCode(val language: String = "") : ContentBlock() +class ContentBlockSampleCode(language: String = "kotlin") : ContentBlockCode(language) abstract class ContentNodeLink() : ContentBlock() { abstract val node: DocumentationNode? diff --git a/core/testdata/format/website/overloadGroup.md b/core/testdata/format/website/overloadGroup.md index 81cb7822..d81f86bf 100644 --- a/core/testdata/format/website/overloadGroup.md +++ b/core/testdata/format/website/overloadGroup.md @@ -31,4 +31,4 @@ Spell ID for future casts **Return** Spell ID for future casts -
\ No newline at end of file + diff --git a/core/testdata/format/website/sample.md b/core/testdata/format/website/sample.md index 1a683da7..374303c0 100644 --- a/core/testdata/format/website/sample.md +++ b/core/testdata/format/website/sample.md @@ -14,6 +14,8 @@ layout: api Groups elements of the original sequence by the key returned by the given keySelector function applied to each element and returns a map where each group key is associated with a list of corresponding elements. +
+ ``` kotlin if (true) { println(property) @@ -22,8 +24,10 @@ if (true) {
+ +
fun foo(i: Int): Int
-
\ No newline at end of file + -- cgit From dc99d1fd5c066ac6083f09e23e52cf6c592768e4 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Thu, 10 Nov 2016 18:55:14 +0300 Subject: Added //sampleStart //sampleEnd to samples on kotlin website --- .../kotlin/Formats/KotlinWebsiteFormatService.kt | 9 +++++++-- .../main/kotlin/Formats/StructuredFormatService.kt | 12 ++++++------ .../kotlin/Kotlin/DescriptorDocumentationParser.kt | 20 ++++++++++++++++---- core/src/main/kotlin/Model/Content.kt | 2 +- core/testdata/format/website/sample.md | 5 +++++ 5 files changed, 35 insertions(+), 13 deletions(-) (limited to 'core') diff --git a/core/src/main/kotlin/Formats/KotlinWebsiteFormatService.kt b/core/src/main/kotlin/Formats/KotlinWebsiteFormatService.kt index edae9976..ac70bb02 100644 --- a/core/src/main/kotlin/Formats/KotlinWebsiteFormatService.kt +++ b/core/src/main/kotlin/Formats/KotlinWebsiteFormatService.kt @@ -53,9 +53,14 @@ class KotlinWebsiteOutputBuilder(to: StringBuilder, } } - override fun appendSampleBlockCode(language: String, body: () -> Unit) { + override fun appendSampleBlockCode(language: String, imports: () -> Unit, body: () -> Unit) { div(to, "sample", true) { - appendBlockCode(language, body) + appendBlockCode(language) { + imports() + wrap("\nfun main(args: Array) {", "}") { + wrap("\n//sampleStart\n", "\n//sampleEnd\n", body) + } + } } } diff --git a/core/src/main/kotlin/Formats/StructuredFormatService.kt b/core/src/main/kotlin/Formats/StructuredFormatService.kt index 3bd06130..183282ea 100644 --- a/core/src/main/kotlin/Formats/StructuredFormatService.kt +++ b/core/src/main/kotlin/Formats/StructuredFormatService.kt @@ -47,7 +47,7 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, protected abstract fun ensureParagraph() - open fun appendSampleBlockCode(language: String, body: () -> Unit) = appendBlockCode(language, body) + open fun appendSampleBlockCode(language: String, imports: () -> Unit, body: () -> Unit) = appendBlockCode(language, body) abstract fun appendBlockCode(language: String, body: () -> Unit) abstract fun appendHeader(level: Int = 1, body: () -> Unit) abstract fun appendParagraph(body: () -> Unit) @@ -146,19 +146,19 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, is ContentBlockSampleCode, is ContentBlockCode -> { content as ContentBlockCode - fun appendBlockCodeContent() { - for ((index, contentNode) in content.children.withIndex()) { + fun ContentBlockCode.appendBlockCodeContent() { + for ((index, contentNode) in this.children.withIndex()) { appendContent(contentNode) - if (index < content.children.size - 1) { + if (index < this.children.size - 1) { to.append("\n") } } } when (content) { is ContentBlockSampleCode -> - appendSampleBlockCode(content.language, ::appendBlockCodeContent) + appendSampleBlockCode(content.language, content.importsBlock::appendBlockCodeContent, { content.appendBlockCodeContent() }) is ContentBlockCode -> - appendBlockCode(content.language, ::appendBlockCodeContent) + appendBlockCode(content.language, { content.appendBlockCodeContent() }) } } is ContentHeading -> appendHeader(content.level) { appendContent(content.children) } diff --git a/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt b/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt index 2fc268e8..532b186c 100644 --- a/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt +++ b/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtBlockExpression import org.jetbrains.kotlin.psi.KtDeclarationWithBody +import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.annotations.argumentValue @@ -148,7 +149,7 @@ class DescriptorDocumentationParser private fun functionBody(descriptor: DeclarationDescriptor, functionName: String?): ContentNode { if (functionName == null) { logger.warn("Missing function name in @sample in ${descriptor.signature()}") - return ContentBlockSampleCode().let { it.append(ContentText("//Missing function name in @sample")); it } + return ContentBlockSampleCode().apply { append(ContentText("//Missing function name in @sample")) } } val scope = getKDocLinkResolutionScope(resolutionFacade, descriptor) val rootPackage = resolutionFacade.moduleDescriptor.getPackage(FqName.ROOT) @@ -156,12 +157,12 @@ class DescriptorDocumentationParser val symbol = resolveInScope(functionName, scope) ?: resolveInScope(functionName, rootScope) if (symbol == null) { logger.warn("Unresolved function $functionName in @sample in ${descriptor.signature()}") - return ContentBlockSampleCode().let { it.append(ContentText("//Unresolved: $functionName")); it } + return ContentBlockSampleCode().apply { append(ContentText("//Unresolved: $functionName")) } } val psiElement = DescriptorToSourceUtils.descriptorToDeclaration(symbol) if (psiElement == null) { logger.warn("Can't find source for function $functionName in @sample in ${descriptor.signature()}") - return ContentBlockSampleCode().let { it.append(ContentText("//Source not found: $functionName")); it } + return ContentBlockSampleCode().apply { append(ContentText("//Source not found: $functionName")) } } val text = when (psiElement) { @@ -178,7 +179,18 @@ class DescriptorDocumentationParser val lines = text.trimEnd().split("\n".toRegex()).toTypedArray().filterNot(String::isEmpty) val indent = lines.map { it.takeWhile(Char::isWhitespace).count() }.min() ?: 0 val finalText = lines.map { it.drop(indent) }.joinToString("\n") - return ContentBlockSampleCode().let { it.append(ContentText(finalText)); it } + + val psiFile = psiElement.containingFile + val importsBlock = if (psiFile is KtFile) { + ContentBlockCode("kotlin").apply { + append(ContentText(psiFile.importList?.text ?: "")) + } + } else { + ContentBlockCode("") + } + + + return ContentBlockSampleCode(importsBlock = importsBlock).apply { append(ContentText(finalText)) } } private fun resolveInScope(functionName: String, scope: ResolutionScope): DeclarationDescriptor? { diff --git a/core/src/main/kotlin/Model/Content.kt b/core/src/main/kotlin/Model/Content.kt index fcf94c12..ecf75b20 100644 --- a/core/src/main/kotlin/Model/Content.kt +++ b/core/src/main/kotlin/Model/Content.kt @@ -83,7 +83,7 @@ class ContentStrong() : ContentBlock() class ContentStrikethrough() : ContentBlock() class ContentCode() : ContentBlock() open class ContentBlockCode(val language: String = "") : ContentBlock() -class ContentBlockSampleCode(language: String = "kotlin") : ContentBlockCode(language) +class ContentBlockSampleCode(language: String = "kotlin", val importsBlock: ContentBlockCode = ContentBlockCode(language)) : ContentBlockCode(language) abstract class ContentNodeLink() : ContentBlock() { abstract val node: DocumentationNode? diff --git a/core/testdata/format/website/sample.md b/core/testdata/format/website/sample.md index 374303c0..203f1b02 100644 --- a/core/testdata/format/website/sample.md +++ b/core/testdata/format/website/sample.md @@ -17,9 +17,14 @@ applied to each element and returns a map where each group key is associated wit
``` kotlin + +fun main(args: Array) { +//sampleStart if (true) { println(property) } +//sampleEnd +} ```
-- cgit From 47790d166100dc50d797fc0312b9b3fe0e7e9d7f Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Mon, 14 Nov 2016 18:08:17 +0300 Subject: Replacing assertPrints, assertTrue to println for kotlin-website samples, Added SampleProcessingService to FormatDescriptor --- core/src/main/kotlin/Formats/FormatDescriptor.kt | 2 + core/src/main/kotlin/Formats/StandardFormats.kt | 6 ++ .../kotlin/Kotlin/DescriptorDocumentationParser.kt | 83 +--------------- .../Samples/DefaultSampleProcessingService.kt | 106 +++++++++++++++++++++ .../KotlinWebsiteSampleProcessingService.kt | 81 ++++++++++++++++ .../main/kotlin/Samples/SampleProcessingService.kt | 8 ++ core/src/main/kotlin/Utilities/DokkaModule.kt | 2 + core/src/main/kotlin/javadoc/dokka-adapters.kt | 2 + core/src/test/kotlin/TestAPI.kt | 6 +- .../test/kotlin/format/KotlinWebSiteFormatTest.kt | 6 +- core/testdata/format/website/sampleWithAsserts.kt | 15 +++ core/testdata/format/website/sampleWithAsserts.md | 23 +++++ 12 files changed, 259 insertions(+), 81 deletions(-) create mode 100644 core/src/main/kotlin/Samples/DefaultSampleProcessingService.kt create mode 100644 core/src/main/kotlin/Samples/KotlinWebsiteSampleProcessingService.kt create mode 100644 core/src/main/kotlin/Samples/SampleProcessingService.kt create mode 100644 core/testdata/format/website/sampleWithAsserts.kt create mode 100644 core/testdata/format/website/sampleWithAsserts.md (limited to 'core') diff --git a/core/src/main/kotlin/Formats/FormatDescriptor.kt b/core/src/main/kotlin/Formats/FormatDescriptor.kt index e384f223..58c9472b 100644 --- a/core/src/main/kotlin/Formats/FormatDescriptor.kt +++ b/core/src/main/kotlin/Formats/FormatDescriptor.kt @@ -1,5 +1,6 @@ package org.jetbrains.dokka.Formats +import Samples.SampleProcessingService import org.jetbrains.dokka.* import kotlin.reflect.KClass @@ -9,4 +10,5 @@ interface FormatDescriptor { val generatorServiceClass: KClass val packageDocumentationBuilderClass: KClass val javaDocumentationBuilderClass: KClass + val sampleProcessingService: KClass } diff --git a/core/src/main/kotlin/Formats/StandardFormats.kt b/core/src/main/kotlin/Formats/StandardFormats.kt index fdc8eb9e..45a653b0 100644 --- a/core/src/main/kotlin/Formats/StandardFormats.kt +++ b/core/src/main/kotlin/Formats/StandardFormats.kt @@ -1,5 +1,8 @@ package org.jetbrains.dokka.Formats +import Samples.DefaultSampleProcessingService +import Samples.KotlinWebsiteSampleProcessingService +import Samples.SampleProcessingService import org.jetbrains.dokka.* import kotlin.reflect.KClass @@ -9,6 +12,7 @@ abstract class KotlinFormatDescriptorBase : FormatDescriptor { override val generatorServiceClass = FileGenerator::class override val outlineServiceClass: KClass? = null + override val sampleProcessingService: KClass = DefaultSampleProcessingService::class } class HtmlFormatDescriptor : KotlinFormatDescriptorBase() { @@ -22,11 +26,13 @@ class HtmlAsJavaFormatDescriptor : FormatDescriptor { override val generatorServiceClass = FileGenerator::class override val packageDocumentationBuilderClass = KotlinAsJavaDocumentationBuilder::class override val javaDocumentationBuilderClass = JavaPsiDocumentationBuilder::class + override val sampleProcessingService: KClass = DefaultSampleProcessingService::class } class KotlinWebsiteFormatDescriptor : KotlinFormatDescriptorBase() { override val formatServiceClass = KotlinWebsiteFormatService::class override val outlineServiceClass = YamlOutlineService::class + override val sampleProcessingService: KClass = KotlinWebsiteSampleProcessingService::class } class JekyllFormatDescriptor : KotlinFormatDescriptorBase() { diff --git a/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt b/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt index 532b186c..a7aa6452 100644 --- a/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt +++ b/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt @@ -1,5 +1,6 @@ package org.jetbrains.dokka.Kotlin +import Samples.SampleProcessingService import com.google.inject.Inject import com.intellij.psi.PsiDocCommentOwner import com.intellij.psi.PsiNamedElement @@ -17,6 +18,7 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtBlockExpression +import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtDeclarationWithBody import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils @@ -33,7 +35,8 @@ class DescriptorDocumentationParser val logger: DokkaLogger, val linkResolver: DeclarationLinkResolver, val resolutionFacade: DokkaResolutionFacade, - val refGraph: NodeReferenceGraph) + val refGraph: NodeReferenceGraph, + val sampleService: SampleProcessingService) { fun parseDocumentation(descriptor: DeclarationDescriptor, inline: Boolean = false): Content = parseDocumentationAndDetails(descriptor, inline).first @@ -64,7 +67,7 @@ class DescriptorDocumentationParser tags.forEach { when (it.knownTag) { KDocKnownTag.SAMPLE -> - content.append(functionBody(descriptor, it.getSubjectName())) + content.append(sampleService.resolveSample(descriptor, it.getSubjectName())) KDocKnownTag.SEE -> content.addTagToSeeAlso(descriptor, it) else -> { @@ -146,80 +149,4 @@ class DescriptorDocumentationParser } } - private fun functionBody(descriptor: DeclarationDescriptor, functionName: String?): ContentNode { - if (functionName == null) { - logger.warn("Missing function name in @sample in ${descriptor.signature()}") - return ContentBlockSampleCode().apply { append(ContentText("//Missing function name in @sample")) } - } - val scope = getKDocLinkResolutionScope(resolutionFacade, descriptor) - val rootPackage = resolutionFacade.moduleDescriptor.getPackage(FqName.ROOT) - val rootScope = rootPackage.memberScope - val symbol = resolveInScope(functionName, scope) ?: resolveInScope(functionName, rootScope) - if (symbol == null) { - logger.warn("Unresolved function $functionName in @sample in ${descriptor.signature()}") - return ContentBlockSampleCode().apply { append(ContentText("//Unresolved: $functionName")) } - } - val psiElement = DescriptorToSourceUtils.descriptorToDeclaration(symbol) - if (psiElement == null) { - logger.warn("Can't find source for function $functionName in @sample in ${descriptor.signature()}") - return ContentBlockSampleCode().apply { append(ContentText("//Source not found: $functionName")) } - } - - val text = when (psiElement) { - is KtDeclarationWithBody -> ContentBlockCode().let { - val bodyExpression = psiElement.bodyExpression - when (bodyExpression) { - is KtBlockExpression -> bodyExpression.text.removeSurrounding("{", "}") - else -> bodyExpression!!.text - } - } - else -> psiElement.text - } - - val lines = text.trimEnd().split("\n".toRegex()).toTypedArray().filterNot(String::isEmpty) - val indent = lines.map { it.takeWhile(Char::isWhitespace).count() }.min() ?: 0 - val finalText = lines.map { it.drop(indent) }.joinToString("\n") - - val psiFile = psiElement.containingFile - val importsBlock = if (psiFile is KtFile) { - ContentBlockCode("kotlin").apply { - append(ContentText(psiFile.importList?.text ?: "")) - } - } else { - ContentBlockCode("") - } - - - return ContentBlockSampleCode(importsBlock = importsBlock).apply { append(ContentText(finalText)) } - } - - private fun resolveInScope(functionName: String, scope: ResolutionScope): DeclarationDescriptor? { - var currentScope = scope - val parts = functionName.split('.') - - var symbol: DeclarationDescriptor? = null - - for (part in parts) { - // short name - val symbolName = Name.identifier(part) - val partSymbol = currentScope.getContributedDescriptors(DescriptorKindFilter.ALL, { it == symbolName }) - .filter { it.name == symbolName } - .firstOrNull() - - if (partSymbol == null) { - symbol = null - break - } - @Suppress("IfThenToElvis") - currentScope = if (partSymbol is ClassDescriptor) - partSymbol.defaultType.memberScope - else if (partSymbol is PackageViewDescriptor) - partSymbol.memberScope - else - getKDocLinkResolutionScope(resolutionFacade, partSymbol) - symbol = partSymbol - } - - return symbol - } } diff --git a/core/src/main/kotlin/Samples/DefaultSampleProcessingService.kt b/core/src/main/kotlin/Samples/DefaultSampleProcessingService.kt new file mode 100644 index 00000000..26841ea6 --- /dev/null +++ b/core/src/main/kotlin/Samples/DefaultSampleProcessingService.kt @@ -0,0 +1,106 @@ +package Samples + +import com.google.inject.Inject +import com.intellij.psi.PsiElement +import org.jetbrains.dokka.* +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.PackageViewDescriptor +import org.jetbrains.kotlin.idea.kdoc.getKDocLinkResolutionScope +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.KtBlockExpression +import org.jetbrains.kotlin.psi.KtDeclarationWithBody +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils +import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter +import org.jetbrains.kotlin.resolve.scopes.ResolutionScope + + +open class DefaultSampleProcessingService +@Inject constructor(val options: DocumentationOptions, + val logger: DokkaLogger, + val resolutionFacade: DokkaResolutionFacade) + : SampleProcessingService { + + override fun resolveSample(descriptor: DeclarationDescriptor, functionName: String?): ContentNode { + if (functionName == null) { + logger.warn("Missing function name in @sample in ${descriptor.signature()}") + return ContentBlockSampleCode().apply { append(ContentText("//Missing function name in @sample")) } + } + val scope = getKDocLinkResolutionScope(resolutionFacade, descriptor) + val rootPackage = resolutionFacade.moduleDescriptor.getPackage(FqName.ROOT) + val rootScope = rootPackage.memberScope + val symbol = resolveInScope(functionName, scope) ?: resolveInScope(functionName, rootScope) + if (symbol == null) { + logger.warn("Unresolved function $functionName in @sample in ${descriptor.signature()}") + return ContentBlockSampleCode().apply { append(ContentText("//Unresolved: $functionName")) } + } + val psiElement = DescriptorToSourceUtils.descriptorToDeclaration(symbol) + if (psiElement == null) { + logger.warn("Can't find source for function $functionName in @sample in ${descriptor.signature()}") + return ContentBlockSampleCode().apply { append(ContentText("//Source not found: $functionName")) } + } + + val text = processSampleBody(psiElement) + + val lines = text.trimEnd().split("\n".toRegex()).toTypedArray().filterNot(String::isEmpty) + val indent = lines.map { it.takeWhile(Char::isWhitespace).count() }.min() ?: 0 + val finalText = lines.map { it.drop(indent) }.joinToString("\n") + + return ContentBlockSampleCode(importsBlock = processImports(psiElement)).apply { append(ContentText(finalText)) } + } + + protected open fun processSampleBody(psiElement: PsiElement): String = when (psiElement) { + is KtDeclarationWithBody -> { + val bodyExpression = psiElement.bodyExpression + when (bodyExpression) { + is KtBlockExpression -> bodyExpression.text.removeSurrounding("{", "}") + else -> bodyExpression!!.text + } + } + else -> psiElement.text + } + + protected open fun processImports(psiElement: PsiElement): ContentBlockCode { + val psiFile = psiElement.containingFile + if (psiFile is KtFile) { + return ContentBlockCode("kotlin").apply { + append(ContentText(psiFile.importList?.text ?: "")) + } + } else { + return ContentBlockCode("") + } + } + + private fun resolveInScope(functionName: String, scope: ResolutionScope): DeclarationDescriptor? { + var currentScope = scope + val parts = functionName.split('.') + + var symbol: DeclarationDescriptor? = null + + for (part in parts) { + // short name + val symbolName = Name.identifier(part) + val partSymbol = currentScope.getContributedDescriptors(DescriptorKindFilter.ALL, { it == symbolName }) + .filter { it.name == symbolName } + .firstOrNull() + + if (partSymbol == null) { + symbol = null + break + } + @Suppress("IfThenToElvis") + currentScope = if (partSymbol is ClassDescriptor) + partSymbol.defaultType.memberScope + else if (partSymbol is PackageViewDescriptor) + partSymbol.memberScope + else + getKDocLinkResolutionScope(resolutionFacade, partSymbol) + symbol = partSymbol + } + + return symbol + } +} + diff --git a/core/src/main/kotlin/Samples/KotlinWebsiteSampleProcessingService.kt b/core/src/main/kotlin/Samples/KotlinWebsiteSampleProcessingService.kt new file mode 100644 index 00000000..864734ea --- /dev/null +++ b/core/src/main/kotlin/Samples/KotlinWebsiteSampleProcessingService.kt @@ -0,0 +1,81 @@ +package Samples + +import com.google.inject.Inject +import com.intellij.openapi.util.TextRange +import com.intellij.psi.PsiElement +import org.jetbrains.dokka.DocumentationOptions +import org.jetbrains.dokka.DokkaLogger +import org.jetbrains.dokka.DokkaResolutionFacade +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.startOffset +import java.util.* + +open class KotlinWebsiteSampleProcessingService +@Inject constructor(options: DocumentationOptions, + logger: DokkaLogger, + resolutionFacade: DokkaResolutionFacade) + : DefaultSampleProcessingService(options, logger, resolutionFacade) { + + + fun buildReplacementData(psiElement: PsiElement): Map { + + val result = TreeMap({ o1, o2 -> o1.startOffset.compareTo(o2.startOffset) }) + fun convertAssertPrints(expression: KtCallExpression) { + val (argument, commentArgument) = expression.valueArguments + val comment = commentArgument.getArgumentExpression() as KtStringTemplateExpression + val commentText = comment.entries.joinToString("") { it.text } + result[expression.textRange] = "println(${argument.text}) //$commentText" + } + + fun convertAssertTrue(expression: KtCallExpression) { + val (argument) = expression.valueArguments + result[expression.textRange] = "println(\"${argument.text} is \${${argument.text}}\") //true " + } + + if (psiElement is KtElement) { + val visitor = object : KtTreeVisitor() { + override fun visitCallExpression(expression: KtCallExpression, data: Any?): Void? { + when (expression.calleeExpression?.text) { + "assertPrints" -> convertAssertPrints(expression) + "assertTrue" -> convertAssertTrue(expression) + else -> super.visitCallExpression(expression, data) + } + return null + } + } + psiElement.acceptChildren(visitor) + } + return result + } + + private fun String.applyReplacements(baseOffset: Int, replacementData: Map): String { + val partsList = arrayListOf() + var prevRange = TextRange(0, baseOffset) + for ((range, replacement) in replacementData) { + partsList.add(substring(prevRange.endOffset - baseOffset, range.startOffset - baseOffset)) + partsList.add(replacement) + prevRange = range + } + partsList.add(substring(prevRange.endOffset - baseOffset)) + return partsList.joinToString(separator = "") + } + + + override fun processSampleBody(psiElement: PsiElement): String { + + val replacementData = buildReplacementData(psiElement) + + return when (psiElement) { + is KtDeclarationWithBody -> { + val bodyExpression = psiElement.bodyExpression + val bodyExpressionText = bodyExpression!!.text.applyReplacements(bodyExpression.startOffset, replacementData) + when (bodyExpression) { + is KtBlockExpression -> bodyExpressionText.removeSurrounding("{", "}") + else -> bodyExpressionText + } + } + else -> psiElement.text.applyReplacements(psiElement.startOffset, replacementData) + } + } +} + diff --git a/core/src/main/kotlin/Samples/SampleProcessingService.kt b/core/src/main/kotlin/Samples/SampleProcessingService.kt new file mode 100644 index 00000000..61abda6d --- /dev/null +++ b/core/src/main/kotlin/Samples/SampleProcessingService.kt @@ -0,0 +1,8 @@ +package Samples + +import org.jetbrains.dokka.ContentNode +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor + +interface SampleProcessingService { + fun resolveSample(descriptor: DeclarationDescriptor, functionName: String?): ContentNode +} \ No newline at end of file diff --git a/core/src/main/kotlin/Utilities/DokkaModule.kt b/core/src/main/kotlin/Utilities/DokkaModule.kt index 1eb82313..4b2a99d3 100644 --- a/core/src/main/kotlin/Utilities/DokkaModule.kt +++ b/core/src/main/kotlin/Utilities/DokkaModule.kt @@ -1,5 +1,6 @@ package org.jetbrains.dokka.Utilities +import Samples.SampleProcessingService import com.google.inject.Binder import com.google.inject.Module import com.google.inject.Provider @@ -44,6 +45,7 @@ class DokkaModule(val environment: AnalysisEnvironment, } binder.bind().to(descriptor.packageDocumentationBuilderClass.java) binder.bind().to(descriptor.javaDocumentationBuilderClass.java) + binder.bind().to(descriptor.sampleProcessingService.java) binder.bind().to(descriptor.generatorServiceClass.java) diff --git a/core/src/main/kotlin/javadoc/dokka-adapters.kt b/core/src/main/kotlin/javadoc/dokka-adapters.kt index 23ee1702..e3a58331 100644 --- a/core/src/main/kotlin/javadoc/dokka-adapters.kt +++ b/core/src/main/kotlin/javadoc/dokka-adapters.kt @@ -1,5 +1,6 @@ package org.jetbrains.dokka.javadoc +import Samples.DefaultSampleProcessingService import com.google.inject.Inject import com.sun.tools.doclets.formats.html.HtmlDoclet import org.jetbrains.dokka.* @@ -27,4 +28,5 @@ class JavadocFormatDescriptor : FormatDescriptor { override val generatorServiceClass = JavadocGenerator::class override val packageDocumentationBuilderClass = KotlinAsJavaDocumentationBuilder::class override val javaDocumentationBuilderClass = JavaPsiDocumentationBuilder::class + override val sampleProcessingService = DefaultSampleProcessingService::class } diff --git a/core/src/test/kotlin/TestAPI.kt b/core/src/test/kotlin/TestAPI.kt index 508d28fc..7197d2c4 100644 --- a/core/src/test/kotlin/TestAPI.kt +++ b/core/src/test/kotlin/TestAPI.kt @@ -125,8 +125,9 @@ fun verifyOutput(roots: Array, outputExtension: String, withJdk: Boolean = false, withKotlinRuntime: Boolean = false, + format: String = "html", outputGenerator: (DocumentationModule, StringBuilder) -> Unit) { - verifyModel(*roots, withJdk = withJdk, withKotlinRuntime = withKotlinRuntime) { + verifyModel(*roots, withJdk = withJdk, withKotlinRuntime = withKotlinRuntime, format = format) { verifyModelOutput(it, outputExtension, outputGenerator, roots.first().path) } } @@ -147,8 +148,9 @@ fun verifyOutput(path: String, outputExtension: String, withJdk: Boolean = false, withKotlinRuntime: Boolean = false, + format: String = "html", outputGenerator: (DocumentationModule, StringBuilder) -> Unit) { - verifyOutput(arrayOf(contentRootFromPath(path)), outputExtension, withJdk, withKotlinRuntime, outputGenerator) + verifyOutput(arrayOf(contentRootFromPath(path)), outputExtension, withJdk, withKotlinRuntime, format, outputGenerator) } fun verifyJavaOutput(path: String, diff --git a/core/src/test/kotlin/format/KotlinWebSiteFormatTest.kt b/core/src/test/kotlin/format/KotlinWebSiteFormatTest.kt index e7419ec8..e7677862 100644 --- a/core/src/test/kotlin/format/KotlinWebSiteFormatTest.kt +++ b/core/src/test/kotlin/format/KotlinWebSiteFormatTest.kt @@ -19,8 +19,12 @@ class KotlinWebSiteFormatTest { verifyKWSNodeByName("overloadGroup", "magic") } + @Test fun sampleWithAsserts() { + verifyKWSNodeByName("sampleWithAsserts", "a") + } + private fun verifyKWSNodeByName(fileName: String, name: String) { - verifyOutput("testdata/format/website/$fileName.kt", ".md") { model, output -> + verifyOutput("testdata/format/website/$fileName.kt", ".md", format = "kotlin-website") { model, output -> kwsService.createOutputBuilder(output, tempLocation).appendNodes(model.members.single().members.filter { it.name == name }) } } diff --git a/core/testdata/format/website/sampleWithAsserts.kt b/core/testdata/format/website/sampleWithAsserts.kt new file mode 100644 index 00000000..bb9732d5 --- /dev/null +++ b/core/testdata/format/website/sampleWithAsserts.kt @@ -0,0 +1,15 @@ +/** + * @sample sample + */ +fun a(): String { + return "Hello, Work" +} + +fun b(): String { + return "Hello, Rest" +} + +fun sample() { + assertPrints(a(), "Hello, Work") + assertTrue(a() == b()) +} \ No newline at end of file diff --git a/core/testdata/format/website/sampleWithAsserts.md b/core/testdata/format/website/sampleWithAsserts.md new file mode 100644 index 00000000..3353ce46 --- /dev/null +++ b/core/testdata/format/website/sampleWithAsserts.md @@ -0,0 +1,23 @@ +--- +title: a - test +layout: api +--- + + + +# a + +
fun a(): String
+
+ +``` kotlin + +fun main(args: Array) { +//sampleStart +println(a()) //Hello, Work +println("a() == b() is ${a() == b()}") //true +//sampleEnd +} +``` + +
-- cgit From 875e7e5e39c6c1668729685bbc7f51bc07aed4b6 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Mon, 14 Nov 2016 20:52:19 +0300 Subject: Post review fixes, now building text in single pass. --- core/src/main/kotlin/Formats/FormatDescriptor.kt | 2 +- core/src/main/kotlin/Formats/StandardFormats.kt | 6 +- .../kotlin/Kotlin/DescriptorDocumentationParser.kt | 10 +-- .../Samples/DefaultSampleProcessingService.kt | 2 +- .../KotlinWebsiteSampleProcessingService.kt | 87 +++++++++++----------- .../main/kotlin/Samples/SampleProcessingService.kt | 2 +- core/src/main/kotlin/Utilities/DokkaModule.kt | 2 +- core/src/main/kotlin/javadoc/dokka-adapters.kt | 2 +- core/testdata/format/website/sampleWithAsserts.md | 4 +- 9 files changed, 54 insertions(+), 63 deletions(-) (limited to 'core') diff --git a/core/src/main/kotlin/Formats/FormatDescriptor.kt b/core/src/main/kotlin/Formats/FormatDescriptor.kt index 58c9472b..7cc50acb 100644 --- a/core/src/main/kotlin/Formats/FormatDescriptor.kt +++ b/core/src/main/kotlin/Formats/FormatDescriptor.kt @@ -1,7 +1,7 @@ package org.jetbrains.dokka.Formats -import Samples.SampleProcessingService import org.jetbrains.dokka.* +import org.jetbrains.dokka.Samples.SampleProcessingService import kotlin.reflect.KClass interface FormatDescriptor { diff --git a/core/src/main/kotlin/Formats/StandardFormats.kt b/core/src/main/kotlin/Formats/StandardFormats.kt index 45a653b0..dabde881 100644 --- a/core/src/main/kotlin/Formats/StandardFormats.kt +++ b/core/src/main/kotlin/Formats/StandardFormats.kt @@ -1,9 +1,9 @@ package org.jetbrains.dokka.Formats -import Samples.DefaultSampleProcessingService -import Samples.KotlinWebsiteSampleProcessingService -import Samples.SampleProcessingService import org.jetbrains.dokka.* +import org.jetbrains.dokka.Samples.DefaultSampleProcessingService +import org.jetbrains.dokka.Samples.KotlinWebsiteSampleProcessingService +import org.jetbrains.dokka.Samples.SampleProcessingService import kotlin.reflect.KClass abstract class KotlinFormatDescriptorBase : FormatDescriptor { diff --git a/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt b/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt index a7aa6452..d1f64eeb 100644 --- a/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt +++ b/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt @@ -1,14 +1,13 @@ package org.jetbrains.dokka.Kotlin -import Samples.SampleProcessingService import com.google.inject.Inject import com.intellij.psi.PsiDocCommentOwner import com.intellij.psi.PsiNamedElement import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.dokka.* +import org.jetbrains.dokka.Samples.SampleProcessingService import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.kdoc.findKDoc -import org.jetbrains.kotlin.idea.kdoc.getKDocLinkResolutionScope import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection @@ -16,17 +15,10 @@ import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.psi.KtBlockExpression -import org.jetbrains.kotlin.psi.KtCallExpression -import org.jetbrains.kotlin.psi.KtDeclarationWithBody -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.annotations.argumentValue import org.jetbrains.kotlin.resolve.constants.StringValue import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter -import org.jetbrains.kotlin.resolve.scopes.ResolutionScope import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered import org.jetbrains.kotlin.resolve.source.PsiSourceElement diff --git a/core/src/main/kotlin/Samples/DefaultSampleProcessingService.kt b/core/src/main/kotlin/Samples/DefaultSampleProcessingService.kt index 26841ea6..e6539135 100644 --- a/core/src/main/kotlin/Samples/DefaultSampleProcessingService.kt +++ b/core/src/main/kotlin/Samples/DefaultSampleProcessingService.kt @@ -1,4 +1,4 @@ -package Samples +package org.jetbrains.dokka.Samples import com.google.inject.Inject import com.intellij.psi.PsiElement diff --git a/core/src/main/kotlin/Samples/KotlinWebsiteSampleProcessingService.kt b/core/src/main/kotlin/Samples/KotlinWebsiteSampleProcessingService.kt index 864734ea..648a6b67 100644 --- a/core/src/main/kotlin/Samples/KotlinWebsiteSampleProcessingService.kt +++ b/core/src/main/kotlin/Samples/KotlinWebsiteSampleProcessingService.kt @@ -1,14 +1,11 @@ -package Samples +package org.jetbrains.dokka.Samples import com.google.inject.Inject -import com.intellij.openapi.util.TextRange import com.intellij.psi.PsiElement import org.jetbrains.dokka.DocumentationOptions import org.jetbrains.dokka.DokkaLogger import org.jetbrains.dokka.DokkaResolutionFacade import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.startOffset -import java.util.* open class KotlinWebsiteSampleProcessingService @Inject constructor(options: DocumentationOptions, @@ -16,66 +13,68 @@ open class KotlinWebsiteSampleProcessingService resolutionFacade: DokkaResolutionFacade) : DefaultSampleProcessingService(options, logger, resolutionFacade) { + private class SampleBuilder() : KtVisitorVoid() { + val builder = StringBuilder() + val text: String + get() = builder.toString() - fun buildReplacementData(psiElement: PsiElement): Map { - - val result = TreeMap({ o1, o2 -> o1.startOffset.compareTo(o2.startOffset) }) fun convertAssertPrints(expression: KtCallExpression) { val (argument, commentArgument) = expression.valueArguments val comment = commentArgument.getArgumentExpression() as KtStringTemplateExpression val commentText = comment.entries.joinToString("") { it.text } - result[expression.textRange] = "println(${argument.text}) //$commentText" + builder.apply { + append("println(") + append(argument.text) + append(") // ") + append(commentText) + } } fun convertAssertTrue(expression: KtCallExpression) { val (argument) = expression.valueArguments - result[expression.textRange] = "println(\"${argument.text} is \${${argument.text}}\") //true " + builder.apply { + append("println(\"") + append(argument.text) + append(" is \${") + append(argument.text) + append("}\") // true") + } } - if (psiElement is KtElement) { - val visitor = object : KtTreeVisitor() { - override fun visitCallExpression(expression: KtCallExpression, data: Any?): Void? { - when (expression.calleeExpression?.text) { - "assertPrints" -> convertAssertPrints(expression) - "assertTrue" -> convertAssertTrue(expression) - else -> super.visitCallExpression(expression, data) - } - return null - } + override fun visitCallExpression(expression: KtCallExpression) { + when (expression.calleeExpression?.text) { + "assertPrints" -> convertAssertPrints(expression) + "assertTrue" -> convertAssertTrue(expression) + else -> super.visitCallExpression(expression) } - psiElement.acceptChildren(visitor) } - return result - } - private fun String.applyReplacements(baseOffset: Int, replacementData: Map): String { - val partsList = arrayListOf() - var prevRange = TextRange(0, baseOffset) - for ((range, replacement) in replacementData) { - partsList.add(substring(prevRange.endOffset - baseOffset, range.startOffset - baseOffset)) - partsList.add(replacement) - prevRange = range + override fun visitElement(element: PsiElement?) { + if (element != null) { + if (element.children.isEmpty()) + builder.append(element.text) + else + element.acceptChildren(this) + } } - partsList.add(substring(prevRange.endOffset - baseOffset)) - return partsList.joinToString(separator = "") } + private fun PsiElement.buildSampleText(): String { + val sampleBuilder = SampleBuilder() + this.accept(sampleBuilder) + return sampleBuilder.text + } - override fun processSampleBody(psiElement: PsiElement): String { - - val replacementData = buildReplacementData(psiElement) - - return when (psiElement) { - is KtDeclarationWithBody -> { - val bodyExpression = psiElement.bodyExpression - val bodyExpressionText = bodyExpression!!.text.applyReplacements(bodyExpression.startOffset, replacementData) - when (bodyExpression) { - is KtBlockExpression -> bodyExpressionText.removeSurrounding("{", "}") - else -> bodyExpressionText - } + override fun processSampleBody(psiElement: PsiElement) = when (psiElement) { + is KtDeclarationWithBody -> { + val bodyExpression = psiElement.bodyExpression + val bodyExpressionText = bodyExpression!!.buildSampleText() + when (bodyExpression) { + is KtBlockExpression -> bodyExpressionText.removeSurrounding("{", "}") + else -> bodyExpressionText } - else -> psiElement.text.applyReplacements(psiElement.startOffset, replacementData) } + else -> psiElement.buildSampleText() } } diff --git a/core/src/main/kotlin/Samples/SampleProcessingService.kt b/core/src/main/kotlin/Samples/SampleProcessingService.kt index 61abda6d..7f46299f 100644 --- a/core/src/main/kotlin/Samples/SampleProcessingService.kt +++ b/core/src/main/kotlin/Samples/SampleProcessingService.kt @@ -1,4 +1,4 @@ -package Samples +package org.jetbrains.dokka.Samples import org.jetbrains.dokka.ContentNode import org.jetbrains.kotlin.descriptors.DeclarationDescriptor diff --git a/core/src/main/kotlin/Utilities/DokkaModule.kt b/core/src/main/kotlin/Utilities/DokkaModule.kt index 4b2a99d3..e1ae829a 100644 --- a/core/src/main/kotlin/Utilities/DokkaModule.kt +++ b/core/src/main/kotlin/Utilities/DokkaModule.kt @@ -1,12 +1,12 @@ package org.jetbrains.dokka.Utilities -import Samples.SampleProcessingService import com.google.inject.Binder import com.google.inject.Module import com.google.inject.Provider import com.google.inject.name.Names import org.jetbrains.dokka.* import org.jetbrains.dokka.Formats.FormatDescriptor +import org.jetbrains.dokka.Samples.SampleProcessingService import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import java.io.File diff --git a/core/src/main/kotlin/javadoc/dokka-adapters.kt b/core/src/main/kotlin/javadoc/dokka-adapters.kt index e3a58331..920eca2d 100644 --- a/core/src/main/kotlin/javadoc/dokka-adapters.kt +++ b/core/src/main/kotlin/javadoc/dokka-adapters.kt @@ -1,10 +1,10 @@ package org.jetbrains.dokka.javadoc -import Samples.DefaultSampleProcessingService import com.google.inject.Inject import com.sun.tools.doclets.formats.html.HtmlDoclet import org.jetbrains.dokka.* import org.jetbrains.dokka.Formats.FormatDescriptor +import org.jetbrains.dokka.Samples.DefaultSampleProcessingService class JavadocGenerator @Inject constructor (val options: DocumentationOptions, val logger: DokkaLogger) : Generator { override fun buildPages(nodes: Iterable) { diff --git a/core/testdata/format/website/sampleWithAsserts.md b/core/testdata/format/website/sampleWithAsserts.md index 3353ce46..98d7df33 100644 --- a/core/testdata/format/website/sampleWithAsserts.md +++ b/core/testdata/format/website/sampleWithAsserts.md @@ -14,8 +14,8 @@ layout: api fun main(args: Array) { //sampleStart -println(a()) //Hello, Work -println("a() == b() is ${a() == b()}") //true +println(a()) // Hello, Work +println("a() == b() is ${a() == b()}") // true //sampleEnd } ``` -- cgit