Skip to content

Commit

Permalink
Support definitely non-nullable types
Browse files Browse the repository at this point in the history
  • Loading branch information
vmishenev committed Jun 6, 2022
1 parent 73f78dc commit 9d2a2f7
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 1 deletion.
5 changes: 5 additions & 0 deletions core/src/main/kotlin/model/Documentable.kt
Expand Up @@ -459,6 +459,11 @@ data class UnresolvedBound(
// The following Projections are not AnnotationTargets; they cannot be annotated.
data class Nullable(val inner: Bound) : Bound()

/**
* It introduces [definitely non-nullable types](https://github.com/Kotlin/KEEP/blob/c72601cf35c1e95a541bb4b230edb474a6d1d1a8/proposals/definitely-non-nullable-types.md)
*/
data class DefinitelyNonNullable(val inner: Bound) : Bound()

sealed class Variance<out T : Bound> : Projection() {
abstract val inner: T
}
Expand Down
Expand Up @@ -430,6 +430,11 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
signatureForProjection(p.inner, showFullyQualifiedName)
operator("?")
}
is DefinitelyNonNullable -> group(styles = emptySet()) {
signatureForProjection(p.inner, showFullyQualifiedName)
operator(" & ")
link("Any", DriOfAny)
}

is TypeAliased -> signatureForProjection(p.typeAlias)
is JavaObject -> {
Expand Down
Expand Up @@ -39,6 +39,7 @@ object KotlinSignatureUtils : JvmSignatureUtils {
is TypeParameter -> dri
is TypeConstructor -> dri
is Nullable -> inner.driOrNull
is DefinitelyNonNullable -> inner.driOrNull
is PrimitiveJavaType -> dri
is Void -> DriOfUnit
is JavaObject -> DriOfAny
Expand All @@ -52,6 +53,7 @@ object KotlinSignatureUtils : JvmSignatureUtils {
is TypeParameter -> listOf(dri)
is TypeConstructor -> listOf(dri) + projections.flatMap { it.drisOfAllNestedBounds }
is Nullable -> inner.drisOfAllNestedBounds
is DefinitelyNonNullable -> inner.drisOfAllNestedBounds
is PrimitiveJavaType -> listOf(dri)
is Void -> listOf(DriOfUnit)
is JavaObject -> listOf(DriOfAny)
Expand Down
Expand Up @@ -9,7 +9,6 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.toList
import org.jetbrains.dokka.base.signatures.KotlinSignatureUtils.driOrNull
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.links.DriOfAny
import org.jetbrains.dokka.model.*
Expand Down Expand Up @@ -91,6 +90,7 @@ private fun Callable.asPairsWithReceiverDRIs(): Sequence<Pair<DRI, Callable>> =
// care about it since there is nowhere to put documentation of given extension.
private fun Callable.findReceiverDRIs(bound: Bound): Sequence<DRI> = when (bound) {
is Nullable -> findReceiverDRIs(bound.inner)
is DefinitelyNonNullable -> findReceiverDRIs(bound.inner)
is TypeParameter ->
if (this is DFunction && bound.dri == this.dri)
generics.find { it.name == bound.name }?.bounds?.asSequence()?.flatMap(::findReceiverDRIs).orEmpty()
Expand Down
Expand Up @@ -910,6 +910,9 @@ private class DokkaDescriptorVisitor(
expandedType.toBound(),
annotations()
)
is DefinitelyNotNullType -> DefinitelyNonNullable(
original.toBound()
)
else -> when (val ctor = constructor.declarationDescriptor) {
is TypeParameterDescriptor -> TypeParameter(
dri = DRI.from(ctor),
Expand Down
25 changes: 25 additions & 0 deletions plugins/base/src/test/kotlin/signatures/SignatureTest.kt
Expand Up @@ -185,6 +185,31 @@ class SignatureTest : BaseAbstractTest() {
}
}

@Test
fun `fun with definitely non-nullable types`() {
val source = source("fun <T> elvisLike(x: T, y: T & Any): T & Any = x ?: y")
val writerPlugin = TestOutputWriterPlugin()

testInline(
source,
configuration,
pluginOverrides = listOf(writerPlugin)
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/elvis-like.html").firstSignature().match(
"fun <", A("T"), "> ", A("elvisLike"),
"(",
Span(
Span("x: ", A("T"), ", "),
Span("y: ", A("T"), " & ", A("Any"))
),
"): ", A("T"), " & ", A("Any"), Span(),
ignoreSpanWithTokenStyle = true
)
}
}
}

@Test
fun `fun with keywords, params and generic bound`() {
val source = source("inline suspend fun <T : String> simpleFun(a: Int, b: String): T = \"Celebrimbor\" as T")
Expand Down
1 change: 1 addition & 0 deletions plugins/base/src/test/kotlin/utils/TestUtils.kt
Expand Up @@ -66,6 +66,7 @@ val DClass.supers
val Bound.name: String?
get() = when (this) {
is Nullable -> inner.name
is DefinitelyNonNullable -> inner.name
is TypeParameter -> name
is PrimitiveJavaType -> name
is TypeConstructor -> dri.classNames
Expand Down
Expand Up @@ -305,6 +305,7 @@ private fun Bound.asJava(): Bound = when (this) {
inner = inner.asJava()
)
is Nullable -> copy(inner.asJava())
is DefinitelyNonNullable -> copy(inner.asJava())
is PrimitiveJavaType -> this
is Void -> this
is JavaObject -> this
Expand Down
Expand Up @@ -196,6 +196,7 @@ class JavaSignatureProvider internal constructor(ctcc: CommentsToContentConverte
is Star -> operator("?")

is Nullable -> signatureForProjection(p.inner)
is DefinitelyNonNullable -> signatureForProjection(p.inner)

is JavaObject, is Dynamic -> link("Object", DRI("java.lang", "Object"))
is Void -> text("void")
Expand Down

0 comments on commit 9d2a2f7

Please sign in to comment.