diff options
Diffstat (limited to 'plugins/base/src/main/kotlin/transformers')
18 files changed, 53 insertions, 465 deletions
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt b/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt index 17e3cbcd..d9c68981 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt @@ -1,13 +1,13 @@ package org.jetbrains.dokka.base.transformers.documentables import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.base.utils.firstNotNullOfOrNull import org.jetbrains.dokka.model.* import org.jetbrains.dokka.model.properties.ExtraProperty import org.jetbrains.dokka.model.properties.MergeStrategy import org.jetbrains.dokka.model.properties.mergeExtras import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.transformers.documentation.DocumentableMerger -import org.jetbrains.kotlin.util.firstNotNullResult internal class DefaultDocumentableMerger(val context: DokkaContext) : DocumentableMerger { private val dependencyInfo = context.getDependencyInfo() @@ -21,7 +21,7 @@ internal class DefaultDocumentableMerger(val context: DokkaContext) : Documentab list.flatMap { it.packages } ) { pck1, pck2 -> pck1.mergeWith(pck2) }, documentation = list.map { it.documentation }.flatMap { it.entries }.associate { (k, v) -> k to v }, - expectPresentInSet = list.firstNotNullResult { it.expectPresentInSet }, + expectPresentInSet = list.firstNotNullOfOrNull { it.expectPresentInSet }, sourceSets = list.flatMap { it.sourceSets }.toSet() ).mergeExtras(left, right) } diff --git a/plugins/base/src/main/kotlin/transformers/documentables/DeprecatedDocumentableFilterTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/DeprecatedDocumentableFilterTransformer.kt index 1112ac15..366690c7 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/DeprecatedDocumentableFilterTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/DeprecatedDocumentableFilterTransformer.kt @@ -1,7 +1,7 @@ package org.jetbrains.dokka.base.transformers.documentables -import org.jetbrains.dokka.DokkaConfiguration.PackageOptions import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.DokkaConfiguration.PackageOptions import org.jetbrains.dokka.model.Annotations import org.jetbrains.dokka.model.Documentable import org.jetbrains.dokka.model.EnumValue diff --git a/plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilterTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilterTransformer.kt index 94688799..713166bb 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilterTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilterTransformer.kt @@ -1,11 +1,11 @@ package org.jetbrains.dokka.base.transformers.documentables import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet +import org.jetbrains.dokka.DokkaDefaults import org.jetbrains.dokka.model.* import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet -import org.jetbrains.dokka.DokkaDefaults class DocumentableVisibilityFilterTransformer(val context: DokkaContext) : PreMergeDocumentableTransformer { diff --git a/plugins/base/src/main/kotlin/transformers/documentables/ExtensionExtractorTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/ExtensionExtractorTransformer.kt index 19af0564..79df844e 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/ExtensionExtractorTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/ExtensionExtractorTransformer.kt @@ -2,7 +2,6 @@ package org.jetbrains.dokka.base.transformers.documentables import kotlinx.coroutines.* import kotlinx.coroutines.channels.* -import org.jetbrains.dokka.base.transformers.documentables.utils.FullClassHierarchyBuilder import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.links.DriOfAny import org.jetbrains.dokka.model.* @@ -10,16 +9,19 @@ import org.jetbrains.dokka.model.properties.ExtraProperty import org.jetbrains.dokka.model.properties.MergeStrategy import org.jetbrains.dokka.model.properties.plus import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.plugability.plugin +import org.jetbrains.dokka.plugability.querySingle import org.jetbrains.dokka.transformers.documentation.DocumentableTransformer import org.jetbrains.dokka.utilities.parallelForEach import org.jetbrains.dokka.utilities.parallelMap +import org.jetbrains.kotlin.analysis.kotlin.internal.InternalKotlinAnalysisPlugin class ExtensionExtractorTransformer : DocumentableTransformer { override fun invoke(original: DModule, context: DokkaContext): DModule = runBlocking(Dispatchers.Default) { val classGraph = async { if (!context.configuration.suppressInheritedMembers) - FullClassHierarchyBuilder()(original) + context.plugin<InternalKotlinAnalysisPlugin>().querySingle { fullClassHierarchyBuilder }.build(original) else emptyMap() } diff --git a/plugins/base/src/main/kotlin/transformers/documentables/InheritedEntriesDocumentableFilterTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/InheritedEntriesDocumentableFilterTransformer.kt index 2e4b29ff..01438432 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/InheritedEntriesDocumentableFilterTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/InheritedEntriesDocumentableFilterTransformer.kt @@ -1,6 +1,7 @@ package org.jetbrains.dokka.base.transformers.documentables -import org.jetbrains.dokka.model.* +import org.jetbrains.dokka.model.Documentable +import org.jetbrains.dokka.model.InheritedMember import org.jetbrains.dokka.model.properties.WithExtraProperties import org.jetbrains.dokka.plugability.DokkaContext @@ -14,4 +15,4 @@ class InheritedEntriesDocumentableFilterTransformer(context: DokkaContext) : return context.configuration.suppressInheritedMembers && containsInheritedFrom } -}
\ No newline at end of file +} diff --git a/plugins/base/src/main/kotlin/transformers/documentables/InheritorsExtractorTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/InheritorsExtractorTransformer.kt index 463ec419..6106466f 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/InheritorsExtractorTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/InheritorsExtractorTransformer.kt @@ -1,11 +1,11 @@ package org.jetbrains.dokka.base.transformers.documentables +import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.* import org.jetbrains.dokka.model.properties.ExtraProperty import org.jetbrains.dokka.model.properties.MergeStrategy import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.transformers.documentation.DocumentableTransformer class InheritorsExtractorTransformer : DocumentableTransformer { diff --git a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationReader.kt b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationReader.kt deleted file mode 100644 index faf94db2..00000000 --- a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationReader.kt +++ /dev/null @@ -1,107 +0,0 @@ -package org.jetbrains.dokka.base.transformers.documentables - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.analysis.KotlinAnalysis -import org.jetbrains.dokka.base.DokkaBase -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.* -import org.jetbrains.dokka.model.doc.Deprecated -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.querySingle -import org.jetbrains.dokka.utilities.associateWithNotNull - -internal interface ModuleAndPackageDocumentationReader { - operator fun get(module: DModule): SourceSetDependent<DocumentationNode> - operator fun get(pkg: DPackage): SourceSetDependent<DocumentationNode> -} - -internal fun ModuleAndPackageDocumentationReader(context: DokkaContext): ModuleAndPackageDocumentationReader = - ContextModuleAndPackageDocumentationReader(context) - -private class ContextModuleAndPackageDocumentationReader( - private val context: DokkaContext -) : ModuleAndPackageDocumentationReader { - - private val kotlinAnalysis: KotlinAnalysis = context.plugin<DokkaBase>().querySingle { kotlinAnalysis } - - 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[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 } - .mergeDocumentationNodes()) - } - } - } - - private val ModuleAndPackageDocumentationFragment.canonicalPackageName: String - get() { - check(classifier == Classifier.Package) - if (name == "[root]") return "" - return name - } - - 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 -> - fragment.classifier == Classifier.Package && fragment.canonicalPackageName == pkg.dri.packageName - } - } - - private fun List<TagWrapper>.mergeDocumentationNodes(): List<TagWrapper> = - groupBy { it::class }.values.map { - it.reduce { acc, tagWrapper -> - val newRoot = CustomDocTag( - acc.children + tagWrapper.children, - name = (tagWrapper as? NamedTagWrapper)?.name.orEmpty() - ) - when (acc) { - is See -> acc.copy(newRoot) - is Param -> acc.copy(newRoot) - is Throws -> acc.copy(newRoot) - is Sample -> acc.copy(newRoot) - is Property -> acc.copy(newRoot) - is CustomTagWrapper -> acc.copy(newRoot) - is Description -> acc.copy(newRoot) - is Author -> acc.copy(newRoot) - is Version -> acc.copy(newRoot) - is Since -> acc.copy(newRoot) - is Return -> acc.copy(newRoot) - is Receiver -> acc.copy(newRoot) - is Constructor -> acc.copy(newRoot) - is Deprecated -> acc.copy(newRoot) - is org.jetbrains.dokka.model.doc.Suppress -> acc.copy(newRoot) - } - } - } -} diff --git a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt index 99fba9f7..9f10873b 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt @@ -5,21 +5,27 @@ import org.jetbrains.dokka.model.DModule import org.jetbrains.dokka.model.SourceSetDependent import org.jetbrains.dokka.model.doc.DocumentationNode import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.plugability.plugin +import org.jetbrains.dokka.plugability.querySingle import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer +import org.jetbrains.kotlin.analysis.kotlin.internal.InternalKotlinAnalysisPlugin +import org.jetbrains.kotlin.analysis.kotlin.internal.ModuleAndPackageDocumentationReader internal class ModuleAndPackageDocumentationTransformer( private val moduleAndPackageDocumentationReader: ModuleAndPackageDocumentationReader ) : PreMergeDocumentableTransformer { - constructor(context: DokkaContext) : this(ModuleAndPackageDocumentationReader(context)) + constructor(context: DokkaContext) : this( + context.plugin<InternalKotlinAnalysisPlugin>().querySingle { moduleAndPackageDocumentationReader } + ) override fun invoke(modules: List<DModule>): List<DModule> { return modules.map { module -> module.copy( - documentation = module.documentation + moduleAndPackageDocumentationReader[module], + documentation = module.documentation + moduleAndPackageDocumentationReader.read(module), packages = module.packages.map { pkg -> pkg.copy( - documentation = pkg.documentation + moduleAndPackageDocumentationReader[pkg] + documentation = pkg.documentation + moduleAndPackageDocumentationReader.read(pkg) ) } ) diff --git a/plugins/base/src/main/kotlin/transformers/documentables/ReportUndocumentedTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/ReportUndocumentedTransformer.kt index ad9e34df..3368ded1 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/ReportUndocumentedTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/ReportUndocumentedTransformer.kt @@ -2,14 +2,12 @@ package org.jetbrains.dokka.base.transformers.documentables import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet -import org.jetbrains.dokka.analysis.DescriptorDocumentableSource import org.jetbrains.dokka.model.* import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.plugability.plugin +import org.jetbrains.dokka.plugability.querySingle import org.jetbrains.dokka.transformers.documentation.DocumentableTransformer -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERRIDE -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED -import org.jetbrains.kotlin.utils.addToStdlib.safeAs +import org.jetbrains.kotlin.analysis.kotlin.internal.InternalKotlinAnalysisPlugin internal class ReportUndocumentedTransformer : DocumentableTransformer { @@ -19,14 +17,14 @@ internal class ReportUndocumentedTransformer : DocumentableTransformer { private fun invoke(documentable: Documentable, context: DokkaContext) { documentable.sourceSets.forEach { sourceSet -> - if (shouldBeReportedIfNotDocumented(documentable, sourceSet)) { + if (shouldBeReportedIfNotDocumented(documentable, sourceSet, context)) { reportIfUndocumented(context, documentable, sourceSet) } } } private fun shouldBeReportedIfNotDocumented( - documentable: Documentable, sourceSet: DokkaSourceSet + documentable: Documentable, sourceSet: DokkaSourceSet, context: DokkaContext ): Boolean { val packageOptionsOrNull = packageOptionsOrNull(sourceSet, documentable) @@ -42,11 +40,8 @@ internal class ReportUndocumentedTransformer : DocumentableTransformer { return false } - if (isFakeOverride(documentable, sourceSet)) { - return false - } - - if (isSynthesized(documentable, sourceSet)) { + val syntheticDetector = context.plugin<InternalKotlinAnalysisPlugin>().querySingle { syntheticDocumentableDetector } + if (syntheticDetector.isSynthetic(documentable, sourceSet)) { return false } @@ -118,28 +113,8 @@ internal class ReportUndocumentedTransformer : DocumentableTransformer { return documentable.isConstructor } - private fun isFakeOverride(documentable: Documentable, sourceSet: DokkaSourceSet): Boolean { - return callableMemberDescriptorOrNull(documentable, sourceSet)?.kind == FAKE_OVERRIDE - } - - private fun isSynthesized(documentable: Documentable, sourceSet: DokkaSourceSet): Boolean { - return callableMemberDescriptorOrNull(documentable, sourceSet)?.kind == SYNTHESIZED - } - - private fun callableMemberDescriptorOrNull( - documentable: Documentable, sourceSet: DokkaSourceSet - ): CallableMemberDescriptor? { - if (documentable is WithSources) { - return documentable.sources[sourceSet] - .safeAs<DescriptorDocumentableSource>()?.descriptor - .safeAs<CallableMemberDescriptor>() - } - - return null - } - private fun isPrivateOrInternalApi(documentable: Documentable, sourceSet: DokkaSourceSet): Boolean { - return when (documentable.safeAs<WithVisibility>()?.visibility?.get(sourceSet)) { + return when ((documentable as? WithVisibility)?.visibility?.get(sourceSet)) { KotlinVisibility.Public -> false KotlinVisibility.Private -> true KotlinVisibility.Protected -> true diff --git a/plugins/base/src/main/kotlin/transformers/documentables/SuppressTagDocumentableFilter.kt b/plugins/base/src/main/kotlin/transformers/documentables/SuppressTagDocumentableFilter.kt index a297908d..2d65e98b 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/SuppressTagDocumentableFilter.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/SuppressTagDocumentableFilter.kt @@ -2,11 +2,11 @@ package org.jetbrains.dokka.base.transformers.documentables import org.jetbrains.dokka.model.Documentable import org.jetbrains.dokka.model.dfs -import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.model.doc.Suppress +import org.jetbrains.dokka.plugability.DokkaContext class SuppressTagDocumentableFilter(val dokkaContext: DokkaContext) : SuppressedByConditionDocumentableFilterTransformer(dokkaContext) { override fun shouldBeSuppressed(d: Documentable): Boolean = d.documentation.any { (_, docs) -> docs.dfs { it is Suppress } != null } -}
\ No newline at end of file +} diff --git a/plugins/base/src/main/kotlin/transformers/documentables/utils/FullClassHierarchyBuilder.kt b/plugins/base/src/main/kotlin/transformers/documentables/utils/FullClassHierarchyBuilder.kt deleted file mode 100644 index d657fa32..00000000 --- a/plugins/base/src/main/kotlin/transformers/documentables/utils/FullClassHierarchyBuilder.kt +++ /dev/null @@ -1,84 +0,0 @@ -package org.jetbrains.dokka.base.transformers.documentables.utils - -import com.intellij.psi.PsiClass -import kotlinx.coroutines.* -import org.jetbrains.dokka.analysis.DescriptorDocumentableSource -import org.jetbrains.dokka.analysis.PsiDocumentableSource -import org.jetbrains.dokka.analysis.from -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.* -import org.jetbrains.dokka.utilities.parallelForEach -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes -import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny -import java.util.concurrent.ConcurrentHashMap - -typealias Supertypes = List<DRI> -typealias ClassHierarchy = SourceSetDependent<Map<DRI, Supertypes>> - -class FullClassHierarchyBuilder { - suspend operator fun invoke(original: DModule): ClassHierarchy = coroutineScope { - val map = original.sourceSets.associateWith { ConcurrentHashMap<DRI, List<DRI>>() } - original.packages.parallelForEach { visitDocumentable(it, map) } - map - } - - private suspend fun collectSupertypesFromKotlinType( - driWithKType: Pair<DRI, KotlinType>, - supersMap: MutableMap<DRI, Supertypes> - ): Unit = coroutineScope { - val (dri, kotlinType) = driWithKType - val supertypes = kotlinType.immediateSupertypes().filterNot { it.isAnyOrNullableAny() } - val supertypesDriWithKType = supertypes.mapNotNull { supertype -> - supertype.constructor.declarationDescriptor?.let { - DRI.from(it) to supertype - } - } - - if (supersMap[dri] == null) { - // another thread can rewrite the same value, but it isn't a problem - supersMap[dri] = supertypesDriWithKType.map { it.first } - supertypesDriWithKType.parallelForEach { collectSupertypesFromKotlinType(it, supersMap) } - } - } - - private suspend fun collectSupertypesFromPsiClass( - driWithPsiClass: Pair<DRI, PsiClass>, - supersMap: MutableMap<DRI, Supertypes> - ): Unit = coroutineScope { - val (dri, psiClass) = driWithPsiClass - val supertypes = psiClass.superTypes.mapNotNull { it.resolve() } - .filterNot { it.qualifiedName == "java.lang.Object" } - val supertypesDriWithPsiClass = supertypes.map { DRI.from(it) to it } - - if (supersMap[dri] == null) { - // another thread can rewrite the same value, but it isn't a problem - supersMap[dri] = supertypesDriWithPsiClass.map { it.first } - supertypesDriWithPsiClass.parallelForEach { collectSupertypesFromPsiClass(it, supersMap) } - } - } - - private suspend fun visitDocumentable( - documentable: Documentable, - hierarchy: SourceSetDependent<MutableMap<DRI, List<DRI>>> - ): Unit = coroutineScope { - if (documentable is WithScope) { - documentable.classlikes.parallelForEach { visitDocumentable(it, hierarchy) } - } - if (documentable is DClasslike) { - // to build a full class graph, using supertypes from Documentable - // is not enough since it keeps only one level of hierarchy - documentable.sources.forEach { (sourceSet, source) -> - if (source is DescriptorDocumentableSource) { - val descriptor = source.descriptor as ClassDescriptor - val type = descriptor.defaultType - hierarchy[sourceSet]?.let { collectSupertypesFromKotlinType(documentable.dri to type, it) } - } else if (source is PsiDocumentableSource) { - val psi = source.psi as PsiClass - hierarchy[sourceSet]?.let { collectSupertypesFromPsiClass(documentable.dri to psi, it) } - } - } - } - } -}
\ No newline at end of file diff --git a/plugins/base/src/main/kotlin/transformers/pages/annotations/SinceKotlinTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/annotations/SinceKotlinTransformer.kt index 75f43324..23b3f625 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/annotations/SinceKotlinTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/annotations/SinceKotlinTransformer.kt @@ -1,9 +1,9 @@ package org.jetbrains.dokka.base.transformers.pages.annotations -import com.intellij.util.containers.ComparatorUtil.max -import org.intellij.markdown.MarkdownElementTypes + import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.Platform +import org.jetbrains.dokka.analysis.markdown.jb.MARKDOWN_ELEMENT_FILE_NAME import org.jetbrains.dokka.base.signatures.KotlinSignatureUtils.annotations import org.jetbrains.dokka.model.* import org.jetbrains.dokka.model.doc.CustomDocTag @@ -13,7 +13,6 @@ import org.jetbrains.dokka.model.doc.Text import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.transformers.documentation.DocumentableTransformer import org.jetbrains.dokka.utilities.associateWithNotNull -import org.jetbrains.kotlin.utils.addToStdlib.safeAs class SinceKotlinVersion constructor(str: String) : Comparable<SinceKotlinVersion> { private val parts: List<Int> = str.split(".").map { it.toInt() } @@ -124,7 +123,7 @@ class SinceKotlinTransformer(val context: DokkaContext) : DocumentableTransforme val annotatedVersion = annotations()[sourceSet] ?.findSinceKotlinAnnotation() - ?.params?.get("version").safeAs<StringValue>()?.value + ?.params?.let { it["version"] as? StringValue }?.value ?.let { SinceKotlinVersion(it) } val minSinceKotlin = minSinceKotlinVersionOfPlatform[sourceSet.analysisPlatform] @@ -139,7 +138,7 @@ class SinceKotlinTransformer(val context: DokkaContext) : DocumentableTransforme val version = getVersion(sourceSet) val parentVersion = parent?.get(sourceSet) if (parentVersion != null) - max(version, parentVersion) + maxOf(version, parentVersion) else version } @@ -157,7 +156,7 @@ class SinceKotlinTransformer(val context: DokkaContext) : DocumentableTransforme version.toString() ) ), - name = MarkdownElementTypes.MARKDOWN_FILE.name + name = MARKDOWN_ELEMENT_FILE_NAME ), "Since Kotlin" ) diff --git a/plugins/base/src/main/kotlin/transformers/pages/comments/CommentsToContentConverter.kt b/plugins/base/src/main/kotlin/transformers/pages/comments/CommentsToContentConverter.kt index fa9ce37e..58e22103 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/comments/CommentsToContentConverter.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/comments/CommentsToContentConverter.kt @@ -3,7 +3,9 @@ package org.jetbrains.dokka.base.transformers.pages.comments import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.model.doc.DocTag import org.jetbrains.dokka.model.properties.PropertyContainer -import org.jetbrains.dokka.pages.* +import org.jetbrains.dokka.pages.ContentNode +import org.jetbrains.dokka.pages.DCI +import org.jetbrains.dokka.pages.Style interface CommentsToContentConverter { fun buildContent( diff --git a/plugins/base/src/main/kotlin/transformers/pages/comments/DocTagToContentConverter.kt b/plugins/base/src/main/kotlin/transformers/pages/comments/DocTagToContentConverter.kt index 2193283c..083a82cc 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/comments/DocTagToContentConverter.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/comments/DocTagToContentConverter.kt @@ -1,13 +1,14 @@ package org.jetbrains.dokka.base.transformers.pages.comments -import org.intellij.markdown.MarkdownElementTypes + import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet +import org.jetbrains.dokka.analysis.markdown.jb.MARKDOWN_ELEMENT_FILE_NAME import org.jetbrains.dokka.model.doc.* import org.jetbrains.dokka.model.properties.PropertyContainer import org.jetbrains.dokka.model.properties.plus import org.jetbrains.dokka.model.toDisplaySourceSets import org.jetbrains.dokka.pages.* -import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull +import org.jetbrains.dokka.utilities.firstIsInstanceOrNull open class DocTagToContentConverter : CommentsToContentConverter { override fun buildContent( @@ -261,5 +262,5 @@ open class DocTagToContentConverter : CommentsToContentConverter { } } - private fun CustomDocTag.isNonemptyFile() = name == MarkdownElementTypes.MARKDOWN_FILE.name && children.size > 1 + private fun CustomDocTag.isNonemptyFile() = name == MARKDOWN_ELEMENT_FILE_NAME && children.size > 1 } diff --git a/plugins/base/src/main/kotlin/transformers/pages/merger/SourceSetMergingPageTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/merger/SourceSetMergingPageTransformer.kt index 6cb7f603..f9da616c 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/merger/SourceSetMergingPageTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/merger/SourceSetMergingPageTransformer.kt @@ -3,7 +3,9 @@ package org.jetbrains.dokka.base.transformers.pages.merger import org.jetbrains.dokka.Platform import org.jetbrains.dokka.model.DisplaySourceSet import org.jetbrains.dokka.model.toDisplaySourceSets -import org.jetbrains.dokka.pages.* +import org.jetbrains.dokka.pages.ContentComposite +import org.jetbrains.dokka.pages.ContentNode +import org.jetbrains.dokka.pages.RootPageNode import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.transformers.pages.PageTransformer diff --git a/plugins/base/src/main/kotlin/transformers/pages/samples/DefaultSamplesTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/samples/DefaultSamplesTransformer.kt deleted file mode 100644 index 49ddd0a5..00000000 --- a/plugins/base/src/main/kotlin/transformers/pages/samples/DefaultSamplesTransformer.kt +++ /dev/null @@ -1,36 +0,0 @@ -package org.jetbrains.dokka.base.transformers.pages.samples - -import com.intellij.psi.PsiElement -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.kotlin.psi.KtBlockExpression -import org.jetbrains.kotlin.psi.KtDeclarationWithBody -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.utils.addToStdlib.safeAs - -class DefaultSamplesTransformer(context: DokkaContext) : SamplesTransformer(context) { - - override fun processBody(psiElement: PsiElement): String { - val text = processSampleBody(psiElement).trim { it == '\n' || it == '\r' }.trimEnd() - val lines = text.split("\n") - val indent = lines.filter(String::isNotBlank).map { it.takeWhile(Char::isWhitespace).count() }.minOrNull() ?: 0 - return lines.joinToString("\n") { it.drop(indent) } - } - - private fun processSampleBody(psiElement: PsiElement): String = when (psiElement) { - is KtDeclarationWithBody -> { - when (val bodyExpression = psiElement.bodyExpression) { - is KtBlockExpression -> bodyExpression.text.removeSurrounding("{", "}") - else -> bodyExpression!!.text - } - } - else -> psiElement.text - } - - override fun processImports(psiElement: PsiElement): String { - val psiFile = psiElement.containingFile - return when(val text = psiFile.safeAs<KtFile>()?.importList?.text) { - is String -> text - else -> "" - } - } -}
\ No newline at end of file diff --git a/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt deleted file mode 100644 index e72700e0..00000000 --- a/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt +++ /dev/null @@ -1,148 +0,0 @@ -package org.jetbrains.dokka.base.transformers.pages.samples - -import com.intellij.psi.PsiElement -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet -import org.jetbrains.dokka.analysis.* -import org.jetbrains.dokka.base.DokkaBase -import org.jetbrains.dokka.base.renderers.sourceSets -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.DisplaySourceSet -import org.jetbrains.dokka.model.doc.Sample -import org.jetbrains.dokka.model.properties.PropertyContainer -import org.jetbrains.dokka.pages.* -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.querySingle -import org.jetbrains.dokka.transformers.pages.PageTransformer -import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils - -internal const val KOTLIN_PLAYGROUND_SCRIPT = "<script src=\"https://unpkg.com/kotlin-playground@1\"></script>" -abstract class SamplesTransformer(val context: DokkaContext) : PageTransformer { - - abstract fun processBody(psiElement: PsiElement): String - abstract fun processImports(psiElement: PsiElement): String - - final override fun invoke(input: RootPageNode): RootPageNode = - /** - * Run from the thread of [Dispatchers.Default]. It can help to avoid a memory leaks in `ThreadLocal`s (that keep `URLCLassLoader`) - * since we shut down Dispatchers. Default at the end of each task (see [org.jetbrains.dokka.DokkaConfiguration.finalizeCoroutines]). - * Currently, all `ThreadLocal`s are in a compiler/IDE codebase. - */ - runBlocking(Dispatchers.Default) { - val analysis = SamplesKotlinAnalysis( - sourceSets = context.configuration.sourceSets, - logger = context.logger, - projectKotlinAnalysis = context.plugin<DokkaBase>().querySingle { kotlinAnalysis } - ) - analysis.use { - input.transformContentPagesTree { page -> - val samples = (page as? WithDocumentables)?.documentables?.flatMap { - it.documentation.entries.flatMap { entry -> - entry.value.children.filterIsInstance<Sample>().map { entry.key to it } - } - } - - samples?.fold(page as ContentPage) { acc, (sampleSourceSet, sample) -> - acc.modified( - content = acc.content.addSample(page, sampleSourceSet, sample.name, it), - embeddedResources = acc.embeddedResources + KOTLIN_PLAYGROUND_SCRIPT - ) - } ?: page - } - } - } - - private fun ContentNode.addSample( - contentPage: ContentPage, - sourceSet: DokkaSourceSet, - fqName: String, - analysis: KotlinAnalysis - ): ContentNode { - val facade = analysis[sourceSet].facade - val psiElement = fqNameToPsiElement(facade, fqName) - ?: return this.also { context.logger.warn("Cannot find PsiElement corresponding to $fqName") } - val imports = - processImports(psiElement) - val body = processBody(psiElement) - val node = contentCode(contentPage.sourceSets(), contentPage.dri, createSampleBody(imports, body), "kotlin") - - return dfs(fqName, node) - } - - protected open fun createSampleBody(imports: String, body: String) = - """ |$imports - |fun main() { - | //sampleStart - | $body - | //sampleEnd - |}""".trimMargin() - - private fun ContentNode.dfs(fqName: String, node: ContentCodeBlock): ContentNode { - return when (this) { - is ContentHeader -> copy(children.map { it.dfs(fqName, node) }) - is ContentDivergentGroup -> @Suppress("UNCHECKED_CAST") copy(children.map { - it.dfs(fqName, node) - } as List<ContentDivergentInstance>) - is ContentDivergentInstance -> copy( - before.let { it?.dfs(fqName, node) }, - divergent.dfs(fqName, node), - after.let { it?.dfs(fqName, node) }) - is ContentCodeBlock -> copy(children.map { it.dfs(fqName, node) }) - is ContentCodeInline -> copy(children.map { it.dfs(fqName, node) }) - is ContentDRILink -> copy(children.map { it.dfs(fqName, node) }) - is ContentResolvedLink -> copy(children.map { it.dfs(fqName, node) }) - is ContentEmbeddedResource -> copy(children.map { it.dfs(fqName, node) }) - is ContentTable -> copy(children = children.map { it.dfs(fqName, node) as ContentGroup }) - is ContentList -> copy(children.map { it.dfs(fqName, node) }) - is ContentGroup -> copy(children.map { it.dfs(fqName, node) }) - is PlatformHintedContent -> copy(inner.dfs(fqName, node)) - is ContentText -> if (text == fqName) node else this - is ContentBreakLine -> this - else -> this.also { context.logger.error("Could not recognize $this ContentNode in SamplesTransformer") } - } - } - - private fun fqNameToPsiElement(resolutionFacade: DokkaResolutionFacade, functionName: String): PsiElement? { - val packageName = functionName.takeWhile { it != '.' } - val descriptor = resolutionFacade.resolveSession.getPackageFragment(FqName(packageName)) - ?: return null.also { context.logger.warn("Cannot find descriptor for package $packageName") } - val symbol = resolveKDocLink( - BindingContext.EMPTY, - resolutionFacade, - descriptor, - null, - functionName.split(".") - ).firstOrNull() ?: return null.also { context.logger.warn("Unresolved function $functionName in @sample") } - return DescriptorToSourceUtils.descriptorToDeclaration(symbol) - } - - private fun contentCode( - sourceSets: Set<DisplaySourceSet>, - dri: Set<DRI>, - content: String, - language: String, - styles: Set<Style> = emptySet(), - extra: PropertyContainer<ContentNode> = PropertyContainer.empty() - ) = - ContentCodeBlock( - children = listOf( - ContentText( - text = content, - dci = DCI(dri, ContentKind.Sample), - sourceSets = sourceSets, - style = emptySet(), - extra = PropertyContainer.empty() - ) - ), - language = language, - dci = DCI(dri, ContentKind.Sample), - sourceSets = sourceSets, - style = styles + ContentStyle.RunnableSample + TextStyle.Monospace, - extra = extra - ) -} diff --git a/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt index 27428fc6..f2c3d3f0 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt @@ -1,26 +1,19 @@ package org.jetbrains.dokka.base.transformers.pages.sourcelinks -import com.intellij.psi.PsiDocumentManager -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiIdentifier import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet -import org.jetbrains.dokka.analysis.DescriptorDocumentableSource -import org.jetbrains.dokka.analysis.PsiDocumentableSource import org.jetbrains.dokka.base.DokkaBase import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.* +import org.jetbrains.dokka.model.Documentable +import org.jetbrains.dokka.model.DocumentableSource +import org.jetbrains.dokka.model.WithSources +import org.jetbrains.dokka.model.sourceSetIDs import org.jetbrains.dokka.pages.* import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.plugability.plugin import org.jetbrains.dokka.plugability.querySingle import org.jetbrains.dokka.transformers.pages.PageTransformer -import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource -import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.psi.psiUtil.getChildOfType -import org.jetbrains.kotlin.resolve.source.getPsi -import org.jetbrains.kotlin.utils.addToStdlib.cast import java.io.File class SourceLinksTransformer(val context: DokkaContext) : PageTransformer { @@ -80,31 +73,13 @@ class SourceLinksTransformer(val context: DokkaContext) : PageTransformer { val sourcePath = File(this.path).invariantSeparatorsPath val sourceLinkPath = File(sourceLink.path).invariantSeparatorsPath - val lineNumber = when (this) { - is DescriptorDocumentableSource -> this.descriptor - .cast<DeclarationDescriptorWithSource>() - .source.getPsi() - ?.lineNumber() - is PsiDocumentableSource -> this.psi.lineNumber() - else -> null - } + val lineNumber = this.computeLineNumber() return sourceLink.url + sourcePath.split(sourceLinkPath)[1] + sourceLink.lineSuffix + "${lineNumber ?: 1}" } - private fun PsiElement.lineNumber(): Int? { - val ktIdentifierTextRange = this.node?.findChildByType(KtTokens.IDENTIFIER)?.textRange - val javaIdentifierTextRange = this.getChildOfType<PsiIdentifier>()?.textRange - // synthetic and some light methods might return null - val textRange = ktIdentifierTextRange ?: javaIdentifierTextRange ?: textRange ?: return null - - val doc = PsiDocumentManager.getInstance(project).getDocument(containingFile) - // IJ uses 0-based line-numbers; external source browsers use 1-based - return doc?.getLineNumber(textRange.startOffset)?.plus(1) - } - private fun ContentNode.signatureGroupOrNull() = (this as? ContentGroup)?.takeIf { it.dci.kind == ContentKind.Symbol } @@ -150,4 +125,4 @@ data class SourceLink(val path: String, val url: String, val lineSuffix: String? sourceLinkDefinition.remoteLineSuffix, sourceSetData ) -}
\ No newline at end of file +} |