Skip to content

Commit

Permalink
Refactor Ancestry Graphs
Browse files Browse the repository at this point in the history
  • Loading branch information
BarkingBad committed Feb 15, 2022
1 parent d884fa7 commit 31e6abe
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 127 deletions.
36 changes: 36 additions & 0 deletions core/api/core.api
Expand Up @@ -667,6 +667,42 @@ public final class org/jetbrains/dokka/model/AdditionalModifiers$Companion : org
public fun mergeStrategyFor (Lorg/jetbrains/dokka/model/AdditionalModifiers;Lorg/jetbrains/dokka/model/AdditionalModifiers;)Lorg/jetbrains/dokka/model/properties/MergeStrategy;
}

public final class org/jetbrains/dokka/model/AncestryNode {
public fun <init> (ILorg/jetbrains/dokka/model/TypeConstructor;Lorg/jetbrains/dokka/model/AncestryNode;Ljava/util/List;)V
public final fun allImplementedInterfaces ()Ljava/util/List;
public final fun component1 ()I
public final fun component2 ()Lorg/jetbrains/dokka/model/TypeConstructor;
public final fun component3 ()Lorg/jetbrains/dokka/model/AncestryNode;
public final fun component4 ()Ljava/util/List;
public final fun copy (ILorg/jetbrains/dokka/model/TypeConstructor;Lorg/jetbrains/dokka/model/AncestryNode;Ljava/util/List;)Lorg/jetbrains/dokka/model/AncestryNode;
public static synthetic fun copy$default (Lorg/jetbrains/dokka/model/AncestryNode;ILorg/jetbrains/dokka/model/TypeConstructor;Lorg/jetbrains/dokka/model/AncestryNode;Ljava/util/List;ILjava/lang/Object;)Lorg/jetbrains/dokka/model/AncestryNode;
public fun equals (Ljava/lang/Object;)Z
public final fun getInterfaces ()Ljava/util/List;
public final fun getLevel ()I
public final fun getSuperclass ()Lorg/jetbrains/dokka/model/AncestryNode;
public final fun getTypeConstructor ()Lorg/jetbrains/dokka/model/TypeConstructor;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class org/jetbrains/dokka/model/AncestryPath : org/jetbrains/dokka/model/properties/ExtraProperty {
public static final field Companion Lorg/jetbrains/dokka/model/AncestryPath$Companion;
public fun <init> (Ljava/util/Map;)V
public final fun component1 ()Ljava/util/Map;
public final fun copy (Ljava/util/Map;)Lorg/jetbrains/dokka/model/AncestryPath;
public static synthetic fun copy$default (Lorg/jetbrains/dokka/model/AncestryPath;Ljava/util/Map;ILjava/lang/Object;)Lorg/jetbrains/dokka/model/AncestryPath;
public fun equals (Ljava/lang/Object;)Z
public final fun getAncestryNode ()Ljava/util/Map;
public fun getKey ()Lorg/jetbrains/dokka/model/properties/ExtraProperty$Key;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class org/jetbrains/dokka/model/AncestryPath$Companion : org/jetbrains/dokka/model/properties/ExtraProperty$Key {
public synthetic fun mergeStrategyFor (Ljava/lang/Object;Ljava/lang/Object;)Lorg/jetbrains/dokka/model/properties/MergeStrategy;
public fun mergeStrategyFor (Lorg/jetbrains/dokka/model/AncestryPath;Lorg/jetbrains/dokka/model/AncestryPath;)Lorg/jetbrains/dokka/model/properties/MergeStrategy;
}

public abstract class org/jetbrains/dokka/model/AnnotationParameterValue {
}

Expand Down
15 changes: 14 additions & 1 deletion core/src/main/kotlin/model/additionalExtras.kt
Expand Up @@ -123,4 +123,17 @@ data class ConstructorValues(val values: SourceSetDependent<List<Expression>>) :
}

override val key: ExtraProperty.Key<DEnumEntry, ConstructorValues> = ConstructorValues
}
}

data class AncestryNode(
val typeConstructor: TypeConstructor,
val superclass: AncestryNode?,
val interfaces: List<AncestryNode>,
) {
fun allImplementedInterfaces(): List<TypeConstructor> {
fun traverseInterfaces(ancestry: AncestryNode): List<TypeConstructor> =
ancestry.interfaces.flatMap { listOf(it.typeConstructor) + traverseInterfaces(it) } +
(ancestry.superclass?.let(::traverseInterfaces) ?: emptyList())
return traverseInterfaces(this).distinct()
}
}
Expand Up @@ -13,15 +13,14 @@ import org.jetbrains.dokka.analysis.KotlinAnalysis
import org.jetbrains.dokka.analysis.from
import org.jetbrains.dokka.base.DokkaBase
import org.jetbrains.dokka.base.parsers.MarkdownParser
import org.jetbrains.dokka.base.translators.isDirectlyAnException
import org.jetbrains.dokka.base.translators.typeConstructorsBeingExceptionsOrNull
import org.jetbrains.dokka.base.translators.psi.parsers.JavadocParser
import org.jetbrains.dokka.base.translators.unquotedValue
import org.jetbrains.dokka.links.*
import org.jetbrains.dokka.links.Callable
import org.jetbrains.dokka.model.*
import org.jetbrains.dokka.model.AnnotationTarget
import org.jetbrains.dokka.model.Nullable
import org.jetbrains.dokka.model.TypeConstructor
import org.jetbrains.dokka.model.doc.*
import org.jetbrains.dokka.model.properties.PropertyContainer
import org.jetbrains.dokka.plugability.DokkaContext
Expand Down Expand Up @@ -215,8 +214,8 @@ private class DokkaDescriptorVisitor(
extra = PropertyContainer.withAll(
descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(),
descriptor.getAnnotations().toSourceSetDependent().toAnnotations(),
ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent()),
info.exceptionsInSupertypes?.let { ExceptionInSupertypes(it.toSourceSetDependent()) },
ImplementedInterfaces(info.ancestry.allImplementedInterfaces().toSourceSetDependent()),
info.ancestry.exceptionInSupertypesOrNull()
)
)
}
Expand Down Expand Up @@ -253,8 +252,8 @@ private class DokkaDescriptorVisitor(
extra = PropertyContainer.withAll(
descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(),
descriptor.getAnnotations().toSourceSetDependent().toAnnotations(),
ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent()),
info.exceptionsInSupertypes?.let { ExceptionInSupertypes(it.toSourceSetDependent()) },
ImplementedInterfaces(info.ancestry.allImplementedInterfaces().toSourceSetDependent()),
info.ancestry.exceptionInSupertypesOrNull()
)
)
}
Expand Down Expand Up @@ -298,7 +297,7 @@ private class DokkaDescriptorVisitor(
extra = PropertyContainer.withAll(
descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(),
descriptor.getAnnotations().toSourceSetDependent().toAnnotations(),
ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent())
ImplementedInterfaces(info.ancestry.allImplementedInterfaces().toSourceSetDependent())
)
)
}
Expand Down Expand Up @@ -420,8 +419,8 @@ private class DokkaDescriptorVisitor(
extra = PropertyContainer.withAll<DClass>(
descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(),
descriptor.getAnnotations().toSourceSetDependent().toAnnotations(),
ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent()),
info.exceptionsInSupertypes?.let { ExceptionInSupertypes(it.toSourceSetDependent()) },
ImplementedInterfaces(info.ancestry.allImplementedInterfaces().toSourceSetDependent()),
info.ancestry.exceptionInSupertypesOrNull()
)
)
}
Expand Down Expand Up @@ -664,8 +663,10 @@ private class DokkaDescriptorVisitor(
with(descriptor) {
coroutineScope {
val generics = async { descriptor.declaredTypeParameters.parallelMap { it.toVariantTypeParameter() } }
val info = buildAncestryInformation(listOf(underlyingType)).sortedBy { it.level }

val info = buildAncestryInformation(defaultType).copy(
superclass = buildAncestryInformation(underlyingType),
interfaces = emptyList()
)
DTypeAlias(
dri = DRI.from(this@with),
name = name.asString(),
Expand All @@ -678,8 +679,7 @@ private class DokkaDescriptorVisitor(
generics = generics.await(),
extra = PropertyContainer.withAll(
descriptor.getAnnotations().toSourceSetDependent().toAnnotations(),
info.exceptionsInSupertypes()?.takeIf { it.isNotEmpty() }
?.let { ExceptionInSupertypes(it.toSourceSetDependent()) },
info.exceptionInSupertypesOrNull(),
)
)
}
Expand Down Expand Up @@ -759,41 +759,31 @@ private class DokkaDescriptorVisitor(
DRI.from(kt.constructor.declarationDescriptor as DeclarationDescriptor),
kt.arguments.map { it.toProjection() })


private tailrec suspend fun buildAncestryInformation(
supertypes: Collection<KotlinType>,
level: Int = 0,
ancestryInformation: Set<AncestryLevel> = emptySet()
): Set<AncestryLevel> {
if (supertypes.isEmpty()) return ancestryInformation

val (interfaces, superclass) = supertypes
private suspend fun buildAncestryInformation(
kotlinType: KotlinType
): AncestryNode {
val (interfaces, superclass) = kotlinType.immediateSupertypes().filterNot { it.isAnyOrNullableAny() }
.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(
level,
superclass.parallelMap(::toTypeConstructor).singleOrNull(),
interfaces.parallelMap(::toTypeConstructor)
return coroutineScope {
AncestryNode(
typeConstructor = toTypeConstructor(kotlinType),
superclass = superclass.parallelMap(::buildAncestryInformation).singleOrNull(),
interfaces = interfaces.parallelMap(::buildAncestryInformation)
)
}

return buildAncestryInformation(
supertypes = supertypes.flatMap { it.immediateSupertypes() },
level = level + 1,
ancestryInformation = updated
)
}


private suspend fun ClassDescriptor.resolveClassDescriptionData(): ClassInfo {
return coroutineScope {
ClassInfo(
buildAncestryInformation(this@resolveClassDescriptionData.typeConstructor.supertypes.filterNot { it.isAnyOrNullableAny() }).sortedBy { it.level },
buildAncestryInformation(this@resolveClassDescriptionData.defaultType),
resolveDescriptorData()
)
}
Expand Down Expand Up @@ -1050,22 +1040,16 @@ private class DokkaDescriptorVisitor(
else -> node?.text?.let { ComplexExpression(it) }
}

private data class ClassInfo(val ancestry: List<AncestryLevel>, val docs: SourceSetDependent<DocumentationNode>) {
private data class ClassInfo(val ancestry: AncestryNode, val docs: SourceSetDependent<DocumentationNode>) {
val supertypes: List<TypeConstructorWithKind>
get() = ancestry.firstOrNull { it.level == 0 }?.let {
listOfNotNull(it.superclass?.let {
get() = listOfNotNull(ancestry.superclass?.let {
it.typeConstructor.let {
TypeConstructorWithKind(
it,
KotlinClassKindTypes.CLASS
)
}) + it.interfaces.map { TypeConstructorWithKind(it, KotlinClassKindTypes.INTERFACE) }
}.orEmpty()

val allImplementedInterfaces: List<TypeConstructor>
get() = ancestry.flatMap { it.interfaces }.distinct()

val exceptionsInSupertypes: List<TypeConstructor>?
get() = ancestry.exceptionsInSupertypes()
}
}) + ancestry.interfaces.map { TypeConstructorWithKind(it.typeConstructor, KotlinClassKindTypes.INTERFACE) }
}

private fun DescriptorVisibility.toDokkaVisibility(): org.jetbrains.dokka.model.Visibility = when (this.delegate) {
Expand Down Expand Up @@ -1093,13 +1077,8 @@ private class DokkaDescriptorVisitor(
kind == CallableMemberDescriptor.Kind.SYNTHESIZED ||
containingDeclaration.fqNameOrNull()?.asString()
?.let { it == "kotlin.Any" || it == "kotlin.Enum" || it == "java.lang.Enum" || it == "java.lang.Object" } == true
}

private data class AncestryLevel(
val level: Int,
val superclass: TypeConstructor?,
val interfaces: List<TypeConstructor>
)
private fun AncestryNode.exceptionInSupertypesOrNull(): ExceptionInSupertypes? =
typeConstructorsBeingExceptionsOrNull()?.let { ExceptionInSupertypes(it.toSourceSetDependent()) }
}

private fun List<AncestryLevel>.exceptionsInSupertypes(): List<TypeConstructor>? =
mapNotNull { it.superclass }.filter { type -> type.dri.isDirectlyAnException() }.takeIf { it.isNotEmpty() }
9 changes: 9 additions & 0 deletions plugins/base/src/main/kotlin/translators/isException.kt
@@ -1,6 +1,15 @@
package org.jetbrains.dokka.base.translators

import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.AncestryNode
import org.jetbrains.dokka.model.TypeConstructor

internal fun AncestryNode.typeConstructorsBeingExceptionsOrNull(): List<TypeConstructor>? {
fun traverseSupertypes(ancestry: AncestryNode): List<TypeConstructor> =
listOf(ancestry.typeConstructor) + (ancestry.superclass?.let(::traverseSupertypes) ?: emptyList())

return superclass?.let(::traverseSupertypes)?.filter { type -> type.dri.isDirectlyAnException() }?.takeIf { it.isNotEmpty() }
}

internal fun DRI.isDirectlyAnException(): Boolean =
toString().let { stringed ->
Expand Down

0 comments on commit 31e6abe

Please sign in to comment.