aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorKamil Doległo <kamilok1965@interia.pl>2020-10-15 18:11:17 +0200
committerKamil Doległo <kamilok1965@interia.pl>2020-10-15 18:11:17 +0200
commitc5a31b47ef182e4de3ec58d5ce5624e65fe11015 (patch)
tree9df60d122c56ea2ea2d918584f47051ef533622e /plugins
parent7f948864077388e10ba3608b0d5e1d9a4ea0f4d9 (diff)
downloaddokka-c5a31b47ef182e4de3ec58d5ce5624e65fe11015.tar.gz
dokka-c5a31b47ef182e4de3ec58d5ce5624e65fe11015.tar.bz2
dokka-c5a31b47ef182e4de3ec58d5ce5624e65fe11015.zip
Fix class cast exception when creating the ancestry tree
Diffstat (limited to 'plugins')
-rw-r--r--plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt50
-rw-r--r--plugins/base/src/test/kotlin/model/ClassesTest.kt62
2 files changed, 80 insertions, 32 deletions
diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt
index 1a643624..8db3aa43 100644
--- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt
+++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt
@@ -241,7 +241,8 @@ private class DokkaDescriptorVisitor(
val functions = async { descriptorsWithKind.functions.visitFunctions(driWithPlatform) }
val properties = async { descriptorsWithKind.properties.visitProperties(driWithPlatform) }
val classlikes = async { descriptorsWithKind.classlikes.visitClasslikes(driWithPlatform) }
- val constructors = async { descriptor.constructors.parallelMap { visitConstructorDescriptor(it, driWithPlatform) } }
+ val constructors =
+ async { descriptor.constructors.parallelMap { visitConstructorDescriptor(it, driWithPlatform) } }
val entries = async { descriptorsWithKind.enumEntries.visitEnumEntries(driWithPlatform) }
DEnum(
@@ -312,7 +313,8 @@ private class DokkaDescriptorVisitor(
val properties = async { descriptorsWithKind.properties.visitProperties(driWithPlatform) }
val classlikes = async { descriptorsWithKind.classlikes.visitClasslikes(driWithPlatform) }
val generics = async { descriptor.declaredTypeParameters.parallelMap { it.toVariantTypeParameter() } }
- val constructors = async { descriptor.constructors.parallelMap { visitConstructorDescriptor(it, driWithPlatform) } }
+ val constructors =
+ async { descriptor.constructors.parallelMap { visitConstructorDescriptor(it, driWithPlatform) } }
DAnnotation(
dri = driWithPlatform.dri,
@@ -391,7 +393,10 @@ private class DokkaDescriptorVisitor(
}
}
- private suspend fun visitPropertyDescriptor(originalDescriptor: PropertyDescriptor, parent: DRIWithPlatformInfo): DProperty {
+ private suspend fun visitPropertyDescriptor(
+ originalDescriptor: PropertyDescriptor,
+ parent: DRIWithPlatformInfo
+ ): DProperty {
val dri = parent.dri.copy(callable = Callable.from(originalDescriptor))
val descriptor = originalDescriptor.getConcreteDescriptor()
val isExpect = descriptor.isExpect
@@ -439,7 +444,10 @@ private class DokkaDescriptorVisitor(
else
overriddenDescriptors.first().createDRI(DRI.from(this))
- private suspend fun visitFunctionDescriptor(originalDescriptor: FunctionDescriptor, parent: DRIWithPlatformInfo): DFunction {
+ private suspend fun visitFunctionDescriptor(
+ originalDescriptor: FunctionDescriptor,
+ parent: DRIWithPlatformInfo
+ ): DFunction {
val (dri, inheritedFrom) = originalDescriptor.createDRI()
val descriptor = originalDescriptor.getConcreteDescriptor()
val isExpect = descriptor.isExpect
@@ -630,7 +638,8 @@ private class DokkaDescriptorVisitor(
generics = generics.await(),
extra = PropertyContainer.withAll(
descriptor.getAnnotations().toSourceSetDependent().toAnnotations(),
- info.exceptionsInSupertypes()?.takeIf { it.isNotEmpty() }?.let { ExceptionInSupertypes(it.toSourceSetDependent()) },
+ info.exceptionsInSupertypes()?.takeIf { it.isNotEmpty() }
+ ?.let { ExceptionInSupertypes(it.toSourceSetDependent()) },
)
)
}
@@ -666,14 +675,16 @@ private class DokkaDescriptorVisitor(
class EnumEntryDescriptor
- val groupedDescriptors = descriptors.groupBy { when {
- it is FunctionDescriptor -> FunctionDescriptor::class
- it is PropertyDescriptor -> PropertyDescriptor::class
- it is ClassDescriptor && it.kind != ClassKind.ENUM_ENTRY -> ClassDescriptor::class
- it is TypeAliasDescriptor -> TypeAliasDescriptor::class
- it is ClassDescriptor && it.kind == ClassKind.ENUM_ENTRY -> EnumEntryDescriptor::class
- else -> IllegalStateException::class
- } }
+ val groupedDescriptors = descriptors.groupBy {
+ when {
+ it is FunctionDescriptor -> FunctionDescriptor::class
+ it is PropertyDescriptor -> PropertyDescriptor::class
+ it is ClassDescriptor && it.kind != ClassKind.ENUM_ENTRY -> ClassDescriptor::class
+ it is TypeAliasDescriptor -> TypeAliasDescriptor::class
+ it is ClassDescriptor && it.kind == ClassKind.ENUM_ENTRY -> EnumEntryDescriptor::class
+ else -> IllegalStateException::class
+ }
+ }
return DescriptorsWithKind(
(groupedDescriptors[FunctionDescriptor::class] ?: emptyList()) as List<FunctionDescriptor>,
@@ -716,9 +727,13 @@ private class DokkaDescriptorVisitor(
): Set<AncestryLevel> {
if (supertypes.isEmpty()) return ancestryInformation
- val (interfaces, superclass) = supertypes.partition {
- (it.constructor.declarationDescriptor as ClassDescriptor).kind == ClassKind.INTERFACE
- }
+ val (interfaces, superclass) = supertypes
+ .partition {
+ val declaration = it.constructor.declarationDescriptor
+ val descriptor = declaration as? ClassDescriptor
+ ?: (declaration as? TypeAliasDescriptor)?.underlyingType?.constructor?.declarationDescriptor as? ClassDescriptor
+ descriptor?.kind == ClassKind.INTERFACE
+ }
val updated = coroutineScope {
ancestryInformation + AncestryLevel(
@@ -758,7 +773,8 @@ private class DokkaDescriptorVisitor(
private suspend fun org.jetbrains.kotlin.descriptors.annotations.Annotations.getPresentableName(): String? =
map { it.toAnnotation() }.singleOrNull { it.dri.classNames == "ParameterName" }?.params?.get("name")
- .safeAs<StringValue>()?.value?.drop(1)?.dropLast(1) // Dropping enclosing doublequotes because we don't want to have it in our custom signature serializer
+ .safeAs<StringValue>()?.value?.drop(1)
+ ?.dropLast(1) // Dropping enclosing doublequotes because we don't want to have it in our custom signature serializer
private suspend fun KotlinType.toBound(): Bound = when (this) {
diff --git a/plugins/base/src/test/kotlin/model/ClassesTest.kt b/plugins/base/src/test/kotlin/model/ClassesTest.kt
index bb7bac2d..b6787126 100644
--- a/plugins/base/src/test/kotlin/model/ClassesTest.kt
+++ b/plugins/base/src/test/kotlin/model/ClassesTest.kt
@@ -460,32 +460,40 @@ class ClassesTest : AbstractModelTest("/src/main/kotlin/classes/Test.kt", "class
}
}
- @Test fun genericAnnotationClass() {
+ @Test
+ fun genericAnnotationClass() {
inlineModelTest(
"""annotation class Foo<A,B,C,D:Number>() {}"""
) {
- with((this / "classes" / "Foo").cast<DAnnotation>()){
- generics.map { it.name to it.bounds.first().name } equals listOf("A" to "Any", "B" to "Any", "C" to "Any", "D" to "Number")
+ with((this / "classes" / "Foo").cast<DAnnotation>()) {
+ generics.map { it.name to it.bounds.first().name } equals listOf(
+ "A" to "Any",
+ "B" to "Any",
+ "C" to "Any",
+ "D" to "Number"
+ )
}
}
}
- @Test fun nestedGenericClasses(){
+ @Test
+ fun nestedGenericClasses() {
inlineModelTest(
"""
|class Outer<OUTER> {
| inner class Inner<INNER, T : OUTER> { }
|}
""".trimMargin()
- ){
- with((this / "classes" / "Outer").cast<DClass>()){
+ ) {
+ with((this / "classes" / "Outer").cast<DClass>()) {
val inner = classlikes.single().cast<DClass>()
inner.generics.map { it.name to it.bounds.first().name } equals listOf("INNER" to "Any", "T" to "OUTER")
}
}
}
- @Test fun allImplementedInterfaces() {
+ @Test
+ fun allImplementedInterfaces() {
inlineModelTest(
"""
| interface Highest { }
@@ -494,14 +502,16 @@ class ClassesTest : AbstractModelTest("/src/main/kotlin/classes/Test.kt", "class
| interface LowerImplInterface: Lower { }
| class Tested : HighestImpl(), LowerImplInterface { }
""".trimIndent()
- ){
- with((this / "classes" / "Tested").cast<DClass>()){
- extra[ImplementedInterfaces]?.interfaces?.entries?.single()?.value?.map { it.dri.sureClassNames }?.sorted() equals listOf("Highest", "Lower", "LowerImplInterface").sorted()
+ ) {
+ with((this / "classes" / "Tested").cast<DClass>()) {
+ extra[ImplementedInterfaces]?.interfaces?.entries?.single()?.value?.map { it.dri.sureClassNames }
+ ?.sorted() equals listOf("Highest", "Lower", "LowerImplInterface").sorted()
}
}
}
- @Test fun multipleClassInheritance() {
+ @Test
+ fun multipleClassInheritance() {
inlineModelTest(
"""
| open class A { }
@@ -515,7 +525,8 @@ class ClassesTest : AbstractModelTest("/src/main/kotlin/classes/Test.kt", "class
}
}
- @Test fun multipleClassInheritanceWithInterface(){
+ @Test
+ fun multipleClassInheritanceWithInterface() {
inlineModelTest(
"""
| open class A { }
@@ -524,10 +535,31 @@ class ClassesTest : AbstractModelTest("/src/main/kotlin/classes/Test.kt", "class
| interface Y : X { }
| class Tested : B(), Y { }
""".trimIndent()
- ){
+ ) {
with((this / "classes" / "Tested").cast<DClass>()) {
- supertypes.entries.single().value.map { it.typeConstructor.dri.sureClassNames to it.kind }.sortedBy { it.first } equals listOf("B" to KotlinClassKindTypes.CLASS, "Y" to KotlinClassKindTypes.INTERFACE)
+ supertypes.entries.single().value.map { it.typeConstructor.dri.sureClassNames to it.kind }
+ .sortedBy { it.first } equals listOf(
+ "B" to KotlinClassKindTypes.CLASS,
+ "Y" to KotlinClassKindTypes.INTERFACE
+ )
+ }
+ }
+ }
+
+ @Test
+ fun doublyTypealiasedException() {
+ inlineModelTest(
+ """
+ | typealias B = RuntimeException
+ | typealias A = B
+ """.trimMargin()
+ ) {
+ with((this / "classes" / "A").cast<DTypeAlias>()) {
+ extra[ExceptionInSupertypes].assertNotNull("Typealias A should have ExceptionInSupertypes in its extra field")
+ }
+ with((this / "classes" / "B").cast<DTypeAlias>()) {
+ extra[ExceptionInSupertypes].assertNotNull("Typealias B should have ExceptionInSupertypes in its extra field")
}
}
}
-} \ No newline at end of file
+}