From 8e4ffa367b43cdc57c3921fab2182a4209913a51 Mon Sep 17 00:00:00 2001 From: Paweł Marks Date: Wed, 11 Mar 2020 16:55:40 +0100 Subject: Use Bounds instead of Wrappers to describe types --- .../kotlin/signatures/KotlinSignatureProvider.kt | 23 ++++++++++++----- .../DefaultDescriptorToDocumentableTranslator.kt | 20 +++++++-------- .../documentables/PageContentBuilder.kt | 19 +------------- .../psi/DefaultPsiToDocumentableTranslator.kt | 30 +++++++++++++++++----- 4 files changed, 50 insertions(+), 42 deletions(-) (limited to 'plugins/base/src/main/kotlin') diff --git a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt index b468c56b..3c4698fe 100644 --- a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt +++ b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt @@ -2,6 +2,8 @@ package org.jetbrains.dokka.base.signatures import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentConverter import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder +import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.links.DriOfUnit import org.jetbrains.dokka.links.sureClassNames import org.jetbrains.dokka.model.* import org.jetbrains.dokka.model.Annotation @@ -53,25 +55,25 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog platformText(f.visibility) { (it.takeIf { it !in ignoredVisibilities }?.name ?: "") + " " } text(f.modifier.name + " ") text("fun ") + list(f.generics, prefix = "<", suffix = "> ") { + +buildSignature(it) + } f.receiver?.also { - type(it.type) + signatureForProjection(it.type) text(".") } link(f.name, f.dri) - list(f.generics, prefix = "<", suffix = ">") { - +buildSignature(it) - } text("(") list(f.parameters) { text(it.name!!) text(": ") - type(it.type) + signatureForProjection(it.type) } text(")") val returnType = f.type - if (!f.isConstructor && returnType.constructorFqName != Unit::class.qualifiedName) { + if (!f.isConstructor && returnType is TypeConstructor && returnType.dri != DriOfUnit) { text(": ") - type(returnType) + signatureForProjection(returnType) } } @@ -103,5 +105,12 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog signatureForProjection(p.inner) text("?") } + + is PrimitiveJavaType -> signatureForProjection(p.translateToKotlin()) } } + +private fun PrimitiveJavaType.translateToKotlin() = TypeConstructor( + dri = DRI("kotlin", name.capitalize()), + projections = emptyList() +) diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt index 2b73dc7f..9a71145f 100644 --- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt @@ -223,7 +223,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv visibility = PlatformDependent(mapOf(platformData to descriptor.visibility.toDokkaVisibility())), documentation = descriptor.resolveDescriptorData(platformData), modifier = descriptor.modifier(), - type = KotlinTypeWrapper(descriptor.returnType!!), + type = descriptor.returnType!!.toBound(), platformData = listOf(platformData), extra = descriptor.additionalExtras() ) @@ -248,7 +248,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv generics = descriptor.typeParameters.map { it.toTypeParameter() }, documentation = descriptor.resolveDescriptorData(platformData), modifier = descriptor.modifier(), - type = KotlinTypeWrapper(descriptor.returnType!!), + type = descriptor.returnType!!.toBound(), platformData = listOf(platformData), extra = descriptor.additionalExtras() ) @@ -270,7 +270,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv sources = actual, visibility = PlatformDependent(mapOf(platformData to descriptor.visibility.toDokkaVisibility())), documentation = descriptor.resolveDescriptorData(platformData), - type = KotlinTypeWrapper(descriptor.returnType), + type = descriptor.returnType.toBound(), modifier = descriptor.modifier(), generics = descriptor.typeParameters.map { it.toTypeParameter() }, platformData = listOf(platformData), @@ -284,7 +284,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv ) = Parameter( dri = parent.dri.copy(target = 0), name = null, - type = KotlinTypeWrapper(descriptor.type), + type = descriptor.type.toBound(), documentation = descriptor.resolveDescriptorData(platformData), platformData = listOf(platformData) ) @@ -301,7 +301,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv Parameter( parent.copy(target = 1), this.name.asString(), - type = KotlinTypeWrapper(this.type), + type = this.type.toBound(), documentation = descriptor.resolveDescriptorData(platformData), platformData = listOf(platformData), extra = descriptor.additionalExtras() @@ -327,7 +327,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv parameters = parameters, visibility = PlatformDependent(mapOf(platformData to descriptor.visibility.toDokkaVisibility())), documentation = descriptor.resolveDescriptorData(platformData), - type = KotlinTypeWrapper(descriptor.returnType!!), + type = descriptor.returnType!!.toBound(), generics = descriptor.typeParameters.map { it.toTypeParameter() }, modifier = descriptor.modifier(), receiver = descriptor.extensionReceiverParameter?.let { @@ -346,7 +346,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv Parameter( dri = parent.dri.copy(target = index + 1), name = descriptor.name.asString(), - type = KotlinTypeWrapper(descriptor.type), + type = descriptor.type.toBound(), documentation = descriptor.resolveDescriptorData(platformData), platformData = listOf(platformData), extra = descriptor.additionalExtras() @@ -393,15 +393,15 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv private fun TypeParameterDescriptor.toTypeParameter() = TypeParameter( DRI.from(this), - fqNameSafe.asString(), + name.identifier, PlatformDependent.from(platformData, getDocumentation()), upperBounds.map { it.toBound() }, listOf(platformData), extra = additionalExtras() ) - private fun KotlinType.toBound(): Bound = when (constructor.declarationDescriptor) { - is TypeParameterDescriptor -> OtherParameter(fqName.toString()).let { + private fun KotlinType.toBound(): Bound = when (val ctor = constructor.declarationDescriptor) { + is TypeParameterDescriptor -> OtherParameter(ctor.name.asString()).let { if (isMarkedNullable) Nullable(it) else it } else -> TypeConstructor( diff --git a/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt b/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt index f5880656..681b8c71 100644 --- a/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt +++ b/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt @@ -3,9 +3,7 @@ package org.jetbrains.dokka.base.translators.documentables import org.jetbrains.dokka.base.signatures.SignatureProvider import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentConverter import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.Documentable -import org.jetbrains.dokka.model.PlatformDependent -import org.jetbrains.dokka.model.TypeWrapper +import org.jetbrains.dokka.model.* import org.jetbrains.dokka.model.doc.DocTag import org.jetbrains.dokka.model.properties.PropertyContainer import org.jetbrains.dokka.pages.* @@ -256,21 +254,6 @@ open class PageContentBuilder( ) = ContentText(text, DCI(setOf(mainDRI), kind), platformData, styles, extra) - fun type(t: TypeWrapper) { - if (t.constructorNamePathSegments.isNotEmpty() && t.dri != null) - link(t.constructorNamePathSegments.last(), t.dri!!) - else if (t.constructorNamePathSegments.isNotEmpty() && t.dri == null) - text(t.toString()) - else { - logger.error("type $t cannot be resolved") - text("???") - } - list(t.arguments, prefix = "<", suffix = ">") { - type(it) - } - } - - fun platformText( value: PlatformDependent, transform: (T) -> String diff --git a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt index b07d248d..8bf556af 100644 --- a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt @@ -3,6 +3,7 @@ package org.jetbrains.dokka.base.translators.psi import com.intellij.lang.jvm.JvmModifier import com.intellij.lang.jvm.types.JvmReferenceType import com.intellij.psi.* +import com.intellij.psi.impl.source.PsiClassReferenceType import org.jetbrains.dokka.links.Callable import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.links.JavaClassReference @@ -63,7 +64,7 @@ object DefaultPsiToDocumentableTranslator : PsiToDocumentableTranslator { private val javadocParser: JavaDocumentationParser = JavadocParser(logger) - private val typeWrappers = hashMapOf() + private val cachedBounds = hashMapOf() private fun PsiModifierListOwner.getVisibility() = modifierList?.children?.toList()?.let { ml -> when { @@ -226,14 +227,14 @@ object DefaultPsiToDocumentableTranslator : PsiToDocumentableTranslator { dri.copy(target = index + 1), psiParameter.name, javadocParser.parseDocumentation(psiParameter).toPlatformDependant(), - getTypeWrapper(psiParameter.type), + getBound(psiParameter.type), listOf(platformData) ) }, javadocParser.parseDocumentation(psi).toPlatformDependant(), PsiDocumentableSource(psi).toPlatformDependant(), psi.getVisibility().toPlatformDependant(), - psi.returnType?.let { getTypeWrapper(type = it) } ?: JavaTypeWrapper.VOID, + psi.returnType?.let { getBound(type = it) } ?: VoidBound, psi.mapTypeParameters(dri), null, psi.getModifier(), @@ -244,8 +245,22 @@ object DefaultPsiToDocumentableTranslator : PsiToDocumentableTranslator { ) } - private fun getTypeWrapper(type: PsiType) : TypeWrapper = - typeWrappers.getOrPut(type.canonicalText, { JavaTypeWrapper(type) }) + private fun getBound(type: PsiType): Bound = + cachedBounds.getOrPut(type.canonicalText) { + when (type) { + is PsiClassReferenceType -> { + val resolved: PsiClass = type.resolve() + ?: throw IllegalStateException("${type.presentableText} cannot be resolved") + val arguments = type.parameters.map { getProjection(it) } + TypeConstructor(DRI.from(resolved), arguments) + } + is PsiArrayType -> TypeConstructor(DRI("kotlin", "Array"), listOf(getProjection(type.componentType))) + is PsiPrimitiveType -> PrimitiveJavaType(type.name) + else -> throw IllegalStateException("${type.presentableText} is not supported by PSI parser") + } + } + + private fun getProjection(type: PsiType): Projection = if (type is PsiEllipsisType) Star else getBound(type) private fun PsiModifierListOwner.getModifier() = when { hasModifier(JvmModifier.ABSTRACT) -> JavaModifier.Abstract @@ -278,7 +293,8 @@ object DefaultPsiToDocumentableTranslator : PsiToDocumentableTranslator { getAnnotation(DescriptorUtils.JVM_NAME.asString())?.findAttributeValue("name")?.text ?: when { JvmAbi.isGetterName(name) -> propertyNameByGetMethodName(Name.identifier(name))?.asString() - JvmAbi.isSetterName(name) -> propertyNamesBySetMethodName(Name.identifier(name)).firstOrNull()?.asString() + JvmAbi.isSetterName(name) -> propertyNamesBySetMethodName(Name.identifier(name)).firstOrNull() + ?.asString() else -> null } @@ -311,7 +327,7 @@ object DefaultPsiToDocumentableTranslator : PsiToDocumentableTranslator { javadocParser.parseDocumentation(psi).toPlatformDependant(), PsiDocumentableSource(psi).toPlatformDependant(), psi.getVisibility().toPlatformDependant(), - getTypeWrapper(psi.type), + getBound(psi.type), null, accessors.firstOrNull { it.hasParameters() }?.let { parseFunction(it, parent) }, accessors.firstOrNull { it.returnType == psi.type }?.let { parseFunction(it, parent) }, -- cgit