aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src/main/kotlin/transformers/documentables
diff options
context:
space:
mode:
authorIgnat Beresnev <ignat.beresnev@jetbrains.com>2023-07-05 10:04:55 +0200
committerGitHub <noreply@github.com>2023-07-05 10:04:55 +0200
commit9559158bfeeb274e9ccf1b4563f1b23b42afc493 (patch)
tree3ece0887623cfe2b7148af23001867a1dd5e6597 /plugins/base/src/main/kotlin/transformers/documentables
parentcbd9733d3dd2f52992e98e7cebd072091a572529 (diff)
downloaddokka-9559158bfeeb274e9ccf1b4563f1b23b42afc493.tar.gz
dokka-9559158bfeeb274e9ccf1b4563f1b23b42afc493.tar.bz2
dokka-9559158bfeeb274e9ccf1b4563f1b23b42afc493.zip
Decompose Kotlin/Java analysis (#3034)
* Extract analysis into separate modules
Diffstat (limited to 'plugins/base/src/main/kotlin/transformers/documentables')
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt4
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/DeprecatedDocumentableFilterTransformer.kt2
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilterTransformer.kt4
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/ExtensionExtractorTransformer.kt6
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/InheritedEntriesDocumentableFilterTransformer.kt5
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/InheritorsExtractorTransformer.kt2
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationReader.kt107
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt12
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/ReportUndocumentedTransformer.kt41
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/SuppressTagDocumentableFilter.kt4
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/utils/FullClassHierarchyBuilder.kt84
11 files changed, 32 insertions, 239 deletions
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt b/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt
index 17e3cbcd..d9c68981 100644
--- a/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt
+++ b/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt
@@ -1,13 +1,13 @@
package org.jetbrains.dokka.base.transformers.documentables
import org.jetbrains.dokka.DokkaConfiguration
+import org.jetbrains.dokka.base.utils.firstNotNullOfOrNull
import org.jetbrains.dokka.model.*
import org.jetbrains.dokka.model.properties.ExtraProperty
import org.jetbrains.dokka.model.properties.MergeStrategy
import org.jetbrains.dokka.model.properties.mergeExtras
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.transformers.documentation.DocumentableMerger
-import org.jetbrains.kotlin.util.firstNotNullResult
internal class DefaultDocumentableMerger(val context: DokkaContext) : DocumentableMerger {
private val dependencyInfo = context.getDependencyInfo()
@@ -21,7 +21,7 @@ internal class DefaultDocumentableMerger(val context: DokkaContext) : Documentab
list.flatMap { it.packages }
) { pck1, pck2 -> pck1.mergeWith(pck2) },
documentation = list.map { it.documentation }.flatMap { it.entries }.associate { (k, v) -> k to v },
- expectPresentInSet = list.firstNotNullResult { it.expectPresentInSet },
+ expectPresentInSet = list.firstNotNullOfOrNull { it.expectPresentInSet },
sourceSets = list.flatMap { it.sourceSets }.toSet()
).mergeExtras(left, right)
}
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/DeprecatedDocumentableFilterTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/DeprecatedDocumentableFilterTransformer.kt
index 1112ac15..366690c7 100644
--- a/plugins/base/src/main/kotlin/transformers/documentables/DeprecatedDocumentableFilterTransformer.kt
+++ b/plugins/base/src/main/kotlin/transformers/documentables/DeprecatedDocumentableFilterTransformer.kt
@@ -1,7 +1,7 @@
package org.jetbrains.dokka.base.transformers.documentables
-import org.jetbrains.dokka.DokkaConfiguration.PackageOptions
import org.jetbrains.dokka.DokkaConfiguration
+import org.jetbrains.dokka.DokkaConfiguration.PackageOptions
import org.jetbrains.dokka.model.Annotations
import org.jetbrains.dokka.model.Documentable
import org.jetbrains.dokka.model.EnumValue
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilterTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilterTransformer.kt
index 94688799..713166bb 100644
--- a/plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilterTransformer.kt
+++ b/plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilterTransformer.kt
@@ -1,11 +1,11 @@
package org.jetbrains.dokka.base.transformers.documentables
import org.jetbrains.dokka.DokkaConfiguration
+import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
+import org.jetbrains.dokka.DokkaDefaults
import org.jetbrains.dokka.model.*
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer
-import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
-import org.jetbrains.dokka.DokkaDefaults
class DocumentableVisibilityFilterTransformer(val context: DokkaContext) : PreMergeDocumentableTransformer {
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/ExtensionExtractorTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/ExtensionExtractorTransformer.kt
index 19af0564..79df844e 100644
--- a/plugins/base/src/main/kotlin/transformers/documentables/ExtensionExtractorTransformer.kt
+++ b/plugins/base/src/main/kotlin/transformers/documentables/ExtensionExtractorTransformer.kt
@@ -2,7 +2,6 @@ package org.jetbrains.dokka.base.transformers.documentables
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
-import org.jetbrains.dokka.base.transformers.documentables.utils.FullClassHierarchyBuilder
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.links.DriOfAny
import org.jetbrains.dokka.model.*
@@ -10,16 +9,19 @@ import org.jetbrains.dokka.model.properties.ExtraProperty
import org.jetbrains.dokka.model.properties.MergeStrategy
import org.jetbrains.dokka.model.properties.plus
import org.jetbrains.dokka.plugability.DokkaContext
+import org.jetbrains.dokka.plugability.plugin
+import org.jetbrains.dokka.plugability.querySingle
import org.jetbrains.dokka.transformers.documentation.DocumentableTransformer
import org.jetbrains.dokka.utilities.parallelForEach
import org.jetbrains.dokka.utilities.parallelMap
+import org.jetbrains.kotlin.analysis.kotlin.internal.InternalKotlinAnalysisPlugin
class ExtensionExtractorTransformer : DocumentableTransformer {
override fun invoke(original: DModule, context: DokkaContext): DModule = runBlocking(Dispatchers.Default) {
val classGraph = async {
if (!context.configuration.suppressInheritedMembers)
- FullClassHierarchyBuilder()(original)
+ context.plugin<InternalKotlinAnalysisPlugin>().querySingle { fullClassHierarchyBuilder }.build(original)
else
emptyMap()
}
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/InheritedEntriesDocumentableFilterTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/InheritedEntriesDocumentableFilterTransformer.kt
index 2e4b29ff..01438432 100644
--- a/plugins/base/src/main/kotlin/transformers/documentables/InheritedEntriesDocumentableFilterTransformer.kt
+++ b/plugins/base/src/main/kotlin/transformers/documentables/InheritedEntriesDocumentableFilterTransformer.kt
@@ -1,6 +1,7 @@
package org.jetbrains.dokka.base.transformers.documentables
-import org.jetbrains.dokka.model.*
+import org.jetbrains.dokka.model.Documentable
+import org.jetbrains.dokka.model.InheritedMember
import org.jetbrains.dokka.model.properties.WithExtraProperties
import org.jetbrains.dokka.plugability.DokkaContext
@@ -14,4 +15,4 @@ class InheritedEntriesDocumentableFilterTransformer(context: DokkaContext) :
return context.configuration.suppressInheritedMembers && containsInheritedFrom
}
-} \ No newline at end of file
+}
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/InheritorsExtractorTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/InheritorsExtractorTransformer.kt
index 463ec419..6106466f 100644
--- a/plugins/base/src/main/kotlin/transformers/documentables/InheritorsExtractorTransformer.kt
+++ b/plugins/base/src/main/kotlin/transformers/documentables/InheritorsExtractorTransformer.kt
@@ -1,11 +1,11 @@
package org.jetbrains.dokka.base.transformers.documentables
+import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.*
import org.jetbrains.dokka.model.properties.ExtraProperty
import org.jetbrains.dokka.model.properties.MergeStrategy
import org.jetbrains.dokka.plugability.DokkaContext
-import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
import org.jetbrains.dokka.transformers.documentation.DocumentableTransformer
class InheritorsExtractorTransformer : DocumentableTransformer {
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationReader.kt b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationReader.kt
deleted file mode 100644
index faf94db2..00000000
--- a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationReader.kt
+++ /dev/null
@@ -1,107 +0,0 @@
-package org.jetbrains.dokka.base.transformers.documentables
-
-import org.jetbrains.dokka.DokkaConfiguration
-import org.jetbrains.dokka.analysis.KotlinAnalysis
-import org.jetbrains.dokka.base.DokkaBase
-import org.jetbrains.dokka.base.parsers.moduleAndPackage.ModuleAndPackageDocumentation.Classifier
-import org.jetbrains.dokka.base.parsers.moduleAndPackage.ModuleAndPackageDocumentationFragment
-import org.jetbrains.dokka.base.parsers.moduleAndPackage.ModuleAndPackageDocumentationParsingContext
-import org.jetbrains.dokka.base.parsers.moduleAndPackage.parseModuleAndPackageDocumentation
-import org.jetbrains.dokka.base.parsers.moduleAndPackage.parseModuleAndPackageDocumentationFragments
-import org.jetbrains.dokka.model.DModule
-import org.jetbrains.dokka.model.DPackage
-import org.jetbrains.dokka.model.SourceSetDependent
-import org.jetbrains.dokka.model.doc.*
-import org.jetbrains.dokka.model.doc.Deprecated
-import org.jetbrains.dokka.plugability.DokkaContext
-import org.jetbrains.dokka.plugability.plugin
-import org.jetbrains.dokka.plugability.querySingle
-import org.jetbrains.dokka.utilities.associateWithNotNull
-
-internal interface ModuleAndPackageDocumentationReader {
- operator fun get(module: DModule): SourceSetDependent<DocumentationNode>
- operator fun get(pkg: DPackage): SourceSetDependent<DocumentationNode>
-}
-
-internal fun ModuleAndPackageDocumentationReader(context: DokkaContext): ModuleAndPackageDocumentationReader =
- ContextModuleAndPackageDocumentationReader(context)
-
-private class ContextModuleAndPackageDocumentationReader(
- private val context: DokkaContext
-) : ModuleAndPackageDocumentationReader {
-
- private val kotlinAnalysis: KotlinAnalysis = context.plugin<DokkaBase>().querySingle { kotlinAnalysis }
-
- private val documentationFragments: SourceSetDependent<List<ModuleAndPackageDocumentationFragment>> =
- context.configuration.sourceSets.associateWith { sourceSet ->
- sourceSet.includes.flatMap { include -> parseModuleAndPackageDocumentationFragments(include) }
- }
-
- private fun findDocumentationNodes(
- sourceSets: Set<DokkaConfiguration.DokkaSourceSet>,
- predicate: (ModuleAndPackageDocumentationFragment) -> Boolean
- ): SourceSetDependent<DocumentationNode> {
- return sourceSets.associateWithNotNull { sourceSet ->
- val fragments = documentationFragments[sourceSet].orEmpty().filter(predicate)
- val resolutionFacade = kotlinAnalysis[sourceSet].facade
- val documentations = fragments.map { fragment ->
- parseModuleAndPackageDocumentation(
- context = ModuleAndPackageDocumentationParsingContext(context.logger, resolutionFacade),
- fragment = fragment
- )
- }
- when (documentations.size) {
- 0 -> null
- 1 -> documentations.single().documentation
- else -> DocumentationNode(documentations.flatMap { it.documentation.children }
- .mergeDocumentationNodes())
- }
- }
- }
-
- private val ModuleAndPackageDocumentationFragment.canonicalPackageName: String
- get() {
- check(classifier == Classifier.Package)
- if (name == "[root]") return ""
- return name
- }
-
- override fun get(module: DModule): SourceSetDependent<DocumentationNode> {
- return findDocumentationNodes(module.sourceSets) { fragment ->
- fragment.classifier == Classifier.Module && (fragment.name == module.name)
- }
- }
-
- override fun get(pkg: DPackage): SourceSetDependent<DocumentationNode> {
- return findDocumentationNodes(pkg.sourceSets) { fragment ->
- fragment.classifier == Classifier.Package && fragment.canonicalPackageName == pkg.dri.packageName
- }
- }
-
- private fun List<TagWrapper>.mergeDocumentationNodes(): List<TagWrapper> =
- groupBy { it::class }.values.map {
- it.reduce { acc, tagWrapper ->
- val newRoot = CustomDocTag(
- acc.children + tagWrapper.children,
- name = (tagWrapper as? NamedTagWrapper)?.name.orEmpty()
- )
- when (acc) {
- is See -> acc.copy(newRoot)
- is Param -> acc.copy(newRoot)
- is Throws -> acc.copy(newRoot)
- is Sample -> acc.copy(newRoot)
- is Property -> acc.copy(newRoot)
- is CustomTagWrapper -> acc.copy(newRoot)
- is Description -> acc.copy(newRoot)
- is Author -> acc.copy(newRoot)
- is Version -> acc.copy(newRoot)
- is Since -> acc.copy(newRoot)
- is Return -> acc.copy(newRoot)
- is Receiver -> acc.copy(newRoot)
- is Constructor -> acc.copy(newRoot)
- is Deprecated -> acc.copy(newRoot)
- is org.jetbrains.dokka.model.doc.Suppress -> acc.copy(newRoot)
- }
- }
- }
-}
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt
index 99fba9f7..9f10873b 100644
--- a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt
+++ b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt
@@ -5,21 +5,27 @@ import org.jetbrains.dokka.model.DModule
import org.jetbrains.dokka.model.SourceSetDependent
import org.jetbrains.dokka.model.doc.DocumentationNode
import org.jetbrains.dokka.plugability.DokkaContext
+import org.jetbrains.dokka.plugability.plugin
+import org.jetbrains.dokka.plugability.querySingle
import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer
+import org.jetbrains.kotlin.analysis.kotlin.internal.InternalKotlinAnalysisPlugin
+import org.jetbrains.kotlin.analysis.kotlin.internal.ModuleAndPackageDocumentationReader
internal class ModuleAndPackageDocumentationTransformer(
private val moduleAndPackageDocumentationReader: ModuleAndPackageDocumentationReader
) : PreMergeDocumentableTransformer {
- constructor(context: DokkaContext) : this(ModuleAndPackageDocumentationReader(context))
+ constructor(context: DokkaContext) : this(
+ context.plugin<InternalKotlinAnalysisPlugin>().querySingle { moduleAndPackageDocumentationReader }
+ )
override fun invoke(modules: List<DModule>): List<DModule> {
return modules.map { module ->
module.copy(
- documentation = module.documentation + moduleAndPackageDocumentationReader[module],
+ documentation = module.documentation + moduleAndPackageDocumentationReader.read(module),
packages = module.packages.map { pkg ->
pkg.copy(
- documentation = pkg.documentation + moduleAndPackageDocumentationReader[pkg]
+ documentation = pkg.documentation + moduleAndPackageDocumentationReader.read(pkg)
)
}
)
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/ReportUndocumentedTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/ReportUndocumentedTransformer.kt
index ad9e34df..3368ded1 100644
--- a/plugins/base/src/main/kotlin/transformers/documentables/ReportUndocumentedTransformer.kt
+++ b/plugins/base/src/main/kotlin/transformers/documentables/ReportUndocumentedTransformer.kt
@@ -2,14 +2,12 @@ package org.jetbrains.dokka.base.transformers.documentables
import org.jetbrains.dokka.DokkaConfiguration
import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
-import org.jetbrains.dokka.analysis.DescriptorDocumentableSource
import org.jetbrains.dokka.model.*
import org.jetbrains.dokka.plugability.DokkaContext
+import org.jetbrains.dokka.plugability.plugin
+import org.jetbrains.dokka.plugability.querySingle
import org.jetbrains.dokka.transformers.documentation.DocumentableTransformer
-import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
-import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERRIDE
-import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED
-import org.jetbrains.kotlin.utils.addToStdlib.safeAs
+import org.jetbrains.kotlin.analysis.kotlin.internal.InternalKotlinAnalysisPlugin
internal class ReportUndocumentedTransformer : DocumentableTransformer {
@@ -19,14 +17,14 @@ internal class ReportUndocumentedTransformer : DocumentableTransformer {
private fun invoke(documentable: Documentable, context: DokkaContext) {
documentable.sourceSets.forEach { sourceSet ->
- if (shouldBeReportedIfNotDocumented(documentable, sourceSet)) {
+ if (shouldBeReportedIfNotDocumented(documentable, sourceSet, context)) {
reportIfUndocumented(context, documentable, sourceSet)
}
}
}
private fun shouldBeReportedIfNotDocumented(
- documentable: Documentable, sourceSet: DokkaSourceSet
+ documentable: Documentable, sourceSet: DokkaSourceSet, context: DokkaContext
): Boolean {
val packageOptionsOrNull = packageOptionsOrNull(sourceSet, documentable)
@@ -42,11 +40,8 @@ internal class ReportUndocumentedTransformer : DocumentableTransformer {
return false
}
- if (isFakeOverride(documentable, sourceSet)) {
- return false
- }
-
- if (isSynthesized(documentable, sourceSet)) {
+ val syntheticDetector = context.plugin<InternalKotlinAnalysisPlugin>().querySingle { syntheticDocumentableDetector }
+ if (syntheticDetector.isSynthetic(documentable, sourceSet)) {
return false
}
@@ -118,28 +113,8 @@ internal class ReportUndocumentedTransformer : DocumentableTransformer {
return documentable.isConstructor
}
- private fun isFakeOverride(documentable: Documentable, sourceSet: DokkaSourceSet): Boolean {
- return callableMemberDescriptorOrNull(documentable, sourceSet)?.kind == FAKE_OVERRIDE
- }
-
- private fun isSynthesized(documentable: Documentable, sourceSet: DokkaSourceSet): Boolean {
- return callableMemberDescriptorOrNull(documentable, sourceSet)?.kind == SYNTHESIZED
- }
-
- private fun callableMemberDescriptorOrNull(
- documentable: Documentable, sourceSet: DokkaSourceSet
- ): CallableMemberDescriptor? {
- if (documentable is WithSources) {
- return documentable.sources[sourceSet]
- .safeAs<DescriptorDocumentableSource>()?.descriptor
- .safeAs<CallableMemberDescriptor>()
- }
-
- return null
- }
-
private fun isPrivateOrInternalApi(documentable: Documentable, sourceSet: DokkaSourceSet): Boolean {
- return when (documentable.safeAs<WithVisibility>()?.visibility?.get(sourceSet)) {
+ return when ((documentable as? WithVisibility)?.visibility?.get(sourceSet)) {
KotlinVisibility.Public -> false
KotlinVisibility.Private -> true
KotlinVisibility.Protected -> true
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/SuppressTagDocumentableFilter.kt b/plugins/base/src/main/kotlin/transformers/documentables/SuppressTagDocumentableFilter.kt
index a297908d..2d65e98b 100644
--- a/plugins/base/src/main/kotlin/transformers/documentables/SuppressTagDocumentableFilter.kt
+++ b/plugins/base/src/main/kotlin/transformers/documentables/SuppressTagDocumentableFilter.kt
@@ -2,11 +2,11 @@ package org.jetbrains.dokka.base.transformers.documentables
import org.jetbrains.dokka.model.Documentable
import org.jetbrains.dokka.model.dfs
-import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.model.doc.Suppress
+import org.jetbrains.dokka.plugability.DokkaContext
class SuppressTagDocumentableFilter(val dokkaContext: DokkaContext) :
SuppressedByConditionDocumentableFilterTransformer(dokkaContext) {
override fun shouldBeSuppressed(d: Documentable): Boolean =
d.documentation.any { (_, docs) -> docs.dfs { it is Suppress } != null }
-} \ No newline at end of file
+}
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/utils/FullClassHierarchyBuilder.kt b/plugins/base/src/main/kotlin/transformers/documentables/utils/FullClassHierarchyBuilder.kt
deleted file mode 100644
index d657fa32..00000000
--- a/plugins/base/src/main/kotlin/transformers/documentables/utils/FullClassHierarchyBuilder.kt
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.jetbrains.dokka.base.transformers.documentables.utils
-
-import com.intellij.psi.PsiClass
-import kotlinx.coroutines.*
-import org.jetbrains.dokka.analysis.DescriptorDocumentableSource
-import org.jetbrains.dokka.analysis.PsiDocumentableSource
-import org.jetbrains.dokka.analysis.from
-import org.jetbrains.dokka.links.DRI
-import org.jetbrains.dokka.model.*
-import org.jetbrains.dokka.utilities.parallelForEach
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
-import org.jetbrains.kotlin.types.KotlinType
-import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes
-import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
-import java.util.concurrent.ConcurrentHashMap
-
-typealias Supertypes = List<DRI>
-typealias ClassHierarchy = SourceSetDependent<Map<DRI, Supertypes>>
-
-class FullClassHierarchyBuilder {
- suspend operator fun invoke(original: DModule): ClassHierarchy = coroutineScope {
- val map = original.sourceSets.associateWith { ConcurrentHashMap<DRI, List<DRI>>() }
- original.packages.parallelForEach { visitDocumentable(it, map) }
- map
- }
-
- private suspend fun collectSupertypesFromKotlinType(
- driWithKType: Pair<DRI, KotlinType>,
- supersMap: MutableMap<DRI, Supertypes>
- ): Unit = coroutineScope {
- val (dri, kotlinType) = driWithKType
- val supertypes = kotlinType.immediateSupertypes().filterNot { it.isAnyOrNullableAny() }
- val supertypesDriWithKType = supertypes.mapNotNull { supertype ->
- supertype.constructor.declarationDescriptor?.let {
- DRI.from(it) to supertype
- }
- }
-
- if (supersMap[dri] == null) {
- // another thread can rewrite the same value, but it isn't a problem
- supersMap[dri] = supertypesDriWithKType.map { it.first }
- supertypesDriWithKType.parallelForEach { collectSupertypesFromKotlinType(it, supersMap) }
- }
- }
-
- private suspend fun collectSupertypesFromPsiClass(
- driWithPsiClass: Pair<DRI, PsiClass>,
- supersMap: MutableMap<DRI, Supertypes>
- ): Unit = coroutineScope {
- val (dri, psiClass) = driWithPsiClass
- val supertypes = psiClass.superTypes.mapNotNull { it.resolve() }
- .filterNot { it.qualifiedName == "java.lang.Object" }
- val supertypesDriWithPsiClass = supertypes.map { DRI.from(it) to it }
-
- if (supersMap[dri] == null) {
- // another thread can rewrite the same value, but it isn't a problem
- supersMap[dri] = supertypesDriWithPsiClass.map { it.first }
- supertypesDriWithPsiClass.parallelForEach { collectSupertypesFromPsiClass(it, supersMap) }
- }
- }
-
- private suspend fun visitDocumentable(
- documentable: Documentable,
- hierarchy: SourceSetDependent<MutableMap<DRI, List<DRI>>>
- ): Unit = coroutineScope {
- if (documentable is WithScope) {
- documentable.classlikes.parallelForEach { visitDocumentable(it, hierarchy) }
- }
- if (documentable is DClasslike) {
- // to build a full class graph, using supertypes from Documentable
- // is not enough since it keeps only one level of hierarchy
- documentable.sources.forEach { (sourceSet, source) ->
- if (source is DescriptorDocumentableSource) {
- val descriptor = source.descriptor as ClassDescriptor
- val type = descriptor.defaultType
- hierarchy[sourceSet]?.let { collectSupertypesFromKotlinType(documentable.dri to type, it) }
- } else if (source is PsiDocumentableSource) {
- val psi = source.psi as PsiClass
- hierarchy[sourceSet]?.let { collectSupertypesFromPsiClass(documentable.dri to psi, it) }
- }
- }
- }
- }
-} \ No newline at end of file