diff options
| author | Andrzej Ratajczak <andrzej.ratajczak98@gmail.com> | 2020-05-04 13:53:10 +0200 |
|---|---|---|
| committer | Paweł Marks <Kordyjan@users.noreply.github.com> | 2020-05-26 11:32:03 +0200 |
| commit | d47d386ad8c0ff4a2c3b9d5b4450a773bdcba2dc (patch) | |
| tree | 364724f661349211f053ea80db1a7feb283f48ba | |
| parent | b1e3033fca65ac1e8e312e51d2eed4f278ddb076 (diff) | |
| download | dokka-d47d386ad8c0ff4a2c3b9d5b4450a773bdcba2dc.tar.gz dokka-d47d386ad8c0ff4a2c3b9d5b4450a773bdcba2dc.tar.bz2 dokka-d47d386ad8c0ff4a2c3b9d5b4450a773bdcba2dc.zip | |
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
22 files changed, 1330 insertions, 266 deletions
diff --git a/core/src/main/kotlin/model/Documentable.kt b/core/src/main/kotlin/model/Documentable.kt index 9f17638c..b808e09c 100644 --- a/core/src/main/kotlin/model/Documentable.kt +++ b/core/src/main/kotlin/model/Documentable.kt @@ -361,6 +361,7 @@ data class Variance(val kind: Kind, val inner: Bound) : Projection() { data class PrimitiveJavaType(val name: String) : Bound() object Void : Bound() object JavaObject : Bound() +object Dynamic : Bound() enum class FunctionModifiers { NONE, FUNCTION, EXTENSION @@ -368,8 +369,19 @@ enum class FunctionModifiers { enum class ExtraModifiers { STATIC, INLINE, INFIX, SUSPEND, REIFIED, CROSSINLINE, NOINLINE, - OVERRIDE, DATA, CONST, DYNAMIC, EXTERNAL, INNER, LATEINIT, OPERATOR, TAILREC, VARARG, - NATIVE, SYNCHRONIZED, STRICTFP, TRANSIENT, VOLATILE, TRANSITIVE + OVERRIDE, DATA, CONST, EXTERNAL, INNER, LATEINIT, OPERATOR, TAILREC, VARARG, + NATIVE, SYNCHRONIZED, STRICTFP, TRANSIENT, VOLATILE, TRANSITIVE; + + companion object { + val kotlinOnlyModifiers = setOf( + INLINE, INFIX, EXTERNAL, SUSPEND, REIFIED, CROSSINLINE, NOINLINE, OVERRIDE, DATA, CONST, INNER, LATEINIT, OPERATOR, + TAILREC, VARARG + ) + + val javaOnlyModifiers = setOf( + STATIC, NATIVE, SYNCHRONIZED, STRICTFP, TRANSIENT, VOLATILE, TRANSITIVE + ) + } } private fun String.shorten(maxLength: Int) = lineSequence().first().let { diff --git a/core/src/main/kotlin/model/aditionalExtras.kt b/core/src/main/kotlin/model/aditionalExtras.kt index 27ad8a55..05b88f48 100644 --- a/core/src/main/kotlin/model/aditionalExtras.kt +++ b/core/src/main/kotlin/model/aditionalExtras.kt @@ -3,6 +3,7 @@ package org.jetbrains.dokka.model import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.properties.ExtraProperty import org.jetbrains.dokka.model.properties.MergeStrategy +import org.jetbrains.kotlin.psi.KtClass class AdditionalModifiers(val content: Set<ExtraModifiers>) : ExtraProperty<Documentable> { companion object : ExtraProperty.Key<Documentable, AdditionalModifiers> { @@ -27,7 +28,7 @@ class Annotations(val content: List<Annotation>) : ExtraProperty<Documentable> { override val key: ExtraProperty.Key<Documentable, *> = Annotations - data class Annotation(val dri: DRI, val params: Map<String, String>) { + data class Annotation(val dri: DRI, val params: Map<String, AnnotationParameterValue>) { override fun equals(other: Any?): Boolean = when (other) { is Annotation -> dri == other.dri else -> false @@ -37,6 +38,14 @@ class Annotations(val content: List<Annotation>) : ExtraProperty<Documentable> { } } +sealed class AnnotationParameterValue +class AnnotationValue(val annotation: Annotations.Annotation) : AnnotationParameterValue() +class ArrayValue(val value: List<AnnotationParameterValue>) : AnnotationParameterValue() +class EnumValue(val enumName: String, val enumDri: DRI) : AnnotationParameterValue() +class ClassValue(val className: String, val classDRI: DRI) : AnnotationParameterValue() // TODO Investigate if KtClassValue can be parameter of annotation +class StringValue(val value: String) : AnnotationParameterValue() + + object PrimaryConstructorExtra : ExtraProperty<DFunction>, ExtraProperty.Key<DFunction, PrimaryConstructorExtra> { override val key: ExtraProperty.Key<DFunction, *> = this } diff --git a/core/src/main/kotlin/pages/ContentNodes.kt b/core/src/main/kotlin/pages/ContentNodes.kt index 2a668e09..7b702841 100644 --- a/core/src/main/kotlin/pages/ContentNodes.kt +++ b/core/src/main/kotlin/pages/ContentNodes.kt @@ -217,7 +217,7 @@ enum class ContentKind : Kind { } enum class TextStyle : Style { - Bold, Italic, Strong, Strikethrough, Paragraph, Block, Monospace, Indented + Bold, Italic, Strong, Strikethrough, Paragraph, Block, Span, Monospace, Indented } enum class ContentStyle : Style { diff --git a/plugins/base/src/main/kotlin/signatures/JvmSingatureUtils.kt b/plugins/base/src/main/kotlin/signatures/JvmSingatureUtils.kt new file mode 100644 index 00000000..dde553b9 --- /dev/null +++ b/plugins/base/src/main/kotlin/signatures/JvmSingatureUtils.kt @@ -0,0 +1,129 @@ +package org.jetbrains.dokka.base.signatures + +import javaslang.Tuple2 +import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder +import org.jetbrains.dokka.model.* +import org.jetbrains.dokka.model.properties.WithExtraProperties + +interface JvmSingatureUtils { + + fun PageContentBuilder.DocumentableContentBuilder.annotationsBlock(d: Documentable) + + fun PageContentBuilder.DocumentableContentBuilder.annotationsInline(d: Documentable) + + fun <T : Documentable> WithExtraProperties<T>.modifiers(): Set<ExtraModifiers> + + fun Set<ExtraModifiers>.toSignatureString(): String = + joinToString("") { it.name.toLowerCase() + " " } + + fun <T : Documentable> WithExtraProperties<T>.annotations(): List<Annotations.Annotation> = + extra[Annotations]?.content ?: emptyList() + + private fun Annotations.Annotation.toSignatureString(): String = + "@${this.dri.classNames}(${this.params.entries.joinToString { it.key + "=" + it.value }})" + + private fun PageContentBuilder.DocumentableContentBuilder.annotations( + d: Documentable, + ignored: Set<Annotations.Annotation>, + operation: (Annotations.Annotation) -> Unit + ): Unit = when (d) { + is DFunction -> d.annotations() + is DProperty -> d.annotations() + is DClass -> d.annotations() + is DInterface -> d.annotations() + is DObject -> d.annotations() + is DEnum -> d.annotations() + is DAnnotation -> d.annotations() + is DTypeParameter -> d.annotations() + is DEnumEntry -> d.annotations() + is DTypeAlias -> d.annotations() + is DParameter -> d.annotations() + else -> null + }?.let { + it.filter { it !in ignored }.forEach { + operation(it) + } + } ?: Unit + + fun <T : Documentable> WithExtraProperties<T>.modifiersWithFilter( + filter: Set<ExtraModifiers> = ExtraModifiers.values().toSet() + ): Set<ExtraModifiers> = + extra[AdditionalModifiers]?.content?.filter { it in filter }?.toSet() ?: emptySet() + + fun PageContentBuilder.DocumentableContentBuilder.toSignatureString( + a: Annotations.Annotation, + renderAtStrategy: AtStrategy, + listBrackets: Tuple2<Char, Char>, + classExtension: String + ) { + when (renderAtStrategy) { + is All, is OnlyOnce -> text("@") + is Never -> Unit + } + link(a.dri.classNames!!, a.dri) + text("(") + a.params.entries.forEachIndexed { i, it -> + text(it.key + " = ") + when (renderAtStrategy) { + is All -> All + is Never, is OnlyOnce -> Never + }.let { strategy -> + valueToSignature(it.value, strategy, listBrackets, classExtension) + } + if (i != a.params.entries.size - 1) text(", ") + } + text(")") + } + + private fun PageContentBuilder.DocumentableContentBuilder.valueToSignature( + a: AnnotationParameterValue, + renderAtStrategy: AtStrategy, + listBrackets: Tuple2<Char, Char>, + classExtension: String + ): Unit = when (a) { + is AnnotationValue -> toSignatureString(a.annotation, renderAtStrategy, listBrackets, classExtension) + is ArrayValue -> { + text(listBrackets._1.toString()) + a.value.forEachIndexed { i, it -> + valueToSignature(it, renderAtStrategy, listBrackets, classExtension) + if (i != a.value.size - 1) text(", ") + } + text(listBrackets._2.toString()) + } + is EnumValue -> link(a.enumName, a.enumDri) + is ClassValue -> link(a.className + classExtension, a.classDRI) + is StringValue -> text(a.value) + } + + fun PageContentBuilder.DocumentableContentBuilder.annotationsBlockWithIgnored( + d: Documentable, + ignored: Set<Annotations.Annotation>, + renderAtStrategy: AtStrategy, + listBrackets: Tuple2<Char, Char>, + classExtension: String + ) { + annotations(d, ignored) { + group { + toSignatureString(it, renderAtStrategy, listBrackets, classExtension) + } + } + } + + fun PageContentBuilder.DocumentableContentBuilder.annotationsInlineWithIgnored( + d: Documentable, + ignored: Set<Annotations.Annotation>, + renderAtStrategy: AtStrategy, + listBrackets: Tuple2<Char, Char>, + classExtension: String + ) { + annotations(d, ignored) { + toSignatureString(it, renderAtStrategy, listBrackets, classExtension) + text(Typography.nbsp.toString()) + } + } +} + +sealed class AtStrategy +object All : AtStrategy() +object OnlyOnce : AtStrategy() +object Never : AtStrategy()
\ No newline at end of file diff --git a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt index 617af959..4c689abc 100644 --- a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt +++ b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt @@ -6,16 +6,20 @@ import org.jetbrains.dokka.links.* import org.jetbrains.dokka.model.* import org.jetbrains.dokka.model.Nullable import org.jetbrains.dokka.model.TypeConstructor +import org.jetbrains.dokka.model.properties.ExtraProperty 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 KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLogger) : SignatureProvider { +class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLogger) : SignatureProvider, + JvmSingatureUtils by KotlinSignatureUtils { private val contentBuilder = PageContentBuilder(ctcc, this, logger) - private val ignoredVisibilities = setOf(JavaVisibility.Default, KotlinVisibility.Public) + private val ignoredVisibilities = setOf(JavaVisibility.Public, KotlinVisibility.Public) + private val ignoredModifiers = setOf(JavaModifier.Final, KotlinModifier.Final) override fun signature(documentable: Documentable): ContentNode = when (documentable) { is DFunction -> functionSignature(documentable) @@ -29,9 +33,10 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog ) } - private fun signature(e: DEnumEntry) = contentBuilder.contentFor(e, ContentKind.Symbol, setOf(TextStyle.Monospace)){ - link(e.name, e.dri) - } + private fun signature(e: DEnumEntry) = + contentBuilder.contentFor(e, ContentKind.Symbol, setOf(TextStyle.Monospace)) { + link(e.name, e.dri) + } private fun actualTypealiasedSignature(dri: DRI, name: String, aliasedTypes: SourceSetDependent<Bound>) = aliasedTypes.entries.groupBy({ it.value }, { it.key }).map { (bound, platforms) -> @@ -55,84 +60,121 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog private fun regularSignature(c: DClasslike, sourceSets: Set<SourceSetData> = c.sourceSets.toSet()) = contentBuilder.contentFor(c, ContentKind.Symbol, setOf(TextStyle.Monospace), sourceSets = sourceSets) { - platformText(c.visibility, sourceSets) { (it.takeIf { it !in ignoredVisibilities }?.name ?: "") + " " } - if (c is DClass) { - platformText(c.modifier, sourceSets) { - if (c.extra[AdditionalModifiers]?.content?.contains(ExtraModifiers.DATA) == true && it.name == "final") "data " - else it.name + " " + group(styles = setOf(TextStyle.Block)) { + annotationsBlock(c) + platformText( + c.visibility, + sourceSets + ) { it.takeIf { it !in ignoredVisibilities }?.name?.let { "$it " } ?: "" } + if (c is DClass) { + platformText(c.modifier, sourceSets) { + if (it !in ignoredModifiers) + if (c.extra[AdditionalModifiers]?.content?.contains(ExtraModifiers.DATA) == true) "" + else (if (it is JavaModifier.Empty) KotlinModifier.Open else it).let { it.name + " " } + else + "" + } } - } - when (c) { - is DClass -> text("class ") - is DInterface -> text("interface ") - is DEnum -> text("enum ") - is DObject -> text("object ") - is DAnnotation -> text("annotation class ") - } - 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("object ") + is DAnnotation -> text("annotation class ") } - } - if (c is DClass) { - val pConstructor = c.constructors.singleOrNull { it.extra[PrimaryConstructorExtra] != null } - list(pConstructor?.parameters.orEmpty(), "(", ")", ",", pConstructor?.sourceSets.orEmpty().toSet()) { - text(it.name ?: "", styles = mainStyles.plus(TextStyle.Bold).plus(TextStyle.Indented)) - text(": ") - signatureForProjection(it.type) + link(c.name!!, c.dri) + if (c is WithGenerics) { + list(c.generics, prefix = "<", suffix = "> ") { + +buildSignature(it) + } } - } - if (c is WithSupertypes) { - c.supertypes.filter { it.key in sourceSets }.map { (p, dris) -> - list(dris, prefix = " : ", sourceSets = setOf(p)) { - link(it.sureClassNames, it, sourceSets = setOf(p)) + if (c is DClass) { + val pConstructor = c.constructors.singleOrNull { it.extra[PrimaryConstructorExtra] != null } + if (pConstructor?.annotations()?.isNotEmpty() == true) { + text(nbsp.toString()) + annotationsInline(pConstructor) + text("constructor") + } + list( + pConstructor?.parameters.orEmpty(), + "(", + ")", + ",", + pConstructor?.sourceSets.orEmpty().toSet() + ) { + annotationsInline(it) + text(it.name ?: "", styles = mainStyles.plus(TextStyle.Bold)) + text(": ") + signatureForProjection(it.type) + } + } + if (c is WithSupertypes) { + c.supertypes.filter { it.key in sourceSets }.map { (s, dris) -> + list(dris, prefix = " : ", sourceSets = setOf(s)) { + link(it.sureClassNames, it, sourceSets = setOf(s)) + } } } } } + private fun propertySignature(p: DProperty, sourceSets: Set<SourceSetData> = p.sourceSets.toSet()) = contentBuilder.contentFor(p, ContentKind.Symbol, setOf(TextStyle.Monospace), sourceSets = sourceSets) { - platformText(p.visibility) { (it.takeIf { it !in ignoredVisibilities }?.name ?: "") + " " } - platformText(p.modifier){ it.name + " "} - p.setter?.let { text("var ") } ?: text("val ") - list(p.generics, prefix = "<", suffix = "> ") { - +buildSignature(it) - } - p.receiver?.also { - signatureForProjection(it.type) - text(".") + group(styles = setOf(TextStyle.Block)) { + annotationsBlock(p) + platformText(p.visibility) { it.takeIf { it !in ignoredVisibilities }?.name?.let { "$it " } ?: "" } + platformText(p.modifier) { + it.takeIf { it !in ignoredModifiers }?.let { + if (it is JavaModifier.Empty) KotlinModifier.Open else it + }?.name?.let { "$it " } ?: "" + } + text(p.modifiers().toSignatureString()) + p.setter?.let { text("var ") } ?: text("val ") + list(p.generics, prefix = "<", suffix = "> ") { + +buildSignature(it) + } + p.receiver?.also { + signatureForProjection(it.type) + text(".") + } + link(p.name, p.dri) + text(": ") + signatureForProjection(p.type) } - link(p.name, p.dri) - text(": ") - signatureForProjection(p.type) } private fun functionSignature(f: DFunction, sourceSets: Set<SourceSetData> = f.sourceSets.toSet()) = contentBuilder.contentFor(f, ContentKind.Symbol, setOf(TextStyle.Monospace), sourceSets = sourceSets) { - platformText(f.visibility) { (it.takeIf { it !in ignoredVisibilities }?.name ?: "") + " " } - platformText(f.modifier) { it.name + " " } - text("fun ") - list(f.generics, prefix = "<", suffix = "> ") { - +buildSignature(it) - } - f.receiver?.also { - signatureForProjection(it.type) - text(".") - } - link(f.name, f.dri) - text("(") - list(f.parameters) { - text(it.name!!) - text(": ") - - signatureForProjection(it.type) - } - text(")") - if (f.documentReturnType()) { - text(": ") - signatureForProjection(f.type) + group(styles = setOf(TextStyle.Block)) { + annotationsBlock(f) + platformText(f.visibility) { it.takeIf { it !in ignoredVisibilities }?.name?.let { "$it " } ?: "" } + platformText(f.modifier) { + it.takeIf { it !in ignoredModifiers }?.let { + if (it is JavaModifier.Empty) KotlinModifier.Open else it + }?.name?.let { "$it " } ?: "" + } + text(f.modifiers().toSignatureString()) + text("fun ") + list(f.generics, prefix = "<", suffix = "> ") { + +buildSignature(it) + } + f.receiver?.also { + signatureForProjection(it.type) + text(".") + } + link(f.name, f.dri) + list(f.parameters, "(", ")") { + annotationsInline(it) + text(it.modifiers().toSignatureString()) + text(it.name!!) + text(": ") + signatureForProjection(it.type) + } + if (f.documentReturnType()) { + text(": ") + signatureForProjection(f.type) + } } } @@ -152,7 +194,8 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog setOf(TextStyle.Monospace), sourceSets = platforms.toSet() ) { - platformText(t.visibility) { (it.takeIf { it !in ignoredVisibilities }?.name ?: "") + " " } + platformText(t.visibility) { it.takeIf { it !in ignoredVisibilities }?.name?.let { "$it " } ?: "" } + text(t.modifiers().toSignatureString()) text("typealias ") signatureForProjection(t.type) text(" = ") @@ -175,21 +218,21 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog is TypeConstructor -> if (p.function) +funType(mainDRI.single(), mainPlatformData, p) else - group { + 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() + " ") signatureForProjection(p.inner) } is Star -> text("*") - is Nullable -> group { + is Nullable -> group(styles = emptySet()) { signatureForProjection(p.inner) text("?") } @@ -197,6 +240,7 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog is JavaObject -> link("Any", DriOfAny) is Void -> link("Unit", DriOfUnit) is PrimitiveJavaType -> signatureForProjection(p.translateToKotlin()) + is Dynamic -> text("dynamic") } private fun funType(dri: DRI, sourceSets: Set<SourceSetData>, type: TypeConstructor) = diff --git a/plugins/base/src/main/kotlin/signatures/KotlinSignatureUtils.kt b/plugins/base/src/main/kotlin/signatures/KotlinSignatureUtils.kt new file mode 100644 index 00000000..3ce4be0a --- /dev/null +++ b/plugins/base/src/main/kotlin/signatures/KotlinSignatureUtils.kt @@ -0,0 +1,24 @@ +package org.jetbrains.dokka.base.signatures + +import javaslang.Tuple2 +import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder +import org.jetbrains.dokka.model.Documentable +import org.jetbrains.dokka.model.ExtraModifiers +import org.jetbrains.dokka.model.ExtraModifiers.Companion.kotlinOnlyModifiers +import org.jetbrains.dokka.model.properties.WithExtraProperties + +object KotlinSignatureUtils : JvmSingatureUtils { + + private val strategy = OnlyOnce + private val listBrackets = Tuple2('[', ']') + private val classExtension = "::class" + + override fun PageContentBuilder.DocumentableContentBuilder.annotationsBlock(d: Documentable) = + annotationsBlockWithIgnored(d, emptySet(), strategy, listBrackets, classExtension) + + override fun PageContentBuilder.DocumentableContentBuilder.annotationsInline(d: Documentable) = + annotationsInlineWithIgnored(d, emptySet(), strategy, listBrackets, classExtension) + + override fun <T : Documentable> WithExtraProperties<T>.modifiers() = + modifiersWithFilter(kotlinOnlyModifiers) +}
\ No newline at end of file diff --git a/plugins/base/src/main/kotlin/signatures/SignatureProvider.kt b/plugins/base/src/main/kotlin/signatures/SignatureProvider.kt index 041015fc..7d7995b7 100644 --- a/plugins/base/src/main/kotlin/signatures/SignatureProvider.kt +++ b/plugins/base/src/main/kotlin/signatures/SignatureProvider.kt @@ -1,8 +1,12 @@ package org.jetbrains.dokka.base.signatures -import org.jetbrains.dokka.model.Documentable +import javaslang.Tuple2 +import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder +import org.jetbrains.dokka.model.* +import org.jetbrains.dokka.model.properties.WithExtraProperties import org.jetbrains.dokka.pages.ContentNode +import org.jetbrains.dokka.pages.TextStyle interface SignatureProvider { fun signature(documentable: Documentable): ContentNode -}
\ No newline at end of file +} diff --git a/plugins/base/src/main/kotlin/transformers/pages/annotations/DeprecatedStrikethroughTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/annotations/DeprecatedStrikethroughTransformer.kt index 55f01ad3..96e2c907 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/annotations/DeprecatedStrikethroughTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/annotations/DeprecatedStrikethroughTransformer.kt @@ -11,11 +11,11 @@ class DeprecatedStrikethroughTransformer(val context: DokkaContext) : PageTransf override fun invoke(input: RootPageNode): RootPageNode = input.transformContentPagesTree { contentPage -> if (contentPage.documentable?.isDeprecated() == true || contentPage.documentable?.hasDeprecatedChildren() == true) { val deprecatedDRIs = - contentPage.dri + - contentPage.documentable?.children - ?.filter { it.isDeprecated() } - ?.map { it.dri } - ?.toSet().orEmpty() + if (contentPage.documentable?.isDeprecated() == true) contentPage.dri else emptySet<DRI>() + + contentPage.documentable?.children + ?.filter { it.isDeprecated() } + ?.map { it.dri } + ?.toSet().orEmpty() contentPage.modified(content = contentPage.content.addStrikethroughToSignature(deprecatedDRIs)) } else { diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt index f5b86df6..c24a3384 100644 --- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt @@ -1,5 +1,6 @@ package org.jetbrains.dokka.base.translators.descriptors +import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.dokka.analysis.DokkaResolutionFacade import org.jetbrains.dokka.links.* import org.jetbrains.dokka.links.Callable @@ -12,19 +13,27 @@ import org.jetbrains.dokka.parsers.MarkdownParser import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.utilities.DokkaLogger import org.jetbrains.dokka.transformers.sources.SourceToDocumentableTranslator +import org.jetbrains.kotlin.asJava.classes.tryResolveMarkerInterfaceFQName import org.jetbrains.kotlin.builtins.isExtensionFunctionType import org.jetbrains.kotlin.builtins.isFunctionType import org.jetbrains.kotlin.codegen.isJvmStaticInObjectOrClassOrInterface import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies import org.jetbrains.kotlin.idea.kdoc.findKDoc import org.jetbrains.kotlin.load.kotlin.toSourceElement import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.calls.components.isVararg -import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic +import org.jetbrains.kotlin.resolve.constants.ConstantValue +import org.jetbrains.kotlin.resolve.constants.AnnotationValue as ConstantsAnnotationValue +import org.jetbrains.kotlin.resolve.constants.ArrayValue as ConstantsArrayValue +import org.jetbrains.kotlin.resolve.constants.EnumValue as ConstantsEnumValue +import org.jetbrains.kotlin.resolve.constants.KClassValue as ConstantsKtClassValue +import org.jetbrains.kotlin.resolve.constants.KClassValue.Value.NormalClass +import org.jetbrains.kotlin.resolve.constants.KClassValue.Value.LocalClass import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperclassesWithoutAny import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny @@ -32,10 +41,13 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.source.KotlinSourceElement +import org.jetbrains.kotlin.types.DynamicType import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeProjection import org.jetbrains.kotlin.utils.addToStdlib.safeAs import java.nio.file.Paths +import java.lang.IllegalArgumentException +import kotlin.reflect.jvm.internal.impl.resolve.constants.KClassValue object DefaultDescriptorToDocumentableTranslator : SourceToDocumentableTranslator { @@ -285,7 +297,11 @@ private class DokkaDescriptorVisitor( expectPresentInSet = sourceSet.takeIf { isExpect }, sourceSets = listOf(sourceSet), generics = descriptor.typeParameters.map { it.toTypeParameter() }, - extra = PropertyContainer.withAll(descriptor.additionalExtras(), descriptor.getAnnotations()) + extra = PropertyContainer.withAll( + (descriptor.additionalExtras() + (descriptor.backingField?.getAnnotationsAsExtraModifiers() + ?: emptyList())).toProperty(), + descriptor.getAllAnnotations() + ) ) } @@ -375,7 +391,8 @@ private class DokkaDescriptorVisitor( type = descriptor.type.toBound(), expectPresentInSet = null, documentation = descriptor.resolveDescriptorData(), - sourceSets = listOf(sourceSet) + sourceSets = listOf(sourceSet), + extra = PropertyContainer.withAll(descriptor.getAnnotations()) ) private fun visitPropertyAccessorDescriptor( @@ -395,7 +412,7 @@ private class DokkaDescriptorVisitor( expectPresentInSet = sourceSet.takeIf { isExpect }, documentation = descriptor.resolveDescriptorData(), sourceSets = listOf(sourceSet), - extra = PropertyContainer.withAll(descriptor.additionalExtras(), descriptor.getAnnotations()) + extra = PropertyContainer.withAll(descriptor.additionalExtras(), getAllAnnotations()) ) val name = run { @@ -523,20 +540,23 @@ private class DokkaDescriptorVisitor( extra = PropertyContainer.withAll(additionalExtras()) ) - private fun KotlinType.toBound(): Bound = when (val ctor = constructor.declarationDescriptor) { - is TypeParameterDescriptor -> OtherParameter( - declarationDRI = DRI.from(ctor.containingDeclaration), - name = ctor.name.asString() - ).let { - if (isMarkedNullable) Nullable(it) else it + private fun KotlinType.toBound(): Bound = when (this) { + is DynamicType -> Dynamic + else -> when (val ctor = constructor.declarationDescriptor) { + is TypeParameterDescriptor -> OtherParameter( + declarationDRI = DRI.from(ctor.containingDeclaration), + name = ctor.name.asString() + ).let { + if (isMarkedNullable) Nullable(it) else it + } + |
