diff options
author | Andrzej Ratajczak <andrzej.ratajczak98@gmail.com> | 2020-09-17 13:35:13 +0200 |
---|---|---|
committer | Paweł Marks <Kordyjan@users.noreply.github.com> | 2020-09-28 17:22:14 +0200 |
commit | 64ec7ad22e9541b639e854aa413a2cffd650e8d0 (patch) | |
tree | 42106fc356b23ce1a3c394deccb59e74d80ff0f0 /plugins/base/src/main | |
parent | 2274d9261a59570cc3a1a26c3f7ddc167678fe8b (diff) | |
download | dokka-64ec7ad22e9541b639e854aa413a2cffd650e8d0.tar.gz dokka-64ec7ad22e9541b639e854aa413a2cffd650e8d0.tar.bz2 dokka-64ec7ad22e9541b639e854aa413a2cffd650e8d0.zip |
Add better handling of functional types in rendered output
Diffstat (limited to 'plugins/base/src/main')
3 files changed, 49 insertions, 25 deletions
diff --git a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt index 0a22cece..d701de04 100644 --- a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt +++ b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt @@ -323,14 +323,15 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog when (p) { is TypeParameter -> link(p.name, p.dri) - is TypeConstructor -> if (p.function) + is FunctionalTypeConstructor -> +funType(mainDRI.single(), mainSourcesetData, p) - else + + is GenericTypeConstructor -> group(styles = emptySet()) { val linkText = if (showFullyQualifiedName && p.dri.packageName != null) { "${p.dri.packageName}.${p.dri.classNames.orEmpty()}" } else p.dri.classNames.orEmpty() - + if (p.presentableName != null) text(p.presentableName + ": ") link(linkText, p.dri) list(p.projections, prefix = "<", suffix = ">") { signatureForProjection(it, showFullyQualifiedName) @@ -357,14 +358,18 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog is UnresolvedBound -> text(p.name) } - private fun funType(dri: DRI, sourceSets: Set<DokkaSourceSet>, type: TypeConstructor) = + private fun funType(dri: DRI, sourceSets: Set<DokkaSourceSet>, type: FunctionalTypeConstructor) = contentBuilder.contentFor(dri, sourceSets, ContentKind.Main) { - if (type.extension) { + + if (type.presentableName != null) text(type.presentableName + ": ") + if (type.isSuspendable) text("suspend ") + + if (type.isExtensionFunction) { signatureForProjection(type.projections.first()) text(".") } - val args = if (type.extension) + val args = if (type.isExtensionFunction) type.projections.drop(1) else type.projections @@ -379,16 +384,11 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog } } -private fun PrimitiveJavaType.translateToKotlin() = TypeConstructor( +private fun PrimitiveJavaType.translateToKotlin() = GenericTypeConstructor( dri = dri, - projections = emptyList() + projections = emptyList(), + presentableName = null ) private val DTypeParameter.nontrivialBounds: List<Bound> get() = bounds.filterNot { it is Nullable && it.inner.driOrNull == DriOfAny } - -val TypeConstructor.function - get() = modifier == FunctionModifiers.FUNCTION || modifier == FunctionModifiers.EXTENSION - -val TypeConstructor.extension - get() = modifier == FunctionModifiers.EXTENSION diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt index f58b2b36..8525586a 100644 --- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt @@ -17,8 +17,11 @@ import org.jetbrains.dokka.model.properties.PropertyContainer import org.jetbrains.dokka.plugability.DokkaContext 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.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.* import org.jetbrains.kotlin.descriptors.ClassKind @@ -586,7 +589,7 @@ private class DokkaDescriptorVisitor( private fun ClassDescriptor.resolveClassDescriptionData(): ClassInfo { fun toTypeConstructor(kt: KotlinType) = - TypeConstructor( + GenericTypeConstructor( DRI.from(kt.constructor.declarationDescriptor as DeclarationDescriptor), kt.arguments.map { it.toProjection() }) @@ -621,7 +624,7 @@ private class DokkaDescriptorVisitor( private fun TypeParameterDescriptor.toVariantTypeParameter() = DTypeParameter( variantTypeParameter( - TypeParameter(DRI.from(this), name.identifier) + TypeParameter(DRI.from(this), name.identifier, annotations.getPresentableName()) ), resolveDescriptorData(), null, @@ -630,6 +633,10 @@ private class DokkaDescriptorVisitor( extra = PropertyContainer.withAll(additionalExtras().toSourceSetDependent().toAdditionalModifiers()) ) + private fun org.jetbrains.kotlin.descriptors.annotations.Annotations.getPresentableName(): String? = + map { it.toAnnotation() }.singleOrNull { it.dri.classNames == "ParameterName" }?.params?.get("name") + .safeAs<StringValue>()?.value?.drop(1)?.dropLast(1) // Dropping enclosing doublequotes because we don't want to have it in our custom signature serializer + private fun KotlinType.toBound(): Bound = when (this) { is DynamicType -> Dynamic is AbbreviatedType -> TypeAliased( @@ -639,14 +646,20 @@ private class DokkaDescriptorVisitor( else -> when (val ctor = constructor.declarationDescriptor) { is TypeParameterDescriptor -> TypeParameter( dri = DRI.from(ctor), - name = ctor.name.asString() + name = ctor.name.asString(), + presentableName = annotations.getPresentableName() + ) + is FunctionClassDescriptor -> FunctionalTypeConstructor( + DRI.from(ctor), + arguments.map { it.toProjection() }, + isExtensionFunction = isExtensionFunctionType || isBuiltinExtensionFunctionalType, + isSuspendable = isSuspendFunctionTypeOrSubtype, + presentableName = annotations.getPresentableName() ) - else -> TypeConstructor( + else -> GenericTypeConstructor( DRI.from(ctor!!), // TODO: remove '!!' arguments.map { it.toProjection() }, - if (isExtensionFunctionType) FunctionModifiers.EXTENSION - else if (isFunctionType) FunctionModifiers.FUNCTION - else FunctionModifiers.NONE + annotations.getPresentableName() ) }.let { if (isMarkedNullable) Nullable(it) else it diff --git a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt index c413f5c8..d67bd9f5 100644 --- a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt @@ -22,9 +22,11 @@ import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.transformers.sources.SourceToDocumentableTranslator import org.jetbrains.dokka.utilities.DokkaLogger import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation +import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaClassDescriptor import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.propertyNameByGetMethodName @@ -139,7 +141,7 @@ class DefaultPsiToDocumentableTranslator( psiClass.isInterface -> DRI.from(psiClass) to JavaClassKindTypes.INTERFACE else -> DRI.from(psiClass) to JavaClassKindTypes.CLASS } - TypeConstructor( + GenericTypeConstructor( dri, psi.parameters.map(::getProjection) ) to javaClassKind @@ -370,11 +372,19 @@ class DefaultPsiToDocumentableTranslator( dri = DRI.from(resolved), name = resolved.name.orEmpty() ) - else -> - TypeConstructor(DRI.from(resolved), type.parameters.map { getProjection(it) }) + Regex("kotlin\\.jvm\\.functions\\.Function.*").matches(resolved.qualifiedName ?: "") || + Regex("java\\.util\\.function\\.Function.*").matches( + resolved.qualifiedName ?: "" + ) -> FunctionalTypeConstructor( + DRI.from(resolved), + type.parameters.map { getProjection(it) } + ) + else -> GenericTypeConstructor( + DRI.from(resolved), + type.parameters.map { getProjection(it) }) } } - is PsiArrayType -> TypeConstructor( + is PsiArrayType -> GenericTypeConstructor( DRI("kotlin", "Array"), listOf(getProjection(type.componentType)) ) @@ -411,6 +421,7 @@ class DefaultPsiToDocumentableTranslator( DTypeParameter( dri.copy(target = dri.target.nextTarget()), type.name.orEmpty(), + null, javadocParser.parseDocumentation(type).toSourceSetDependent(), null, mapBounds(type.bounds), |