diff options
9 files changed, 67 insertions, 37 deletions
diff --git a/core/src/main/kotlin/model/Documentable.kt b/core/src/main/kotlin/model/Documentable.kt index c9bf7760..2ea4a328 100644 --- a/core/src/main/kotlin/model/Documentable.kt +++ b/core/src/main/kotlin/model/Documentable.kt @@ -309,14 +309,27 @@ data class DParameter( } data class DTypeParameter( - override val dri: DRI, - override val name: String, + val variantTypeParameter: Variance<TypeParameter>, override val documentation: SourceSetDependent<DocumentationNode>, override val expectPresentInSet: DokkaSourceSet?, val bounds: List<Bound>, override val sourceSets: Set<DokkaSourceSet>, override val extra: PropertyContainer<DTypeParameter> = PropertyContainer.empty() ) : Documentable(), WithExtraProperties<DTypeParameter> { + + constructor( + dri: DRI, + name: String, + documentation: SourceSetDependent<DocumentationNode>, + expectPresentInSet: DokkaSourceSet?, + bounds: List<Bound>, + sourceSets: Set<DokkaSourceSet>, + extra: PropertyContainer<DTypeParameter> = PropertyContainer.empty() + ) : this(Invariance(TypeParameter(dri, name)), documentation, expectPresentInSet, bounds, sourceSets, extra) + + override val dri: DRI by variantTypeParameter.inner::dri + override val name: String by variantTypeParameter.inner::name + override val children: List<Nothing> get() = emptyList() @@ -352,8 +365,18 @@ data class TypeConstructor( ) : Bound() data class Nullable(val inner: Bound) : Bound() -data class Variance(val kind: Kind, val inner: Bound) : Projection() { - enum class Kind { In, Out } + +sealed class Variance<out T : Bound> : Projection() { + abstract val inner: T +} +data class Covariance<out T : Bound>(override val inner: T) : Variance<T>() { + override fun toString() = "out" +} +data class Contravariance<out T : Bound>(override val inner: T) : Variance<T>() { + override fun toString() = "in" +} +data class Invariance<out T : Bound>(override val inner: T) : Variance<T>() { + override fun toString() = "" } data class PrimitiveJavaType(val name: String) : Bound() @@ -366,6 +389,12 @@ enum class FunctionModifiers { NONE, FUNCTION, EXTENSION } +fun Variance<TypeParameter>.withNewDri(dri: DRI) = when(this) { + is Contravariance -> Contravariance(TypeParameter(dri, inner.name)) + is Covariance -> Covariance(TypeParameter(dri, inner.name)) + is Invariance -> Invariance(TypeParameter(dri, inner.name)) +} + private fun String.shorten(maxLength: Int) = lineSequence().first().let { if (it.length != length || it.length > maxLength) it.take(maxLength - 3) + "..." else it } diff --git a/core/src/main/kotlin/model/documentableUtils.kt b/core/src/main/kotlin/model/documentableUtils.kt index 287cf313..e32605ca 100644 --- a/core/src/main/kotlin/model/documentableUtils.kt +++ b/core/src/main/kotlin/model/documentableUtils.kt @@ -11,8 +11,7 @@ fun DTypeParameter.filter(filteredSet: Set<DokkaSourceSet>) = val intersection = filteredSet.intersect(sourceSets) if (intersection.isEmpty()) null else DTypeParameter( - dri, - name, + variantTypeParameter, documentation.filtered(intersection), expectPresentInSet?.takeIf { intersection.contains(expectPresentInSet) }, bounds, diff --git a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt index 82eeb296..d6beb474 100644 --- a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt +++ b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt @@ -295,7 +295,7 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog private fun signature(t: DTypeParameter) = t.sourceSets.map { contentBuilder.contentFor(t, styles = t.stylesIfDeprecated(it), sourceSets = setOf(it)) { - link(t.name, t.dri.withTargetToDeclaration()) + signatureForProjection(t.variantTypeParameter.withNewDri(t.dri.withTargetToDeclaration())) list(t.nontrivialBounds, prefix = " : ") { bound -> signatureForProjection(bound) } @@ -333,8 +333,8 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog } } - is Variance -> group(styles = emptySet()) { - text(p.kind.toString() + " ") + is Variance<*> -> group(styles = emptySet()) { + text("$p ".takeIf { it.isNotBlank() } ?: "") signatureForProjection(p.inner, showFullyQualifiedName) } diff --git a/plugins/base/src/main/kotlin/signatures/KotlinSignatureUtils.kt b/plugins/base/src/main/kotlin/signatures/KotlinSignatureUtils.kt index e8107177..c40c48a2 100644 --- a/plugins/base/src/main/kotlin/signatures/KotlinSignatureUtils.kt +++ b/plugins/base/src/main/kotlin/signatures/KotlinSignatureUtils.kt @@ -55,7 +55,7 @@ object KotlinSignatureUtils : JvmSignatureUtils { is JavaObject -> listOf(DriOfAny) is Dynamic -> emptyList() is UnresolvedBound -> emptyList() - is Variance -> inner.drisOfAllNestedBounds + is Variance<*> -> inner.drisOfAllNestedBounds is Star -> emptyList() } diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt index 05c99af1..fccbe716 100644 --- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt @@ -11,7 +11,6 @@ import org.jetbrains.dokka.links.Callable import org.jetbrains.dokka.model.* import org.jetbrains.dokka.model.Nullable import org.jetbrains.dokka.model.TypeConstructor -import org.jetbrains.dokka.model.Variance import org.jetbrains.dokka.model.doc.* import org.jetbrains.dokka.model.properties.PropertyContainer import org.jetbrains.dokka.plugability.DokkaContext @@ -146,7 +145,7 @@ private class DokkaDescriptorVisitor( visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), supertypes = info.supertypes.toSourceSetDependent(), documentation = info.docs, - generics = descriptor.declaredTypeParameters.map { it.toTypeParameter() }, + generics = descriptor.declaredTypeParameters.map { it.toVariantTypeParameter() }, companion = descriptor.companion(driWithPlatform), sourceSets = setOf(sourceSet), extra = PropertyContainer.withAll( @@ -254,7 +253,7 @@ private class DokkaDescriptorVisitor( ), companion = descriptor.companionObjectDescriptor?.let { objectDescriptor(it, driWithPlatform) }, visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), - generics = descriptor.declaredTypeParameters.map { it.toTypeParameter() }, + generics = descriptor.declaredTypeParameters.map { it.toVariantTypeParameter() }, constructors = descriptor.constructors.map { visitConstructorDescriptor(it, driWithPlatform) }, sources = descriptor.createSources() ) @@ -284,7 +283,7 @@ private class DokkaDescriptorVisitor( expectPresentInSet = sourceSet.takeIf { isExpect }, visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), supertypes = info.supertypes.toSourceSetDependent(), - generics = descriptor.declaredTypeParameters.map { it.toTypeParameter() }, + generics = descriptor.declaredTypeParameters.map { it.toVariantTypeParameter() }, documentation = info.docs, modifier = descriptor.modifier().toSourceSetDependent(), companion = descriptor.companion(driWithPlatform), @@ -321,7 +320,7 @@ private class DokkaDescriptorVisitor( type = descriptor.returnType!!.toBound(), expectPresentInSet = sourceSet.takeIf { isExpect }, sourceSets = setOf(sourceSet), - generics = descriptor.typeParameters.map { it.toTypeParameter() }, + generics = descriptor.typeParameters.map { it.toVariantTypeParameter() }, extra = PropertyContainer.withAll( (descriptor.additionalExtras() + descriptor.getAnnotationsWithBackingField() .toAdditionalExtras()).toSet().toSourceSetDependent().toAdditionalModifiers(), @@ -354,7 +353,7 @@ private class DokkaDescriptorVisitor( expectPresentInSet = sourceSet.takeIf { isExpect }, sources = actual, visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), - generics = descriptor.typeParameters.map { it.toTypeParameter() }, + generics = descriptor.typeParameters.map { it.toVariantTypeParameter() }, documentation = descriptor.takeIf { it.kind != CallableMemberDescriptor.Kind.SYNTHESIZED } ?.resolveDescriptorData() ?: emptyMap(), modifier = descriptor.modifier().toSourceSetDependent(), @@ -402,7 +401,7 @@ private class DokkaDescriptorVisitor( }, type = descriptor.returnType.toBound(), modifier = descriptor.modifier().toSourceSetDependent(), - generics = descriptor.typeParameters.map { it.toTypeParameter() }, + generics = descriptor.typeParameters.map { it.toVariantTypeParameter() }, sourceSets = setOf(sourceSet), extra = PropertyContainer.withAll<DFunction>( descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), @@ -472,7 +471,7 @@ private class DokkaDescriptorVisitor( visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), documentation = descriptor.resolveDescriptorData(), type = descriptor.returnType!!.toBound(), - generics = descriptor.typeParameters.map { it.toTypeParameter() }, + generics = descriptor.typeParameters.map { it.toVariantTypeParameter() }, modifier = descriptor.modifier().toSourceSetDependent(), expectPresentInSet = sourceSet.takeIf { isExpect }, receiver = descriptor.extensionReceiverParameter?.let { @@ -501,7 +500,7 @@ private class DokkaDescriptorVisitor( visibility = visibility.toDokkaVisibility().toSourceSetDependent(), documentation = resolveDescriptorData(), sourceSets = setOf(sourceSet), - generics = descriptor.declaredTypeParameters.map { it.toTypeParameter() } + generics = descriptor.declaredTypeParameters.map { it.toVariantTypeParameter() } ) } @@ -588,10 +587,11 @@ private class DokkaDescriptorVisitor( ) } - private fun TypeParameterDescriptor.toTypeParameter() = + private fun TypeParameterDescriptor.toVariantTypeParameter() = DTypeParameter( - DRI.from(this).withPackageFallbackTo(fallbackPackageName()), - name.identifier, + variantTypeParameter( + TypeParameter(DRI.from(this).withPackageFallbackTo(fallbackPackageName()), name.identifier) + ), resolveDescriptorData(), null, upperBounds.map { it.toBound() }, @@ -621,12 +621,14 @@ private class DokkaDescriptorVisitor( private fun TypeProjection.toProjection(): Projection = if (isStarProjection) Star else formPossiblyVariant() - private fun TypeProjection.formPossiblyVariant(): Projection = type.toBound().let { - when (projectionKind) { - org.jetbrains.kotlin.types.Variance.INVARIANT -> it - org.jetbrains.kotlin.types.Variance.IN_VARIANCE -> Variance(Variance.Kind.In, it) - org.jetbrains.kotlin.types.Variance.OUT_VARIANCE -> Variance(Variance.Kind.Out, it) - } + private fun TypeProjection.formPossiblyVariant(): Projection = type.toBound().wrapWithVariance(projectionKind) + + private fun TypeParameterDescriptor.variantTypeParameter(type: TypeParameter) = type.wrapWithVariance(variance) + + private fun <T : Bound> T.wrapWithVariance(variance: org.jetbrains.kotlin.types.Variance) = when (variance) { + org.jetbrains.kotlin.types.Variance.INVARIANT -> Invariance(this) + org.jetbrains.kotlin.types.Variance.IN_VARIANCE -> Contravariance(this) + org.jetbrains.kotlin.types.Variance.OUT_VARIANCE -> Covariance(this) } private fun DeclarationDescriptor.getDocumentation() = findKDoc().let { diff --git a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt index c9118920..c1ed4a08 100644 --- a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt @@ -380,8 +380,8 @@ class DefaultPsiToDocumentableTranslator( } private fun getVariance(type: PsiWildcardType): Projection = when { - type.extendsBound != PsiType.NULL -> Variance(Variance.Kind.Out, getBound(type.extendsBound)) - type.superBound != PsiType.NULL -> Variance(Variance.Kind.In, getBound(type.superBound)) + type.extendsBound != PsiType.NULL -> Covariance(getBound(type.extendsBound)) + type.superBound != PsiType.NULL -> Contravariance(getBound(type.superBound)) else -> throw IllegalStateException("${type.presentableText} has incorrect bounds") } diff --git a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/signatures/JavadocSignatureProvider.kt b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/signatures/JavadocSignatureProvider.kt index d9aed18f..6c93c287 100644 --- a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/signatures/JavadocSignatureProvider.kt +++ b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/signatures/JavadocSignatureProvider.kt @@ -150,7 +150,7 @@ class JavadocSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLo annotationsBlock(t) } signatureWithoutModifiers { - text(t.name) + text(t.name) // Investigate if java classes can be somehow variant } supertypes { list(t.bounds, prefix = "extends ") { @@ -192,8 +192,8 @@ class JavadocSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLo signatureForProjection(it) } } - is Variance -> group { - text(p.kind.toString() + " ") + is Variance<*> -> group { + text("$p ".takeIf { it.isNotBlank() } ?: "") signatureForProjection(p.inner) } is Star -> text("?") diff --git a/plugins/kotlin-as-java/src/main/kotlin/converters/KotlinToJavaConverter.kt b/plugins/kotlin-as-java/src/main/kotlin/converters/KotlinToJavaConverter.kt index 58c62622..f169f89a 100644 --- a/plugins/kotlin-as-java/src/main/kotlin/converters/KotlinToJavaConverter.kt +++ b/plugins/kotlin-as-java/src/main/kotlin/converters/KotlinToJavaConverter.kt @@ -172,7 +172,7 @@ internal fun DClass.asJava(): DClass = copy( ) private fun DTypeParameter.asJava(): DTypeParameter = copy( - dri = dri.possiblyAsJava(), + variantTypeParameter = variantTypeParameter.withNewDri(dri.possiblyAsJava()), bounds = bounds.map { it.asJava() } ) diff --git a/plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureProvider.kt b/plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureProvider.kt index 5134bd4d..d9b9dc5b 100644 --- a/plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureProvider.kt +++ b/plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureProvider.kt @@ -141,7 +141,7 @@ class JavaSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLogge private fun signature(t: DTypeParameter) = t.sourceSets.map { contentBuilder.contentFor(t, styles = t.stylesIfDeprecated(it), sourceSets = setOf(it)) { - text(t.name.substringAfterLast(".")) + text(t.name.substringAfterLast(".")) // Investigate if java classes can be somehow variant list(t.bounds, prefix = " extends ") { signatureForProjection(it) } @@ -159,8 +159,8 @@ class JavaSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLogge } } - is Variance -> group(styles = emptySet()) { - text(p.kind.toString() + " ") // TODO: "super" && "extends" + is Variance<*> -> group(styles = emptySet()) { + text("$p ".takeIf { it.isNotBlank() } ?: "") // TODO: "super" && "extends" signatureForProjection(p.inner) } |