From d47d386ad8c0ff4a2c3b9d5b4450a773bdcba2dc Mon Sep 17 00:00:00 2001 From: Andrzej Ratajczak Date: Mon, 4 May 2020 13:53:10 +0200 Subject: Enhance signature presentation. Support presetnation Java as Kotlin and Kotlin as Java. Refactor annotations creation from PSI/Descriptors. Add proper rendering of annotation signatures in both kotlin syntax and java syntax. Tests for annotations --- .../kotlin/signatures/JavaSignatureProvider.kt | 109 ++++++++++++--------- .../main/kotlin/signatures/JavaSignatureUtils.kt | 34 +++++++ 2 files changed, 98 insertions(+), 45 deletions(-) create mode 100644 plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureUtils.kt (limited to 'plugins/kotlin-as-java/src/main') 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 9135d36e..ec3221e2 100644 --- a/plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureProvider.kt +++ b/plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureProvider.kt @@ -1,24 +1,30 @@ package org.jetbrains.dokka.kotlinAsJava.signatures +import org.jetbrains.dokka.base.signatures.JvmSingatureUtils +import javaslang.Tuple2 +import org.jetbrains.dokka.base.signatures.All import org.jetbrains.dokka.base.signatures.SignatureProvider 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.sureClassNames import org.jetbrains.dokka.model.* +import org.jetbrains.dokka.model.properties.WithExtraProperties import org.jetbrains.dokka.pages.ContentKind import org.jetbrains.dokka.pages.ContentNode import org.jetbrains.dokka.pages.TextStyle import org.jetbrains.dokka.utilities.DokkaLogger +import kotlin.text.Typography.nbsp -class JavaSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLogger) : SignatureProvider { +class JavaSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLogger) : SignatureProvider, + JvmSingatureUtils by JavaSignatureUtils { private val contentBuilder = PageContentBuilder(ctcc, this, logger) - private val ignoredVisibilities = setOf(JavaVisibility.Default, KotlinVisibility.Public) + private val ignoredVisibilities = setOf(JavaVisibility.Default) + private val ignoredModifiers = setOf(KotlinModifier.Open, JavaModifier.Empty, KotlinModifier.Empty, KotlinModifier.Sealed) - override fun signature(documentable: Documentable): ContentNode = when (documentable) { is DFunction -> signature(documentable) is DProperty -> signature(documentable) @@ -30,57 +36,71 @@ class JavaSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLogge ) } - private fun signature(e: DEnumEntry)= contentBuilder.contentFor(e, ContentKind.Symbol, setOf(TextStyle.Monospace)) + private fun signature(e: DEnumEntry) = contentBuilder.contentFor(e, ContentKind.Symbol, setOf(TextStyle.Monospace)) - private fun signature(c: DClasslike) = contentBuilder.contentFor(c, ContentKind.Symbol, setOf(TextStyle.Monospace)) { - platformText(c.visibility) { (it.takeIf { it !in ignoredVisibilities }?.name ?: "") + " " } + private fun signature(c: DClasslike) = + contentBuilder.contentFor(c, ContentKind.Symbol, setOf(TextStyle.Monospace)) { + platformText(c.visibility) { (it.takeIf { it !in ignoredVisibilities }?.name ?: "") + " " } - if (c is DClass) { - platformText(c.modifier){ it.takeIf{it !in ignoredModifiers}?.name.orEmpty() + " "} - } + if (c is DClass) { + platformText(c.modifier) { it.takeIf { it !in ignoredModifiers }?.name.orEmpty() + " " } + text(c.modifiers().toSignatureString()) + } - when (c) { - is DClass -> text("class ") - is DInterface -> text("interface ") - is DEnum -> text("enum ") - is DObject -> text("class ") - is DAnnotation -> text("@interface ") - } - link(c.name!!, c.dri) - if (c is WithGenerics) { - list(c.generics, prefix = "<", suffix = ">") { - +buildSignature(it) + when (c) { + is DClass -> text("class ") + is DInterface -> text("interface ") + is DEnum -> text("enum ") + is DObject -> text("class ") + is DAnnotation -> text("@interface ") } - } - if (c is WithSupertypes) { - c.supertypes.map { (p, dris) -> - list(dris, prefix = " extends ", sourceSets = setOf(p)) { - link(it.sureClassNames, it, sourceSets = setOf(p)) + link(c.name!!, c.dri) + if (c is WithGenerics) { + list(c.generics, prefix = "<", suffix = ">") { + +buildSignature(it) + } + } + if (c is WithSupertypes) { + c.supertypes.map { (p, dris) -> + list(dris, prefix = " extends ", sourceSets = setOf(p)) { + link(it.sureClassNames, it, sourceSets = setOf(p)) + } } } } - } private fun signature(p: DProperty) = contentBuilder.contentFor(p, ContentKind.Symbol, setOf(TextStyle.Monospace)) { - signatureForProjection(p.type) + group(styles = setOf(TextStyle.Block)) { + annotationsBlock(p) + platformText(p.visibility) { (it.takeIf { it !in ignoredVisibilities }?.name ?: "") + " " } + platformText(p.modifier) { it.name + " " } + text(p.modifiers().toSignatureString()) + signatureForProjection(p.type) + text(nbsp.toString()) + link(p.name, p.dri) + } } private fun signature(f: DFunction) = contentBuilder.contentFor(f, ContentKind.Symbol, setOf(TextStyle.Monospace)) { - platformText(f.modifier){ it.takeIf{it !in ignoredModifiers}?.name.orEmpty() + " "} - val returnType = f.type - signatureForProjection(returnType) - text(" ") - link(f.name, f.dri) - list(f.generics, prefix = "<", suffix = ">") { - +buildSignature(it) - } - text("(") - list(f.parameters) { - signatureForProjection(it.type) - text(" ") - link(it.name!!, it.dri) + group(styles = setOf(TextStyle.Block)) { + annotationsBlock(f) + platformText(f.modifier) { it.takeIf { it !in ignoredModifiers }?.name.orEmpty() + " " } + text(f.modifiers().toSignatureString()) + val returnType = f.type + signatureForProjection(returnType) + text(nbsp.toString()) + link(f.name, f.dri) + list(f.generics, prefix = "<", suffix = ">") { + +buildSignature(it) + } + list(f.parameters, "(", ")") { + annotationsInline(it) + text(it.modifiers().toSignatureString()) + signatureForProjection(it.type) + text(nbsp.toString()) + link(it.name!!, it.dri) + } } - text(")") } private fun signature(t: DTypeParameter) = contentBuilder.contentFor(t) { @@ -90,18 +110,17 @@ class JavaSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLogge } } - private fun PageContentBuilder.DocumentableContentBuilder.signatureForProjection(p: Projection): Unit = when (p) { is OtherParameter -> link(p.name, p.declarationDRI) - is TypeConstructor -> group { + is TypeConstructor -> group(styles = emptySet()) { link(p.dri.classNames.orEmpty(), p.dri) list(p.projections, prefix = "<", suffix = ">") { signatureForProjection(it) } } - is Variance -> group { + is Variance -> group(styles = emptySet()) { text(p.kind.toString() + " ") // TODO: "super" && "extends" signatureForProjection(p.inner) } @@ -110,7 +129,7 @@ class JavaSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLogge is Nullable -> signatureForProjection(p.inner) - is JavaObject -> link("Object", DRI("java.lang", "Object")) + is JavaObject, is Dynamic -> link("Object", DRI("java.lang", "Object")) is Void -> text("void") is PrimitiveJavaType -> text(p.name) } diff --git a/plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureUtils.kt b/plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureUtils.kt new file mode 100644 index 00000000..16c3f25a --- /dev/null +++ b/plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureUtils.kt @@ -0,0 +1,34 @@ +package org.jetbrains.dokka.kotlinAsJava.signatures +import javaslang.Tuple2 +import org.jetbrains.dokka.base.signatures.All +import org.jetbrains.dokka.base.signatures.JvmSingatureUtils +import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder +import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.model.* +import org.jetbrains.dokka.model.ExtraModifiers.Companion.javaOnlyModifiers +import org.jetbrains.dokka.model.properties.WithExtraProperties + +object JavaSignatureUtils : JvmSingatureUtils { + + val ignoredAnnotations = setOf( + Annotations.Annotation(DRI("kotlin.jvm", "Transient"), emptyMap()), + Annotations.Annotation(DRI("kotlin.jvm", "Volatile"), emptyMap()), + Annotations.Annotation(DRI("kotlin.jvm", "Transitive"), emptyMap()), + Annotations.Annotation(DRI("kotlin.jvm", "Strictfp"), emptyMap()), + Annotations.Annotation(DRI("kotlin.jvm", "JvmStatic"), emptyMap()) + ) + + private val strategy = All + private val listBrackets = Tuple2('{', '}') + private val classExtension = ".class" + + override fun PageContentBuilder.DocumentableContentBuilder.annotationsBlock(d: Documentable) = + annotationsBlockWithIgnored(d, ignoredAnnotations, strategy, listBrackets, classExtension) + + override fun PageContentBuilder.DocumentableContentBuilder.annotationsInline(d: Documentable) = + annotationsInlineWithIgnored(d, ignoredAnnotations, strategy, listBrackets, classExtension) + + override fun WithExtraProperties.modifiers() = + modifiersWithFilter(javaOnlyModifiers) + +} \ No newline at end of file -- cgit