diff options
| author | Andrzej Ratajczak <andrzej.ratajczak98@gmail.com> | 2020-09-22 11:08:16 +0200 |
|---|---|---|
| committer | Andrzej Ratajczak <32793002+BarkingBad@users.noreply.github.com> | 2020-10-02 12:40:50 +0200 |
| commit | 8de5296b18083361055d11acf6d522c1eef821a4 (patch) | |
| tree | 5e4f4c42bf801f33c40c4efeb5601e0fc4523e36 /plugins/base | |
| parent | 71b03f6d311c6ebfdf67c593e97a7483a64844f4 (diff) | |
| download | dokka-8de5296b18083361055d11acf6d522c1eef821a4.tar.gz dokka-8de5296b18083361055d11acf6d522c1eef821a4.tar.bz2 dokka-8de5296b18083361055d11acf6d522c1eef821a4.zip | |
Make translators run in parallel.
Diffstat (limited to 'plugins/base')
3 files changed, 664 insertions, 533 deletions
diff --git a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt index 47180042..5c0f54d8 100644 --- a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt @@ -228,4 +228,4 @@ fun ContentPage.sourceSets() = this.content.sourceSets fun ContentEmbeddedResource.isImage(): Boolean { val imageExtensions = setOf("png", "jpg", "jpeg", "gif", "bmp", "tif", "webp", "svg") return File(address).extension.toLowerCase() in imageExtensions -}
\ No newline at end of file +} diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt index ecfd5172..d64a7b29 100644 --- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt @@ -1,5 +1,9 @@ package org.jetbrains.dokka.base.translators.descriptors +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.withContext import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.analysis.DescriptorDocumentableSource import org.jetbrains.dokka.analysis.DokkaResolutionFacade @@ -18,8 +22,9 @@ import org.jetbrains.dokka.transformers.sources.SourceToDocumentableTranslator import org.jetbrains.dokka.utilities.DokkaLogger import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor import org.jetbrains.kotlin.builtins.isBuiltinExtensionFunctionalType +import org.jetbrains.dokka.utilities.parallelMap +import org.jetbrains.dokka.utilities.parallelMapNotNull import org.jetbrains.kotlin.builtins.isExtensionFunctionType -import org.jetbrains.kotlin.builtins.isFunctionType import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype import org.jetbrains.kotlin.codegen.isJvmStaticInObjectOrClassOrInterface import org.jetbrains.kotlin.descriptors.* @@ -27,7 +32,6 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor -import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies import org.jetbrains.kotlin.idea.kdoc.findKDoc import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink import org.jetbrains.kotlin.load.kotlin.toSourceElement @@ -40,7 +44,6 @@ import org.jetbrains.kotlin.resolve.constants.ConstantValue 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.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.source.KotlinSourceElement import org.jetbrains.kotlin.resolve.source.PsiSourceElement @@ -49,6 +52,7 @@ import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny import org.jetbrains.kotlin.types.typeUtil.supertypes import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.safeAs +import java.lang.IllegalStateException import java.nio.file.Paths import org.jetbrains.kotlin.resolve.constants.AnnotationValue as ConstantsAnnotationValue import org.jetbrains.kotlin.resolve.constants.ArrayValue as ConstantsArrayValue @@ -59,7 +63,7 @@ class DefaultDescriptorToDocumentableTranslator( private val kotlinAnalysis: KotlinAnalysis ) : SourceToDocumentableTranslator { - override fun invoke(sourceSet: DokkaSourceSet, context: DokkaContext): DModule { + override suspend fun invoke(sourceSet: DokkaSourceSet, context: DokkaContext): DModule { val (environment, facade) = kotlinAnalysis[sourceSet] val packageFragments = environment.getSourceFiles().asSequence() .map { it.packageFqName } @@ -68,7 +72,7 @@ class DefaultDescriptorToDocumentableTranslator( .toList() return DokkaDescriptorVisitor(sourceSet, kotlinAnalysis[sourceSet].facade, context.logger).run { - packageFragments.mapNotNull { it.safeAs<PackageFragmentDescriptor>() }.map { + packageFragments.mapNotNull { it.safeAs<PackageFragmentDescriptor>() }.parallelMap { visitPackageFragmentDescriptor( it, DRIWithPlatformInfo(DRI.topLevel, emptyMap()) @@ -97,11 +101,7 @@ private class DokkaDescriptorVisitor( private val sourceSet: DokkaSourceSet, private val resolutionFacade: DokkaResolutionFacade, private val logger: DokkaLogger -) : DeclarationDescriptorVisitorEmptyBodies<Documentable, DRIWithPlatformInfo>() { - override fun visitDeclarationDescriptor(descriptor: DeclarationDescriptor, parent: DRIWithPlatformInfo): Nothing { - throw IllegalStateException("${javaClass.simpleName} should never enter ${descriptor.javaClass.simpleName}") - } - +) { private fun Collection<DeclarationDescriptor>.filterDescriptorsInSourceSet() = filter { it.toSourceElement.containingFile.toString().let { path -> path.isNotBlank() && sourceSet.sourceRoots.any { root -> @@ -112,26 +112,34 @@ private class DokkaDescriptorVisitor( private fun <T> T.toSourceSetDependent() = mapOf(sourceSet to this) - override fun visitPackageFragmentDescriptor( + suspend fun visitPackageFragmentDescriptor( descriptor: PackageFragmentDescriptor, parent: DRIWithPlatformInfo ): DPackage { val name = descriptor.fqName.asString().takeUnless { it.isBlank() } ?: "" val driWithPlatform = DRI(packageName = name).withEmptyInfo() val scope = descriptor.getMemberScope() - - return DPackage( - dri = driWithPlatform.dri, - functions = scope.functions(driWithPlatform, true), - properties = scope.properties(driWithPlatform, true), - classlikes = scope.classlikes(driWithPlatform, true), - typealiases = scope.typealiases(driWithPlatform, true), - documentation = descriptor.resolveDescriptorData(), - sourceSets = setOf(sourceSet) - ) + return coroutineScope { + val descriptorsWithKind = scope.getDescriptorsWithKind(true) + + val functions = async { descriptorsWithKind.functions.visitFunctions(driWithPlatform) } + val properties = async { descriptorsWithKind.properties.visitProperties(driWithPlatform) } + val classlikes = async { descriptorsWithKind.classlikes.visitClasslikes(driWithPlatform) } + val typealiases = async { descriptorsWithKind.typealiases.visitTypealiases(driWithPlatform) } + + DPackage( + dri = driWithPlatform.dri, + functions = functions.await(), + properties = properties.await(), + classlikes = classlikes.await(), + typealiases = typealiases.await(), + documentation = descriptor.resolveDescriptorData(), + sourceSets = setOf(sourceSet) + ) + } } - override fun visitClassDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DClasslike = + private suspend fun visitClassDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DClasslike = when (descriptor.kind) { ClassKind.ENUM_CLASS -> enumDescriptor(descriptor, parent) ClassKind.OBJECT -> objectDescriptor(descriptor, parent) @@ -140,37 +148,46 @@ private class DokkaDescriptorVisitor( else -> classDescriptor(descriptor, parent) } - private fun interfaceDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DInterface { + private suspend fun interfaceDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DInterface { val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() val scope = descriptor.unsubstitutedMemberScope val isExpect = descriptor.isExpect val isActual = descriptor.isActual val info = descriptor.resolveClassDescriptionData() - return DInterface( - dri = driWithPlatform.dri, - name = descriptor.name.asString(), - functions = scope.functions(driWithPlatform), - properties = scope.properties(driWithPlatform), - classlikes = scope.classlikes(driWithPlatform), - sources = descriptor.createSources(), - expectPresentInSet = sourceSet.takeIf { isExpect }, - visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), - supertypes = info.supertypes.toSourceSetDependent(), - documentation = info.docs, - generics = descriptor.declaredTypeParameters.map { it.toVariantTypeParameter() }, - companion = descriptor.companion(driWithPlatform), - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), - ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent()) + return coroutineScope { + val descriptorsWithKind = scope.getDescriptorsWithKind() + + val functions = async { descriptorsWithKind.functions.visitFunctions(driWithPlatform) } + val properties = async { descriptorsWithKind.properties.visitProperties(driWithPlatform) } + val classlikes = async { descriptorsWithKind.classlikes.visitClasslikes(driWithPlatform) } + val generics = async { descriptor.declaredTypeParameters.parallelMap { it.toVariantTypeParameter() } } + + DInterface( + dri = driWithPlatform.dri, + name = descriptor.name.asString(), + functions = functions.await(), + properties = properties.await(), + classlikes = classlikes.await(), + sources = descriptor.createSources(), + expectPresentInSet = sourceSet.takeIf { isExpect }, + visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), + supertypes = info.supertypes.toSourceSetDependent(), + documentation = info.docs, + generics = generics.await(), + companion = descriptor.companion(driWithPlatform), + sourceSets = setOf(sourceSet), + isExpectActual = (isExpect || isActual), + extra = PropertyContainer.withAll( + descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), + descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), + ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent()) + ) ) - ) + } } - private fun objectDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DObject { + private suspend fun objectDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DObject { val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() val scope = descriptor.unsubstitutedMemberScope val isExpect = descriptor.isExpect @@ -178,109 +195,149 @@ private class DokkaDescriptorVisitor( val info = descriptor.resolveClassDescriptionData() - return DObject( - dri = driWithPlatform.dri, - name = descriptor.name.asString(), - functions = scope.functions(driWithPlatform), - properties = scope.properties(driWithPlatform), - classlikes = scope.classlikes(driWithPlatform), - sources = descriptor.createSources(), - expectPresentInSet = sourceSet.takeIf { isExpect }, - visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), - supertypes = info.supertypes.toSourceSetDependent(), - documentation = info.docs, - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), - ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent()) + return coroutineScope { + val descriptorsWithKind = scope.getDescriptorsWithKind() + + val functions = async { descriptorsWithKind.functions.visitFunctions(driWithPlatform) } + val properties = async { descriptorsWithKind.properties.visitProperties(driWithPlatform) } + val classlikes = async { descriptorsWithKind.classlikes.visitClasslikes(driWithPlatform) } + + DObject( + dri = driWithPlatform.dri, + name = descriptor.name.asString(), + functions = functions.await(), + properties = properties.await(), + classlikes = classlikes.await(), + sources = descriptor.createSources(), + expectPresentInSet = sourceSet.takeIf { isExpect }, + visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), + supertypes = info.supertypes.toSourceSetDependent(), + documentation = info.docs, + sourceSets = setOf(sourceSet), + isExpectActual = (isExpect || isActual), + extra = PropertyContainer.withAll( + descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), + descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), + ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent()) + ) ) - ) + } + + } - private fun enumDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DEnum { + private suspend fun enumDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DEnum { val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() val scope = descriptor.unsubstitutedMemberScope val isExpect = descriptor.isExpect val isActual = descriptor.isActual val info = descriptor.resolveClassDescriptionData() - return DEnum( - dri = driWithPlatform.dri, - name = descriptor.name.asString(), - entries = scope.enumEntries(driWithPlatform), - constructors = descriptor.constructors.map { visitConstructorDescriptor(it, driWithPlatform) }, - functions = scope.functions(driWithPlatform), - properties = scope.properties(driWithPlatform), - classlikes = scope.classlikes(driWithPlatform), - sources = descriptor.createSources(), - expectPresentInSet = sourceSet.takeIf { isExpect }, - visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), - supertypes = info.supertypes.toSourceSetDependent(), - documentation = info.docs, - companion = descriptor.companion(driWithPlatform), - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), - ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent()) + return coroutineScope { + val descriptorsWithKind = scope.getDescriptorsWithKind() + + val functions = async { descriptorsWithKind.functions.visitFunctions(driWithPlatform) } + val properties = async { descriptorsWithKind.properties.visitProperties(driWithPlatform) } + val classlikes = async { descriptorsWithKind.classlikes.visitClasslikes(driWithPlatform) } + val constructors = async { descriptor.constructors.parallelMap { visitConstructorDescriptor(it, driWithPlatform) } } + val entries = async { descriptorsWithKind.enumEntries.visitEnumEntries(driWithPlatform) } + + DEnum( + dri = driWithPlatform.dri, + name = descriptor.name.asString(), + entries = entries.await(), + constructors = constructors.await(), + functions = functions.await(), + properties = properties.await(), + classlikes = classlikes.await(), + sources = descriptor.createSources(), + expectPresentInSet = sourceSet.takeIf { isExpect }, + visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), + supertypes = info.supertypes.toSourceSetDependent(), + documentation = info.docs, + companion = descriptor.companion(driWithPlatform), + sourceSets = setOf(sourceSet), + isExpectActual = (isExpect || isActual), + extra = PropertyContainer.withAll( + descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), + descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), + ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent()) + ) ) - ) + } } - private fun enumEntryDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DEnumEntry { + private suspend fun visitEnumEntryDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DEnumEntry { val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() val scope = descriptor.unsubstitutedMemberScope val isExpect = descriptor.isExpect - return DEnumEntry( - dri = driWithPlatform.dri, - name = descriptor.name.asString(), - documentation = descriptor.resolveDescriptorData(), - classlikes = scope.classlikes(driWithPlatform), - functions = scope.functions(driWithPlatform), - properties = scope.properties(driWithPlatform), - sourceSets = setOf(sourceSet), - expectPresentInSet = sourceSet.takeIf { isExpect }, - extra = PropertyContainer.withAll( - descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), - ConstructorValues(descriptor.getAppliedConstructorParameters().toSourceSetDependent()) + return coroutineScope { + val descriptorsWithKind = scope.getDescriptorsWithKind() + + val functions = async { descriptorsWithKind.functions.visitFunctions(driWithPlatform) } + val properties = async { descriptorsWithKind.properties.visitProperties(driWithPlatform) } + val classlikes = async { descriptorsWithKind.classlikes.visitClasslikes(driWithPlatform) } + + DEnumEntry( + dri = driWithPlatform.dri, + name = descriptor.name.asString(), + documentation = descriptor.resolveDescriptorData(), + functions = functions.await(), + properties = properties.await(), + classlikes = classlikes.await(), + sourceSets = setOf(sourceSet), + expectPresentInSet = sourceSet.takeIf { isExpect }, + extra = PropertyContainer.withAll( + descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), + descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), + ConstructorValues(descriptor.getAppliedConstructorParameters().toSourceSetDependent()) + ) ) - ) + } } - fun annotationDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DAnnotation { + private suspend fun annotationDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DAnnotation { val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() val scope = descriptor.unsubstitutedMemberScope val isExpect = descriptor.isExpect val isActual = descriptor.isActual - return DAnnotation( - dri = driWithPlatform.dri, - name = descriptor.name.asString(), - documentation = descriptor.resolveDescriptorData(), - classlikes = scope.classlikes(driWithPlatform), - functions = scope.functions(driWithPlatform), - properties = scope.properties(driWithPlatform), - expectPresentInSet = sourceSet.takeIf { isExpect }, - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - descriptor.getAnnotations().toSourceSetDependent().toAnnotations() - ), - companion = descriptor.companionObjectDescriptor?.let { objectDescriptor(it, driWithPlatform) }, - visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), - generics = descriptor.declaredTypeParameters.map { it.toVariantTypeParameter() }, - constructors = descriptor.constructors.map { visitConstructorDescriptor(it, driWithPlatform) }, - sources = descriptor.createSources() - ) + return coroutineScope { + val descriptorsWithKind = scope.getDescriptorsWithKind() + + val functions = async { descriptorsWithKind.functions.visitFunctions(driWithPlatform) } + val properties = async { descriptorsWithKind.properties.visitProperties(driWithPlatform) } + val classlikes = async { descriptorsWithKind.classlikes.visitClasslikes(driWithPlatform) } + val generics = async { descriptor.declaredTypeParameters.parallelMap { it.toVariantTypeParameter() } } + val constructors = async { descriptor.constructors.parallelMap { visitConstructorDescriptor(it, driWithPlatform) } } + + DAnnotation( + dri = driWithPlatform.dri, + name = descriptor.name.asString(), + documentation = descriptor.resolveDescriptorData(), + functions = functions.await(), + properties = properties.await(), + classlikes = classlikes.await(), + expectPresentInSet = sourceSet.takeIf { isExpect }, + sourceSets = setOf(sourceSet), + isExpectActual = (isExpect || isActual), + extra = PropertyContainer.withAll( + descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), + descriptor.getAnnotations().toSourceSetDependent().toAnnotations() + ), + companion = descriptor.companionObjectDescriptor?.let { objectDescriptor(it, driWithPlatform) }, + visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), + generics = generics.await(), + constructors = constructors.await(), + sources = descriptor.createSources() + ) + } + + } - private fun classDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DClass { + private suspend fun classDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DClass { val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() val scope = descriptor.unsubstitutedMemberScope val isExpect = descriptor.isExpect @@ -288,163 +345,188 @@ private class DokkaDescriptorVisitor( val info = descriptor.resolveClassDescriptionData() val actual = descriptor.createSources() - return DClass( - dri = driWithPlatform.dri, - name = descriptor.name.asString(), - constructors = descriptor.constructors.map { - visitConstructorDescriptor( - it, - if (it.isPrimary) DRIWithPlatformInfo(driWithPlatform.dri, actual) - else DRIWithPlatformInfo(driWithPlatform.dri, emptyMap()) + return coroutineScope { + val descriptorsWithKind = scope.getDescriptorsWithKind() + + val functions = async { descriptorsWithKind.functions.visitFunctions(driWithPlatform) } + val properties = async { descriptorsWithKind.properties.visitProperties(driWithPlatform) } + val classlikes = async { descriptorsWithKind.classlikes.visitClasslikes(driWithPlatform) } + val generics = async { descriptor.declaredTypeParameters.parallelMap { it.toVariantTypeParameter() } } + val constructors = async { + descriptor.constructors.parallelMap { + visitConstructorDescriptor( + it, + if (it.isPrimary) DRIWithPlatformInfo(driWithPlatform.dri, actual) + else DRIWithPlatformInfo(driWithPlatform.dri, emptyMap()) + ) + } + } + + DClass( + dri = driWithPlatform.dri, + name = descriptor.name.asString(), + constructors = constructors.await(), + functions = functions.await(), + properties = properties.await(), + classlikes = classlikes.await(), + sources = actual, + expectPresentInSet = sourceSet.takeIf { isExpect }, + visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), + supertypes = info.supertypes.toSourceSetDependent(), + generics = generics.await(), + documentation = info.docs, + modifier = descriptor.modifier().toSourceSetDependent(), + companion = descriptor.companion(driWithPlatform), + sourceSets = setOf(sourceSet), + isExpectActual = (isExpect || isActual), + extra = PropertyContainer.withAll<DClass>( + descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), + descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), + ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent()) ) - }, - functions = scope.functions(driWithPlatform), - properties = scope.properties(driWithPlatform), - classlikes = scope.classlikes(driWithPlatform), - sources = actual, - expectPresentInSet = sourceSet.takeIf { isExpect }, - visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), - supertypes = info.supertypes.toSourceSetDependent(), - generics = descriptor.declaredTypeParameters.map { it.toVariantTypeParameter() }, - documentation = info.docs, - modifier = descriptor.modifier().toSourceSetDependent(), - companion = descriptor.companion(driWithPlatform), - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll<DClass>( - descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), - ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent()) ) - ) + } } - override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, parent: DRIWithPlatformInfo): DProperty { + private suspend fun visitPropertyDescriptor(descriptor: PropertyDescriptor, parent: DRIWithPlatformInfo): DProperty { val dri = parent.dri.copy(callable = Callable.from(descriptor)) val isExpect = descriptor.isExpect val isActual = descriptor.isActual val actual = descriptor.createSources() - return DProperty( - dri = dri, - name = descriptor.name.asString(), - receiver = descriptor.extensionReceiverParameter?.let { - visitReceiverParameterDescriptor(it, DRIWithPlatformInfo(dri, actual)) - }, - sources = actual, - getter = descriptor.accessors.filterIsInstance<PropertyGetterDescriptor>().singleOrNull()?.let { - visitPropertyAccessorDescriptor(it, descriptor, dri) - }, - setter = descriptor.accessors.filterIsInstance<PropertySetterDescriptor>().singleOrNull()?.let { - visitPropertyAccessorDescriptor(it, descriptor, dri) - }, - visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), - documentation = descriptor.resolveDescriptorData(), - modifier = descriptor.modifier().toSourceSetDependent(), - type = descriptor.returnType!!.toBound(), - expectPresentInSet = sourceSet.takeIf { isExpect }, - sourceSets = setOf(sourceSet), - generics = descriptor.typeParameters.map { it.toVariantTypeParameter() }, - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll(listOfNotNull( - (descriptor.additionalExtras() + descriptor.getAnnotationsWithBackingField() - .toAdditionalExtras()).toSet().toSourceSetDependent().toAdditionalModifiers(), - descriptor.getAnnotationsWithBackingField().toSourceSetDependent().toAnnotations(), - descriptor.getDefaultValue()?.let { DefaultValue(it) } - )) - ) + + return coroutineScope { + val generics = async { descriptor.typeParameters.parallelMap { it.toVariantTypeParameter() } } + + DProperty( + dri = dri, + name = descriptor.name.asString(), + receiver = descriptor.extensionReceiverParameter?.let { + visitReceiverParameterDescriptor(it, DRIWithPlatformInfo(dri, actual)) + }, + sources = actual, + getter = descriptor.accessors.filterIsInstance<PropertyGetterDescriptor>().singleOrNull()?.let { + visitPropertyAccessorDescriptor(it, descriptor, dri) + }, + setter = descriptor.accessors.filterIsInstance<PropertySetterDescriptor>().singleOrNull()?.let { + visitPropertyAccessorDescriptor(it, descriptor, dri) + }, + visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), + documentation = descriptor.resolveDescriptorData(), + modifier = descriptor.modifier().toSourceSetDependent(), + type = descriptor.returnType!!.toBound(), + expectPresentInSet = sourceSet.takeIf { isExpect }, + sourceSets = setOf(sourceSet), + generics = generics.await(), + isExpectActual = (isExpect || isActual), + extra = PropertyContainer.withAll(listOfNotNull( + (descriptor.additionalExtras() + descriptor.getAnnotationsWithBackingField() + .toAdditionalExtras()).toSet().toSourceSetDependent().toAdditionalModifiers(), + descriptor.getAnnotationsWithBackingField().toSourceSetDependent().toAnnotations(), + descriptor.getDefaultValue()?.let { DefaultValue(it) } + )) + ) + } } - fun CallableMemberDescriptor.createDRI(wasOverridenBy: DRI? = null): Pair<DRI, DRI?> = + private fun CallableMemberDescriptor.createDRI(wasOverridenBy: DRI? = null): Pair<DRI, DRI?> = if (kind == CallableMemberDescriptor.Kind.DECLARATION || overriddenDescriptors.isEmpty()) Pair(DRI.from(this), wasOverridenBy) else overriddenDescriptors.first().createDRI(DRI.from(this)) - override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, parent: DRIWithPlatformInfo): DFunction { + private suspend fun visitFunctionDescriptor(descriptor: FunctionDescriptor, parent: DRIWithPlatformInfo): DFunction { val (dri, inheritedFrom) = descriptor.createDRI() val isExpect = descriptor.isExpect val isActual = descriptor.isActual val actual = descriptor.createSources() - return DFunction( - dri = dri, - name = descriptor.name.asString(), - isConstructor = false, - receiver = descriptor.extensionReceiverParameter?.let { - visitReceiverParameterDescriptor(it, DRIWithPlatformInfo(dri, actual)) - }, - parameters = descriptor.valueParameters.mapIndexed { index, desc -> - parameter(index, desc, DRIWithPlatformInfo(dri, actual)) - }, - expectPresentInSet = sourceSet.takeIf { isExpect }, - sources = actual, - visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), - generics = descriptor.typeParameters.map { it.toVariantTypeParameter() }, - documentation = descriptor.takeIf { it.kind != CallableMemberDescriptor.Kind.SYNTHESIZED } - ?.resolveDescriptorData() ?: emptyMap(), - modifier = descriptor.modifier().toSourceSetDependent(), - type = descriptor.returnType!!.toBound(), - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - InheritedFunction(inheritedFrom.toSourceSetDependent()), - descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - descriptor.getAnnotations().toSourceSetDependent().toAnnotations() + return coroutineScope { + val generics = async { descriptor.typeParameters.parallelMap { it.toVariantTypeParameter() } } + + DFunction( + dri = dri, + name = descriptor.name.asString(), + isConstructor = false, + receiver = descriptor.extensionReceiverParameter?.let { + visitReceiverParameterDescriptor(it, DRIWithPlatformInfo(dri, actual)) + }, + parameters = descriptor.valueParameters.mapIndexed { index, desc -> + parameter(index, desc, DRIWithPlatformInfo(dri, actual)) + }, + expectPresentInSet = sourceSet.takeIf { isExpect }, + sources = actual, + visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), + generics = generics.await(), + documentation = descriptor.takeIf { it.kind != CallableMemberDescriptor.Kind.SYNTHESIZED } + ?.resolveDescriptorData() ?: emptyMap(), + modifier = descriptor.modifier().toSourceSetDependent(), + type = descriptor.returnType!!.toBound(), + sourceSets = setOf(sourceSet), + isExpectActual = (isExpect || isActual), + extra = PropertyContainer.withAll( + InheritedFunction(inheritedFrom.toSourceSetDependent()), + descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), + descriptor.getAnnotations().toSourceSetDependent().toAnnotations() + ) ) - ) + } } - override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, parent: DRIWithPlatformInfo): DFunction { + suspend fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, parent: DRIWithPlatformInfo): DFunction { val name = descriptor.constructedClass.name.toString() val dri = parent.dri.copy(callable = Callable.from(descriptor, name)) val actual = descriptor.createSources() val isExpect = descriptor.isExpect val isActual = descriptor.isActual - return DFunction( - dri = dri, - name = name, - isConstructor = true, - receiver = descriptor.extensionReceiverParameter?.let { - visitReceiverParameterDescriptor(it, DRIWithPlatformInfo(dri, actual)) - }, - parameters = descriptor.valueParameters.mapIndexed { index, desc -> - parameter(index, desc, DRIWithPlatformInfo(dri, actual)) - }, - sources = actual, - expectPresentInSet = sourceSet.takeIf { isExpect }, - visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), - documentation = descriptor.resolveDescriptorData().let { sourceSetDependent -> - if (descriptor.isPrimary) { - sourceSetDependent.map { entry -> - Pair( - entry.key, - entry.value.copy(children = (entry.value.children.find { it is Constructor }?.root?.let { constructor -> - listOf(Description(constructor)) - } ?: emptyList<TagWrapper>()) + entry.value.children.filterIsInstance<Param>())) - }.toMap() - } else { - sourceSetDependent + return coroutineScope { + val generics = async { descriptor.typeParameters.parallelMap { it.toVariantTypeParameter() } } + + DFunction( + dri = dri, + name = name, + isConstructor = true, + receiver = descriptor.extensionReceiverParameter?.let { + visitReceiverParameterDescriptor(it, DRIWithPlatformInfo(dri, actual)) + }, + parameters = descriptor.valueParameters.mapIndexed { index, desc -> + parameter(index, desc, DRIWithPlatformInfo(dri, actual)) + }, + sources = actual, + expectPresentInSet = sourceSet.takeIf { isExpect }, + visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), + documentation = descriptor.resolveDescriptorData().let { sourceSetDependent -> + if (descriptor.isPrimary) { + sourceSetDependent.map { entry -> + Pair( + entry.key, + entry.value.copy(children = (entry.value.children.find { it is Constructor }?.root?.let { constructor -> + listOf(Description(constructor)) + } ?: emptyList<TagWrapper>()) + entry.value.children.filterIsInstance<Param>())) + }.toMap() + } else { + sourceSetDependent + } + }, + type = descriptor.returnType.toBound(), + modifier = descriptor.modifier().toSourceSetDependent(), + generics = generics.await(), + sourceSets = setOf(sourceSet), + isExpectActual = (isExpect || isActual), + extra = PropertyContainer.withAll<DFunction>( + descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), + descriptor.getAnnotations().toSourceSetDependent().toAnnotations() + ).let { + if (descriptor.isPrimary) { + it + PrimaryConstructorExtra + } else it } - |
