aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/src/main/kotlin/model/aditionalExtras.kt9
-rw-r--r--core/src/main/kotlin/model/properties/PropertyContainer.kt3
-rw-r--r--plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt86
-rw-r--r--plugins/base/src/test/kotlin/model/ClassesTest.kt18
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