diff options
author | sebastian.sellmair <sebastian.sellmair@jetbrains.com> | 2020-08-25 14:28:44 +0200 |
---|---|---|
committer | Sebastian Sellmair <34319766+sellmair@users.noreply.github.com> | 2020-08-31 15:10:04 +0200 |
commit | 29cc17ba80018e3e45a5fabcf2e370c735fd5674 (patch) | |
tree | 4845c0d56582c290c69427769a032e8a017c2773 /plugins/base/src/main/kotlin/transformers/documentables | |
parent | 333091e5c5f896769c3371dd74c87a52ffa9562a (diff) | |
download | dokka-29cc17ba80018e3e45a5fabcf2e370c735fd5674.tar.gz dokka-29cc17ba80018e3e45a5fabcf2e370c735fd5674.tar.bz2 dokka-29cc17ba80018e3e45a5fabcf2e370c735fd5674.zip |
Implement ModuleAndPackageDocumentationReader
Diffstat (limited to 'plugins/base/src/main/kotlin/transformers/documentables')
2 files changed, 84 insertions, 81 deletions
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationReader.kt b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationReader.kt new file mode 100644 index 00000000..e8297f3f --- /dev/null +++ b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationReader.kt @@ -0,0 +1,72 @@ +@file:Suppress("FunctionName") + +package org.jetbrains.dokka.base.transformers.documentables + +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.analysis.KotlinAnalysis +import org.jetbrains.dokka.base.parsers.moduleAndPackage.ModuleAndPackageDocumentation.Classifier +import org.jetbrains.dokka.base.parsers.moduleAndPackage.ModuleAndPackageDocumentationFragment +import org.jetbrains.dokka.base.parsers.moduleAndPackage.ModuleAndPackageDocumentationParsingContext +import org.jetbrains.dokka.base.parsers.moduleAndPackage.parseModuleAndPackageDocumentation +import org.jetbrains.dokka.base.parsers.moduleAndPackage.parseModuleAndPackageDocumentationFragments +import org.jetbrains.dokka.model.DModule +import org.jetbrains.dokka.model.DPackage +import org.jetbrains.dokka.model.SourceSetDependent +import org.jetbrains.dokka.model.doc.DocumentationNode +import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.utilities.associateWithNotNull + +internal interface ModuleAndPackageDocumentationReader { + operator fun get(module: DModule): SourceSetDependent<DocumentationNode> + operator fun get(pkg: DPackage): SourceSetDependent<DocumentationNode> +} + +// TODO NOW: Test +internal fun ModuleAndPackageDocumentationReader( + context: DokkaContext, kotlinAnalysis: KotlinAnalysis? = null +): ModuleAndPackageDocumentationReader = ContextModuleAndPackageDocumentationReader(context, kotlinAnalysis) + +private class ContextModuleAndPackageDocumentationReader( + private val context: DokkaContext, + private val kotlinAnalysis: KotlinAnalysis? +) : ModuleAndPackageDocumentationReader { + + private val documentationFragments: SourceSetDependent<List<ModuleAndPackageDocumentationFragment>> = + context.configuration.sourceSets.associateWith { sourceSet -> + sourceSet.includes.flatMap { include -> parseModuleAndPackageDocumentationFragments(include) } + } + + private fun findDocumentationNodes( + sourceSets: Set<DokkaConfiguration.DokkaSourceSet>, + predicate: (ModuleAndPackageDocumentationFragment) -> Boolean + ): SourceSetDependent<DocumentationNode> { + return sourceSets.associateWithNotNull { sourceSet -> + val fragments = documentationFragments[sourceSet].orEmpty().filter(predicate) + val resolutionFacade = kotlinAnalysis?.get(sourceSet)?.facade + val documentations = fragments.map { fragment -> + parseModuleAndPackageDocumentation( + context = ModuleAndPackageDocumentationParsingContext(context.logger, resolutionFacade), + fragment = fragment + ) + } + when (documentations.size) { + 0 -> null + 1 -> documentations.single().documentation + else -> DocumentationNode(documentations.flatMap { it.documentation.children }) + } + } + } + + override fun get(module: DModule): SourceSetDependent<DocumentationNode> { + return findDocumentationNodes(module.sourceSets) { fragment -> + fragment.classifier == Classifier.Module && fragment.name == module.name + } + } + + override fun get(pkg: DPackage): SourceSetDependent<DocumentationNode> { + return findDocumentationNodes(pkg.sourceSets) { fragment -> + // TODO NOW: handle JS Root thing + fragment.classifier == Classifier.Package && fragment.name == pkg.dri.packageName + } + } +} diff --git a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt index 5f1a540d..9bdec75a 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt @@ -1,101 +1,32 @@ package org.jetbrains.dokka.base.transformers.documentables -import org.jetbrains.dokka.analysis.KotlinAnalysis +import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.model.DModule import org.jetbrains.dokka.model.doc.DocumentationNode -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet -import org.jetbrains.dokka.base.parsers.MarkdownParser -import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name -import java.nio.file.Files -import java.nio.file.Paths - +// TODO NOW: Test internal class ModuleAndPackageDocumentationTransformer( - private val context: DokkaContext, - private val kotlinAnalysis: KotlinAnalysis + private val moduleAndPackageDocumentationReader: ModuleAndPackageDocumentationReader ) : PreMergeDocumentableTransformer { override fun invoke(modules: List<DModule>): List<DModule> { - - val modulesAndPackagesDocumentation = - context.configuration.sourceSets - .map { sourceSet -> - Pair(sourceSet.moduleDisplayName, sourceSet) to - sourceSet.includes.map { it.toPath() } - .also { - it.forEach { - if (Files.notExists(it)) - context.logger.warn("Not found file under this path ${it.toAbsolutePath()}") - } - } - .filter { Files.exists(it) } - .flatMap { - it.toFile() - .readText() - .split(Regex("(\n|^)# (?=(Module|Package))")) // Matches heading with Module/Package to split by - .filter { it.isNotEmpty() } - .map { it.split(Regex(" "), 2) } // Matches space between Module/Package and fully qualified name - }.groupBy({ it[0] }, { - it[1].split(Regex("\n"), 2) // Matches new line after fully qualified name - .let { it[0].trim() to it[1].trim() } - }).mapValues { - it.value.toMap() - } - }.toMap() - return modules.map { module -> - - val moduleDocumentation = - module.sourceSets.mapNotNull { pd -> - val doc = modulesAndPackagesDocumentation[Pair(module.name, pd)] - val facade = kotlinAnalysis[pd].facade - try { - doc?.get("Module")?.get(module.name)?.run { - pd to MarkdownParser( - facade, - facade.moduleDescriptor.getPackage(FqName.topLevel(Name.identifier(""))), - context.logger - ).parse(this) - } - } catch (e: IllegalArgumentException) { - context.logger.error(e.message.orEmpty()) - null - } - }.toMap() - - val packagesDocumentation = module.packages.map { - it.name to it.sourceSets.mapNotNull { pd -> - val doc = modulesAndPackagesDocumentation[Pair(module.name, pd)] - val facade = kotlinAnalysis[pd].facade - val descriptor = facade.moduleDescriptor.getPackage(FqName(it.name.let { if(it == "[JS root]") "" else it })) - doc?.get("Package")?.get(it.name)?.run { - pd to MarkdownParser( - facade, - descriptor, - context.logger - ).parse(this) - } - }.toMap() - }.toMap() - module.copy( - documentation = mergeDocumentation(module.documentation, moduleDocumentation), - packages = module.packages.map { - val packageDocumentation = packagesDocumentation[it.name] - if (packageDocumentation != null && packageDocumentation.isNotEmpty()) - it.copy(documentation = mergeDocumentation(it.documentation, packageDocumentation)) - else - it + documentation = module.documentation + moduleAndPackageDocumentationReader[module], + packages = module.packages.map { pkg -> + pkg.copy( + documentation = pkg.documentation + moduleAndPackageDocumentationReader[pkg] + ) } ) } } - private fun mergeDocumentation(origin: Map<DokkaSourceSet, DocumentationNode>, new: Map<DokkaSourceSet, DocumentationNode>): Map<DokkaSourceSet, DocumentationNode> = - (origin.asSequence() + new.asSequence()) + private operator fun Map<DokkaSourceSet, DocumentationNode>.plus( + other: Map<DokkaSourceSet, DocumentationNode> + ): Map<DokkaSourceSet, DocumentationNode> = + (asSequence() + other.asSequence()) .distinct() .groupBy({ it.key }, { it.value }) .mapValues { (_, values) -> DocumentationNode(values.flatMap { it.children }) } |