diff options
author | Paweł Marks <pmarks@virtuslab.com> | 2022-01-18 10:51:31 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-18 12:51:31 +0300 |
commit | 62f2919f403a4617dfc622a260b8c4fc8fc13716 (patch) | |
tree | a16d9bd922cd75fb15658d6a6b38dfacc362e399 /plugins/base/src/main | |
parent | 6b729257b89ff5a19a52045efa386349feec0bc6 (diff) | |
download | dokka-62f2919f403a4617dfc622a260b8c4fc8fc13716.tar.gz dokka-62f2919f403a4617dfc622a260b8c4fc8fc13716.tar.bz2 dokka-62f2919f403a4617dfc622a260b8c4fc8fc13716.zip |
Add external documentable provider (#2307)
* Add external documentable provider
* Update the api spec of base plugin
* Hide mistakenly exposed fields
* Add comments and fix naming
Diffstat (limited to 'plugins/base/src/main')
5 files changed, 103 insertions, 3 deletions
diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt index 03fbf64e..a26f6dcd 100644 --- a/plugins/base/src/main/kotlin/DokkaBase.kt +++ b/plugins/base/src/main/kotlin/DokkaBase.kt @@ -29,6 +29,9 @@ import org.jetbrains.dokka.base.translators.documentables.DefaultDocumentableToP import org.jetbrains.dokka.base.translators.psi.DefaultPsiToDocumentableTranslator import org.jetbrains.dokka.base.generation.SingleModuleGeneration import org.jetbrains.dokka.base.renderers.html.command.consumers.ReplaceVersionsConsumer +import org.jetbrains.dokka.base.translators.descriptors.DefaultExternalDocumentablesProvider +import org.jetbrains.dokka.base.translators.descriptors.ExternalClasslikesTranslator +import org.jetbrains.dokka.base.translators.descriptors.ExternalDocumentablesProvider import org.jetbrains.dokka.plugability.DokkaPlugin import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer import org.jetbrains.dokka.transformers.pages.PageTransformer @@ -46,6 +49,8 @@ class DokkaBase : DokkaPlugin() { val kotlinAnalysis by extensionPoint<KotlinAnalysis>() val tabSortingStrategy by extensionPoint<TabSortingStrategy>() val immediateHtmlCommandConsumer by extensionPoint<ImmediateHtmlCommandConsumer>() + val externalDocumentablesProvider by extensionPoint<ExternalDocumentablesProvider>() + val externalClasslikesTranslator by extensionPoint<ExternalClasslikesTranslator>() val singleGeneration by extending { CoreExtensions.generation providing ::SingleModuleGeneration @@ -252,4 +257,12 @@ class DokkaBase : DokkaPlugin() { val baseSearchbarDataInstaller by extending { htmlPreprocessors providing ::SearchbarDataInstaller order { after(sourceLinksTransformer) } } + + val defaultExternalDocumentablesProvider by extending { + externalDocumentablesProvider providing ::DefaultExternalDocumentablesProvider + } + + val defaultExternalClasslikesTranslator by extending { + externalClasslikesTranslator providing ::DefaultDescriptorToDocumentableTranslator + } } diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt index 04716e16..e996a865 100644 --- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt @@ -2,6 +2,7 @@ package org.jetbrains.dokka.base.translators.descriptors import com.intellij.psi.PsiNamedElement import com.intellij.psi.util.PsiLiteralUtil.* +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.runBlocking @@ -55,6 +56,7 @@ import org.jetbrains.kotlin.resolve.constants.KClassValue.Value.LocalClass import org.jetbrains.kotlin.resolve.constants.KClassValue.Value.NormalClass import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull +import org.jetbrains.kotlin.resolve.descriptorUtil.parents import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.source.KotlinSourceElement import org.jetbrains.kotlin.resolve.source.PsiSourceElement @@ -79,8 +81,8 @@ import org.jetbrains.kotlin.resolve.constants.BooleanValue as ConstantsBooleanVa import org.jetbrains.kotlin.resolve.constants.NullValue as ConstantsNullValue class DefaultDescriptorToDocumentableTranslator( - context: DokkaContext -) : AsyncSourceToDocumentableTranslator { + private val context: DokkaContext +) : AsyncSourceToDocumentableTranslator, ExternalClasslikesTranslator { private val kotlinAnalysis: KotlinAnalysis = context.plugin<DokkaBase>().querySingle { kotlinAnalysis } @@ -109,6 +111,15 @@ class DefaultDescriptorToDocumentableTranslator( ) } } + + override fun translateClassDescriptor(descriptor: ClassDescriptor, sourceSet: DokkaSourceSet): DClasslike { + val driInfo = DRI.from(descriptor.parents.first()).withEmptyInfo() + + return runBlocking(Dispatchers.Default) { + DokkaDescriptorVisitor(sourceSet, kotlinAnalysis[sourceSet].facade, context.logger) + .visitClassDescriptor(descriptor, driInfo) + } + } } data class DRIWithPlatformInfo( @@ -162,7 +173,7 @@ private class DokkaDescriptorVisitor( } } - private suspend fun visitClassDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DClasslike = + suspend fun visitClassDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DClasslike = when (descriptor.kind) { ClassKind.ENUM_CLASS -> enumDescriptor(descriptor, parent) ClassKind.OBJECT -> objectDescriptor(descriptor, parent) diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultExternalDocumentablesProvider.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultExternalDocumentablesProvider.kt new file mode 100644 index 00000000..05982301 --- /dev/null +++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultExternalDocumentablesProvider.kt @@ -0,0 +1,42 @@ +package org.jetbrains.dokka.base.translators.descriptors + +import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet +import org.jetbrains.dokka.base.DokkaBase +import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.model.DClasslike +import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.plugability.querySingle +import org.jetbrains.dokka.plugability.plugin +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.PackageViewDescriptor +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.resolve.scopes.MemberScope +import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered + +class DefaultExternalDocumentablesProvider(context: DokkaContext) : ExternalDocumentablesProvider { + private val analysis = context.plugin<DokkaBase>().querySingle { kotlinAnalysis } + + private val translator = context.plugin<DokkaBase>().querySingle { externalClasslikesTranslator } + + override fun findClasslike(dri: DRI, sourceSet: DokkaSourceSet): DClasslike? { + val pkg = dri.packageName?.let { FqName(it) } ?: FqName.ROOT + val names = dri.classNames?.split('.') ?: return null + + val packageDsc = analysis[sourceSet].facade.moduleDescriptor.getPackage(pkg) + val classDsc = names.fold<String, DeclarationDescriptor?>(packageDsc) { dsc, name -> + dsc?.scope?.getDescriptorsFiltered { it.identifier == name } + ?.filterIsInstance<ClassDescriptor>() + ?.firstOrNull() + } + + return (classDsc as? ClassDescriptor)?.let { translator.translateClassDescriptor(it, sourceSet) } + } + + private val DeclarationDescriptor.scope: MemberScope + get() = when (this) { + is PackageViewDescriptor -> memberScope + is ClassDescriptor -> unsubstitutedMemberScope + else -> throw IllegalArgumentException("Unexpected type of descriptor: ${this::class}") + } +}
\ No newline at end of file diff --git a/plugins/base/src/main/kotlin/translators/descriptors/ExternalClasslikesTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/ExternalClasslikesTranslator.kt new file mode 100644 index 00000000..ec4d1ee9 --- /dev/null +++ b/plugins/base/src/main/kotlin/translators/descriptors/ExternalClasslikesTranslator.kt @@ -0,0 +1,12 @@ +package org.jetbrains.dokka.base.translators.descriptors + +import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet +import org.jetbrains.dokka.model.DClasslike +import org.jetbrains.kotlin.descriptors.ClassDescriptor + +/** + * Service translating [ClassDescriptor]s of symbols defined outside of documented project to [DClasslike]s. + */ +interface ExternalClasslikesTranslator { + fun translateClassDescriptor(descriptor: ClassDescriptor, sourceSet: DokkaSourceSet): DClasslike +}
\ No newline at end of file diff --git a/plugins/base/src/main/kotlin/translators/descriptors/ExternalDocumentablesProvider.kt b/plugins/base/src/main/kotlin/translators/descriptors/ExternalDocumentablesProvider.kt new file mode 100644 index 00000000..c1dbfc28 --- /dev/null +++ b/plugins/base/src/main/kotlin/translators/descriptors/ExternalDocumentablesProvider.kt @@ -0,0 +1,22 @@ +package org.jetbrains.dokka.base.translators.descriptors + +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.model.DClasslike + +/** + * Service that can be queried with [DRI] and source set to obtain a documentable for classlike. + * + * There are some cases when there is a need to process documentables of classlikes that were not defined + * in the project itself but are somehow related to the symbols defined in the documented project (e.g. are supertypes + * of classes defined in project). + */ +interface ExternalDocumentablesProvider { + + /** + * Returns [DClasslike] matching provided [DRI] in specified source set. + * + * Result is null if compiler haven't generated matching class descriptor. + */ + fun findClasslike(dri: DRI, sourceSet: DokkaConfiguration.DokkaSourceSet): DClasslike? +}
\ No newline at end of file |