diff options
4 files changed, 82 insertions, 34 deletions
diff --git a/core/src/main/kotlin/model/aditionalExtras.kt b/core/src/main/kotlin/model/aditionalExtras.kt index d9587fe3..b0755759 100644 --- a/core/src/main/kotlin/model/aditionalExtras.kt +++ b/core/src/main/kotlin/model/aditionalExtras.kt @@ -1,5 +1,6 @@ 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 @@ -14,4 +15,12 @@ class AdditionalModifiers(val content: Set<ExtraModifiers>) : ExtraProperty<Docu override fun equals(other: Any?): Boolean = if (other is AdditionalModifiers) other.content == content else false override fun hashCode() = content.hashCode() override val key: ExtraProperty.Key<Documentable, *> = AdditionalKey +} + +class Annotations(val content: List<Annotation>) : ExtraProperty<Documentable> { + companion object : ExtraProperty.Key<Documentable, Annotations> + + override val key: ExtraProperty.Key<Documentable, *> = Annotations + + data class Annotation(val dri: DRI, val params: Map<String, String>) }
\ No newline at end of file diff --git a/core/src/main/kotlin/model/properties/PropertyContainer.kt b/core/src/main/kotlin/model/properties/PropertyContainer.kt index 7fa46ccb..5ea42e42 100644 --- a/core/src/main/kotlin/model/properties/PropertyContainer.kt +++ b/core/src/main/kotlin/model/properties/PropertyContainer.kt @@ -15,9 +15,12 @@ class PropertyContainer<C : Any> internal constructor( } inline fun <reified T : Any> allOfType(): List<T> = map.values.filterIsInstance<T>() + fun <D : C> addAll(vararg extras: ExtraProperty<D>): PropertyContainer<D> = + PropertyContainer(map + extras.map { p -> p.key to p }) companion object { fun <T : Any> empty(): PropertyContainer<T> = PropertyContainer(emptyMap()) + fun <T : Any> withAll(vararg extras: ExtraProperty<T>) = empty<T>().addAll(*extras) } } diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt index eb23ffd7..e2afefe5 100644 --- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt @@ -5,8 +5,6 @@ import org.jetbrains.dokka.links.Callable import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.links.withClass import org.jetbrains.dokka.model.* -import org.jetbrains.dokka.model.DEnum -import org.jetbrains.dokka.model.DFunction import org.jetbrains.dokka.model.doc.DocumentationNode import org.jetbrains.dokka.model.properties.PropertyContainer import org.jetbrains.dokka.pages.PlatformData @@ -21,9 +19,7 @@ import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBo 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.descriptorUtil.getAllSuperclassesWithoutAny -import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny -import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces +import org.jetbrains.kotlin.resolve.descriptorUtil.* import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.KotlinType @@ -86,6 +82,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv ClassKind.ENUM_CLASS -> enumDescriptor(descriptor, parent) ClassKind.OBJECT -> objectDescriptor(descriptor, parent) ClassKind.INTERFACE -> interfaceDescriptor(descriptor, parent) + ClassKind.ANNOTATION_CLASS -> annotationDescriptor(descriptor, parent) else -> classDescriptor(descriptor, parent) } @@ -107,7 +104,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv generics = descriptor.typeConstructor.parameters.map { it.toTypeParameter() }, companion = descriptor.companion(driWithPlatform), platformData = listOf(platformData), - extra = descriptor.additionalExtras() + extra = PropertyContainer.withAll(descriptor.additionalExtras(), descriptor.getAnnotations()) ) } @@ -127,7 +124,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv supertypes = PlatformDependent.from(platformData, info.supertypes), documentation = info.docs, platformData = listOf(platformData), - extra = descriptor.additionalExtras() + extra = PropertyContainer.withAll(descriptor.additionalExtras(), descriptor.getAnnotations()) ) } @@ -150,7 +147,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv documentation = info.docs, companion = descriptor.companion(driWithPlatform), platformData = listOf(platformData), - extra = descriptor.additionalExtras() + extra = PropertyContainer.withAll(descriptor.additionalExtras(), descriptor.getAnnotations()) ) } @@ -166,7 +163,27 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv functions = scope.functions(driWithPlatform), properties = scope.properties(driWithPlatform), platformData = listOf(platformData), - extra = descriptor.additionalExtras() + extra = PropertyContainer.withAll(descriptor.additionalExtras(), descriptor.getAnnotations()) + ) + } + + fun annotationDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DAnnotation { + val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() + val scope = descriptor.unsubstitutedMemberScope + + return DAnnotation( + dri = driWithPlatform.dri, + name = descriptor.name.asString(), + documentation = descriptor.resolveDescriptorData(platformData), + classlikes = scope.classlikes(driWithPlatform), + functions = scope.functions(driWithPlatform), + properties = scope.properties(driWithPlatform), + platformData = listOf(platformData), + extra = PropertyContainer.withAll(descriptor.additionalExtras(), descriptor.getAnnotations()), + companion = descriptor.companionObjectDescriptor?.let { objectDescriptor(it, driWithPlatform) }, + visibility = PlatformDependent(mapOf(platformData to descriptor.visibility.toDokkaVisibility())), + constructors = descriptor.constructors.map { visitConstructorDescriptor(it, driWithPlatform) }, + sources = descriptor.createSources() ) } @@ -197,7 +214,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv companion = descriptor.companion(driWithPlatform), supertypes = PlatformDependent.from(platformData, info.supertypes), platformData = listOf(platformData), - extra = descriptor.additionalExtras() + extra = PropertyContainer.withAll(descriptor.additionalExtras(), descriptor.getAnnotations()) ) } @@ -213,7 +230,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv }, sources = actual, getter = descriptor.accessors.filterIsInstance<PropertyGetterDescriptor>().singleOrNull()?.let { - visitPropertyAccessorDescriptor(it, descriptor, dri) + visitPropertyAccessorDescriptor(it, descriptor, dri) }, setter = descriptor.accessors.filterIsInstance<PropertySetterDescriptor>().singleOrNull()?.let { visitPropertyAccessorDescriptor(it, descriptor, dri) @@ -223,7 +240,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv modifier = descriptor.modifier(), type = descriptor.returnType!!.toBound(), platformData = listOf(platformData), - extra = descriptor.additionalExtras() + extra = PropertyContainer.withAll(descriptor.additionalExtras(), descriptor.getAnnotations()) ) } @@ -248,7 +265,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv modifier = descriptor.modifier(), type = descriptor.returnType!!.toBound(), platformData = listOf(platformData), - extra = descriptor.additionalExtras() + extra = PropertyContainer.withAll(descriptor.additionalExtras(), descriptor.getAnnotations()) ) } @@ -272,7 +289,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv modifier = descriptor.modifier(), generics = descriptor.typeParameters.map { it.toTypeParameter() }, platformData = listOf(platformData), - extra = descriptor.additionalExtras() + extra = PropertyContainer.withAll(descriptor.additionalExtras(), descriptor.getAnnotations()) ) } @@ -302,7 +319,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv type = this.type.toBound(), documentation = descriptor.resolveDescriptorData(platformData), platformData = listOf(platformData), - extra = descriptor.additionalExtras() + extra = PropertyContainer.withAll(descriptor.additionalExtras(), descriptor.getAnnotations()) ) val name = run { @@ -336,7 +353,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv }, sources = descriptor.createSources(), platformData = listOf(platformData), - extra = descriptor.additionalExtras() + extra = PropertyContainer.withAll(descriptor.additionalExtras(), descriptor.getAnnotations()) ) } @@ -347,7 +364,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv type = descriptor.type.toBound(), documentation = descriptor.resolveDescriptorData(platformData), platformData = listOf(platformData), - extra = descriptor.additionalExtras() + extra = PropertyContainer.withAll(descriptor.additionalExtras()) ) private fun MemberScope.functions(parent: DRIWithPlatformInfo): List<DFunction> = @@ -395,7 +412,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv PlatformDependent.from(platformData, getDocumentation()), upperBounds.map { it.toBound() }, listOf(platformData), - extra = additionalExtras() + extra = PropertyContainer.withAll(additionalExtras()) ) private fun KotlinType.toBound(): Bound = when (val ctor = constructor.declarationDescriptor) { @@ -444,7 +461,7 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv PlatformDependent(mapOf(platformData to DescriptorDocumentableSource(this))) } - inline fun <reified D : Documentable> FunctionDescriptor.additionalExtras(): PropertyContainer<D> = listOfNotNull( + fun FunctionDescriptor.additionalExtras() = listOfNotNull( ExtraModifiers.DYNAMIC.takeIf { isDynamic() }, ExtraModifiers.INFIX.takeIf { isInfix }, ExtraModifiers.INLINE.takeIf { isInline }, @@ -454,18 +471,18 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv ExtraModifiers.TAILREC.takeIf { isTailrec }, ExtraModifiers.EXTERNAL.takeIf { isExternal }, ExtraModifiers.OVERRIDE.takeIf { DescriptorUtils.isOverride(this) } - ).toContainer() + ).toProperty() - inline fun <reified D : Documentable> ClassDescriptor.additionalExtras(): PropertyContainer<D> = listOfNotNull( + fun ClassDescriptor.additionalExtras() = listOfNotNull( ExtraModifiers.DYNAMIC.takeIf { isDynamic() }, ExtraModifiers.INLINE.takeIf { isInline }, ExtraModifiers.EXTERNAL.takeIf { isExternal }, ExtraModifiers.INNER.takeIf { isInner }, ExtraModifiers.DATA.takeIf { isData }, ExtraModifiers.OVERRIDE.takeIf { getSuperInterfaces().isNotEmpty() || getSuperClassNotAny() != null } - ).toContainer() + ).toProperty() - fun ValueParameterDescriptor.additionalExtras(): PropertyContainer<DParameter> = + fun ValueParameterDescriptor.additionalExtras() = listOfNotNull( ExtraModifiers.DYNAMIC.takeIf { isDynamic() }, ExtraModifiers.NOINLINE.takeIf { isNoinline }, @@ -473,27 +490,32 @@ private class DokkaDescriptorVisitor( // TODO: close this class and make it priv ExtraModifiers.CONST.takeIf { isConst }, ExtraModifiers.LATEINIT.takeIf { isLateInit }, ExtraModifiers.VARARG.takeIf { isVararg } - ).toContainer() + ).toProperty() - fun TypeParameterDescriptor.additionalExtras(): PropertyContainer<DTypeParameter> = + fun TypeParameterDescriptor.additionalExtras() = listOfNotNull( ExtraModifiers.DYNAMIC.takeIf { isDynamic() }, ExtraModifiers.REIFIED.takeIf { isReified } - ).toContainer() + ).toProperty() - fun PropertyDescriptor.additionalExtras(): PropertyContainer<DProperty> = listOfNotNull( + fun PropertyDescriptor.additionalExtras() = listOfNotNull( ExtraModifiers.DYNAMIC.takeIf { isDynamic() }, ExtraModifiers.CONST.takeIf { isConst }, ExtraModifiers.LATEINIT.takeIf { isLateInit }, ExtraModifiers.STATIC.takeIf { isJvmStaticInObjectOrClassOrInterface() }, ExtraModifiers.EXTERNAL.takeIf { isExternal }, ExtraModifiers.OVERRIDE.takeIf { DescriptorUtils.isOverride(this) } - ).toContainer() + ).toProperty() - inline fun <reified D : Documentable> List<ExtraModifiers>.toContainer( - container: PropertyContainer<D> = PropertyContainer.empty() - ): PropertyContainer<D> = - container + AdditionalModifiers(this.toSet()) + private fun List<ExtraModifiers>.toProperty() = + AdditionalModifiers(this.toSet()) + + fun DeclarationDescriptor.getAnnotations() = annotations.map { annotation -> + Annotations.Annotation( + annotation.let { it.annotationClass as DeclarationDescriptor }.let { DRI.from(it) }, + annotation.allValueArguments.map { (k, v) -> k.asString() to v.value.toString() }.toMap() + ) + }.let(::Annotations) data class ClassInfo(val supertypes: List<DRI>, val docs: PlatformDependent<DocumentationNode>) diff --git a/plugins/base/src/test/kotlin/model/ClassesTest.kt b/plugins/base/src/test/kotlin/model/ClassesTest.kt index 2f83d8c0..166a72e3 100644 --- a/plugins/base/src/test/kotlin/model/ClassesTest.kt +++ b/plugins/base/src/test/kotlin/model/ClassesTest.kt @@ -402,9 +402,23 @@ class ClassesTest : AbstractModelTest("/src/main/kotlin/classes/Test.kt", "class } } + @Test fun annotatedClass() { + inlineModelTest( + """@Suppress("abc") class Foo() {}""" + ) { + with((this / "classes" / "Foo").cast<Class>()) { + with(extra[Annotations]?.content?.firstOrNull().assertNotNull("annotations")) { + dri.toString() equals "kotlin/Suppress////" + with(params["names"].assertNotNull("param")) { + this equals "[\"abc\"]" + } + } + } + } + } + // TODO annotations -// @Test -// fun annotatedClass() { +// @Test fun annotatedClass() { // verifyPackageMember("testdata/classes/annotatedClass.kt", ModelConfig( // analysisPlatform = analysisPlatform, // withKotlinRuntime = true |