diff options
5 files changed, 97 insertions, 67 deletions
diff --git a/core/src/main/kotlin/model/aditionalExtras.kt b/core/src/main/kotlin/model/aditionalExtras.kt index 1023545d..fcf1efa6 100644 --- a/core/src/main/kotlin/model/aditionalExtras.kt +++ b/core/src/main/kotlin/model/aditionalExtras.kt @@ -19,10 +19,10 @@ class AdditionalModifiers(val content: Set<ExtraModifiers>) : ExtraProperty<Docu override val key: ExtraProperty.Key<Documentable, *> = AdditionalModifiers } -class Annotations(val content: List<Annotation>) : ExtraProperty<Documentable> { +class Annotations(val content: SourceSetDependent<List<Annotation>>) : ExtraProperty<Documentable> { companion object : ExtraProperty.Key<Documentable, Annotations> { override fun mergeStrategyFor(left: Annotations, right: Annotations): MergeStrategy<Documentable> = - MergeStrategy.Replace(Annotations((left.content + right.content).distinct())) + MergeStrategy.Replace(Annotations(left.content + right.content)) } override val key: ExtraProperty.Key<Documentable, *> = Annotations diff --git a/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt b/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt index 0ae72109..0cf085b8 100644 --- a/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt +++ b/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt @@ -15,8 +15,8 @@ interface JvmSignatureUtils { fun Set<ExtraModifiers>.toSignatureString(): String = joinToString("") { it.name.toLowerCase() + " " } - fun <T : Documentable> WithExtraProperties<T>.annotations(): List<Annotations.Annotation> = - extra[Annotations]?.content ?: emptyList() + fun <T : Documentable> WithExtraProperties<T>.annotations(): SourceSetDependent<List<Annotations.Annotation>> = + extra[Annotations]?.content ?: emptyMap() private fun Annotations.Annotation.toSignatureString(): String = "@" + this.dri.classNames + "(" + this.params.entries.joinToString { it.key + "=" + it.value } + ")" @@ -24,7 +24,7 @@ interface JvmSignatureUtils { private fun PageContentBuilder.DocumentableContentBuilder.annotations( d: Documentable, ignored: Set<Annotations.Annotation>, - operation: (Annotations.Annotation) -> Unit + operation: PageContentBuilder.DocumentableContentBuilder.(Annotations.Annotation) -> Unit ): Unit = when (d) { is DFunction -> d.annotations() is DProperty -> d.annotations() @@ -39,8 +39,12 @@ interface JvmSignatureUtils { is DParameter -> d.annotations() else -> null }?.let { - it.filter { it !in ignored }.forEach { - operation(it) + it.entries.forEach { + group(sourceSets = setOf(it.key)) { + it.value.filter { it !in ignored }.forEach { + operation(it) + } + } } } ?: Unit @@ -50,6 +54,7 @@ interface JvmSignatureUtils { listBrackets: Pair<Char, Char>, classExtension: String ) { + when (renderAtStrategy) { is All, is OnlyOnce -> text("@") is Never -> Unit 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 96e2c907..f7d6f88f 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/annotations/DeprecatedStrikethroughTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/annotations/DeprecatedStrikethroughTransformer.kt @@ -1,5 +1,6 @@ package org.jetbrains.dokka.base.transformers.pages.annotations +import org.jetbrains.dokka.base.renderers.platforms import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.* import org.jetbrains.dokka.model.properties.WithExtraProperties @@ -9,17 +10,22 @@ import org.jetbrains.dokka.transformers.pages.PageTransformer class DeprecatedStrikethroughTransformer(val context: DokkaContext) : PageTransformer { override fun invoke(input: RootPageNode): RootPageNode = input.transformContentPagesTree { contentPage -> - if (contentPage.documentable?.isDeprecated() == true || contentPage.documentable?.hasDeprecatedChildren() == true) { - val deprecatedDRIs = - 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 { - contentPage + contentPage.platforms().fold(contentPage) { acc, sourceSetData -> + if (acc.documentable?.isDeprecated(sourceSetData) == true || acc.documentable?.hasDeprecatedChildren( + sourceSetData + ) == true + ) { + val deprecatedDRIs = + if (acc.documentable?.isDeprecated(sourceSetData) == true) contentPage.dri else emptySet<DRI>() + + contentPage.documentable?.children + ?.filter { it.isDeprecated(sourceSetData) } + ?.map { it.dri } + ?.toSet().orEmpty() + + acc.modified(content = acc.content.addStrikethroughToSignature(deprecatedDRIs)) + } else { + acc + } } } @@ -34,23 +40,24 @@ class DeprecatedStrikethroughTransformer(val context: DokkaContext) : PageTransf else -> this } - private fun Documentable.isDeprecated(): Boolean = when (this) { - is DClass -> this.isKotlinOrJavaDeprecated() - is DAnnotation -> this.isKotlinOrJavaDeprecated() - is DObject -> this.isKotlinOrJavaDeprecated() - is DInterface -> this.isKotlinOrJavaDeprecated() - is DEnum -> this.isKotlinOrJavaDeprecated() - is DFunction -> this.isKotlinOrJavaDeprecated() - is DProperty -> this.isKotlinOrJavaDeprecated() - is DEnumEntry -> this.isKotlinOrJavaDeprecated() + private fun Documentable.isDeprecated(sourceSetData: SourceSetData) = when (this) { + is DClass -> this.isKotlinOrJavaDeprecated(sourceSetData) + is DAnnotation -> this.isKotlinOrJavaDeprecated(sourceSetData) + is DObject -> this.isKotlinOrJavaDeprecated(sourceSetData) + is DInterface -> this.isKotlinOrJavaDeprecated(sourceSetData) + is DEnum -> this.isKotlinOrJavaDeprecated(sourceSetData) + is DFunction -> this.isKotlinOrJavaDeprecated(sourceSetData) + is DProperty -> this.isKotlinOrJavaDeprecated(sourceSetData) + is DEnumEntry -> this.isKotlinOrJavaDeprecated(sourceSetData) else -> false } - private fun Documentable.hasDeprecatedChildren() = children.any { it.isDeprecated() } + private fun Documentable.hasDeprecatedChildren(sourceSetData: SourceSetData) = + children.any { it.isDeprecated(sourceSetData) } - private fun <T : Documentable> WithExtraProperties<T>.isKotlinOrJavaDeprecated() = - extra[Annotations]?.content?.any { + private fun <T : Documentable> WithExtraProperties<T>.isKotlinOrJavaDeprecated(sourceSetData: SourceSetData) = + extra[Annotations]?.content?.get(sourceSetData)?.any { it.dri == DRI("kotlin", "Deprecated") || it.dri == DRI("java.lang", "Deprecated") } == true diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt index 9f01267e..a8175405 100644 --- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt @@ -16,7 +16,6 @@ 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.CallableMemberDescriptor.Kind.FAKE_OVERRIDE import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.annotations.Annotated @@ -48,6 +47,7 @@ import org.jetbrains.kotlin.resolve.constants.AnnotationValue as ConstantsAnnota 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 kotlin.IllegalArgumentException object DefaultDescriptorToDocumentableTranslator : SourceToDocumentableTranslator { @@ -88,11 +88,11 @@ private class DokkaDescriptorVisitor( } private fun Collection<DeclarationDescriptor>.filterDescriptorsInSourceSet() = filter { - it.toSourceElement.containingFile.toString().let { path -> - path.isNotBlank() && sourceSet.sourceRoots.any { root -> - Paths.get(path).startsWith(Paths.get(root.path)) - } + it.toSourceElement.containingFile.toString().let { path -> + path.isNotBlank() && sourceSet.sourceRoots.any { root -> + Paths.get(path).startsWith(Paths.get(root.path)) } + } } private fun <T> T.toSourceSetDependent() = mapOf(sourceSet to this) @@ -301,7 +301,7 @@ private class DokkaDescriptorVisitor( sourceSets = listOf(sourceSet), generics = descriptor.typeParameters.map { it.toTypeParameter() }, extra = PropertyContainer.withAll( - (descriptor.additionalExtras() + (descriptor.backingField?.getAnnotationsAsExtraModifiers() + (descriptor.additionalExtras() + (descriptor.backingField?.getAnnotationsAsExtraModifiers()?.entries?.single()?.value ?: emptyList())).toProperty(), descriptor.getAllAnnotations() ) @@ -365,9 +365,11 @@ private class DokkaDescriptorVisitor( documentation = descriptor.resolveDescriptorData().let { sourceSetDependent -> if (descriptor.isPrimary) { sourceSetDependent.map { entry -> - Pair(entry.key, entry.value.copy(children = (entry.value.children.find { it is Constructor }?.root?.let { constructor -> - listOf( Description(constructor) ) - } ?: emptyList<TagWrapper>()) + entry.value.children.filterIsInstance<Param>())) + Pair( + entry.key, + entry.value.copy(children = (entry.value.children.find { it is Constructor }?.root?.let { constructor -> + listOf(Description(constructor)) + } ?: emptyList<TagWrapper>()) + entry.value.children.filterIsInstance<Param>())) }.toMap() } else { sourceSetDependent @@ -379,8 +381,9 @@ private class DokkaDescriptorVisitor( sourceSets = listOf(sourceSet), extra = PropertyContainer.withAll<DFunction>(descriptor.additionalExtras(), descriptor.getAnnotations()) .let { - if(descriptor.isPrimary) { it + PrimaryConstructorExtra } - else it + if (descriptor.isPrimary) { + it + PrimaryConstructorExtra + } else it } ) } @@ -637,18 +640,19 @@ private class DokkaDescriptorVisitor( private fun List<ExtraModifiers>.toProperty() = AdditionalModifiers(this.toSet()) - private fun Annotated.getAnnotations() = getListOfAnnotations().let(::Annotations) + private fun Annotated.getAnnotations() = getListOfSourceSetDependentAnnotations().let(::Annotations) - private fun Annotated.getListOfAnnotations() = annotations.map { it.toAnnotation() } + private fun Annotated.getListOfSourceSetDependentAnnotations() = + mapOf(sourceSet to annotations.mapNotNull { it.toAnnotation() }) - private fun ConstantValue<*>.toValue(): AnnotationParameterValue = when (this) { - is ConstantsAnnotationValue -> AnnotationValue(value.toAnnotation()) - is ConstantsArrayValue -> ArrayValue(value.map { it.toValue() }) + private fun ConstantValue<*>.toValue(): AnnotationParameterValue? = when (this) { + is ConstantsAnnotationValue -> value.toAnnotation()?.let { AnnotationValue(it) } + is ConstantsArrayValue -> ArrayValue(value.mapNotNull { it.toValue() }) is ConstantsEnumValue -> EnumValue( fullEnumEntryName(), DRI(enumClassId.packageFqName.asString(), fullEnumEntryName()) ) - is ConstantsKtClassValue -> when(value) { + is ConstantsKtClassValue -> when (value) { is NormalClass -> (value as NormalClass).value.classId.let { ClassValue( it.relativeClassName.asString(), @@ -665,19 +669,28 @@ private class DokkaDescriptorVisitor( else -> StringValue(toString()) } - private fun AnnotationDescriptor.toAnnotation() = Annotations.Annotation( - DRI.from(annotationClass as DeclarationDescriptor), - allValueArguments.map { it.key.asString() to it.value.toValue() }.toMap() - ) + private fun AnnotationDescriptor.toAnnotation(): Annotations.Annotation? = + DRI.from(annotationClass as DeclarationDescriptor) + .takeIf { it.classNames != "<ERROR CLASS>" }?.let { + Annotations.Annotation( + it, + allValueArguments.map { it.key.asString() to it.value.toValue() }.filter { + it.second != null + }.toMap() as Map<String, AnnotationParameterValue> + ) + } - private fun PropertyDescriptor.getAllAnnotations() = - (getListOfAnnotations() + (backingField?.getListOfAnnotations() ?: emptyList())).let(::Annotations) + private fun PropertyDescriptor.getAllAnnotations(): Annotations = + (getListOfSourceSetDependentAnnotations() + (backingField?.getListOfSourceSetDependentAnnotations() + ?: emptyMap())).let(::Annotations) - private fun FieldDescriptor.getAnnotationsAsExtraModifiers() = getAnnotations().content.mapNotNull { - try { - ExtraModifiers.valueOf(it.dri.classNames?.toLowerCase() ?: "") - } catch (e: IllegalArgumentException) { - null + private fun FieldDescriptor.getAnnotationsAsExtraModifiers() = getAnnotations().content.mapValues { + it.value.mapNotNull { + try { + ExtraModifiers.valueOf(it.dri.classNames?.toLowerCase() ?: "") + } catch (e: IllegalArgumentException) { + null + } } } diff --git a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt index efd689ba..1f52b2d9 100644 --- a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt @@ -35,7 +35,7 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator { override fun invoke(sourceSetData: SourceSetData, context: DokkaContext): DModule { - fun isFileInSourceRoots(file: File) : Boolean { + fun isFileInSourceRoots(file: File): Boolean { return sourceSetData.sourceRoots.any { root -> file.path.startsWith(File(root.path).absolutePath) } } @@ -168,7 +168,8 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator { constructors.map { parseFunction(it, true) }, mapTypeParameters(dri), listOf(sourceSetData), - PropertyContainer.empty<DAnnotation>() + annotations.toList().toListOfAnnotations().let(::Annotations) + PropertyContainer.empty<DAnnotation>() + annotations.toList().toListOfAnnotations() + .let(::Annotations) ) isEnum -> DEnum( dri, @@ -183,7 +184,8 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator { emptyList(), emptyList(), listOf(sourceSetData), - PropertyContainer.empty<DEnumEntry>() + entry.annotations.toList().toListOfAnnotations().let(::Annotations) + PropertyContainer.empty<DEnumEntry>() + entry.annotations.toList().toListOfAnnotations() + .let(::Annotations) ) }, documentation, @@ -213,7 +215,8 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator { mapTypeParameters(dri), ancestors, listOf(sourceSetData), - PropertyContainer.empty<DInterface>() + annotations.toList().toListOfAnnotations().let(::Annotations) + PropertyContainer.empty<DInterface>() + annotations.toList().toListOfAnnotations() + .let(::Annotations) ) else -> DClass( dri, @@ -287,12 +290,12 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator { ).toSet() ) - private fun AdditionalModifiers.toListOfAnnotations() = this.content.map { + private fun AdditionalModifiers.toListOfAnnotations() = mapOf(sourceSetData to this.content.map { if (it !is ExtraModifiers.JavaOnlyModifiers.Static) Annotations.Annotation(DRI("kotlin.jvm", it.name.toLowerCase().capitalize()), emptyMap()) else Annotations.Annotation(DRI("kotlin.jvm", "JvmStatic"), emptyMap()) - } + }) private fun getBound(type: PsiType): Bound = cachedBounds.getOrPut(type.canonicalText) { @@ -400,14 +403,15 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator { ) } - private fun Collection<PsiAnnotation>.toListOfAnnotations() = filter { it !is KtLightAbstractAnnotation }.mapNotNull { it.toAnnotation() } + private fun Collection<PsiAnnotation>.toListOfAnnotations() = + mapOf(sourceSetData to filter { it !is KtLightAbstractAnnotation }.mapNotNull { it.toAnnotation() }) private fun JvmAnnotationAttribute.toValue(): AnnotationParameterValue = when (this) { is PsiNameValuePair -> value?.toValue() ?: StringValue("") else -> StringValue(this.attributeName) } - private fun PsiAnnotationMemberValue.toValue(): AnnotationParameterValue = when(this) { + private fun PsiAnnotationMemberValue.toValue(): AnnotationParameterValue = when (this) { is PsiAnnotation -> AnnotationValue(toAnnotation()) is PsiArrayInitializerMemberValue -> ArrayValue(initializers.map { it.toValue() }) is PsiReferenceExpression -> EnumValue( @@ -423,7 +427,8 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator { private fun PsiAnnotation.toAnnotation() = Annotations.Annotation( driOfReference(), - attributes.filter { it !is KtLightAbstractAnnotation }.mapNotNull { it.attributeName to it.toValue() }.toMap() + attributes.filter { it !is KtLightAbstractAnnotation }.mapNotNull { it.attributeName to it.toValue() } + .toMap() ) private fun PsiElement.driOfReference() = getChildOfType<PsiJavaCodeReferenceElement>()?.resolve()?.let { |