diff options
author | Simon Ogorodnik <Simon.Ogorodnik@jetbrains.com> | 2016-11-14 18:08:17 +0300 |
---|---|---|
committer | Simon Ogorodnik <Simon.Ogorodnik@jetbrains.com> | 2016-11-14 18:08:17 +0300 |
commit | 47790d166100dc50d797fc0312b9b3fe0e7e9d7f (patch) | |
tree | 15750d4e238692305b089b4a9969b005868aaaf6 /core/src/main/kotlin/Samples/DefaultSampleProcessingService.kt | |
parent | dc99d1fd5c066ac6083f09e23e52cf6c592768e4 (diff) | |
download | dokka-47790d166100dc50d797fc0312b9b3fe0e7e9d7f.tar.gz dokka-47790d166100dc50d797fc0312b9b3fe0e7e9d7f.tar.bz2 dokka-47790d166100dc50d797fc0312b9b3fe0e7e9d7f.zip |
Replacing assertPrints, assertTrue to println for kotlin-website samples, Added SampleProcessingService to FormatDescriptor
Diffstat (limited to 'core/src/main/kotlin/Samples/DefaultSampleProcessingService.kt')
-rw-r--r-- | core/src/main/kotlin/Samples/DefaultSampleProcessingService.kt | 106 |
1 files changed, 106 insertions, 0 deletions
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 + } +} + |