From 3f2a790190da4f40ea6d8a976aa1929b2a1b002b Mon Sep 17 00:00:00 2001 From: Błażej Kardyś Date: Tue, 5 May 2020 17:45:12 +0200 Subject: Changing approach from platform-driven to source-set-driven --- core/src/main/kotlin/DokkaGenerator.kt | 36 ++--- core/src/main/kotlin/configuration.kt | 6 +- core/src/main/kotlin/defaultConfiguration.kt | 2 + core/src/main/kotlin/model/Documentable.kt | 168 +++++++++------------ core/src/main/kotlin/model/SourceSetData.kt | 23 +++ core/src/main/kotlin/model/aditionalExtras.kt | 4 +- core/src/main/kotlin/model/documentableUtils.kt | 15 +- core/src/main/kotlin/pages/ContentNodes.kt | 29 ++-- core/src/main/kotlin/pages/PageNodes.kt | 5 +- core/src/main/kotlin/plugability/DokkaContext.kt | 14 +- .../PreMergeDocumentableTransformer.kt | 2 +- .../sources/SourceToDocumentableTranslator.kt | 4 +- 12 files changed, 156 insertions(+), 152 deletions(-) create mode 100644 core/src/main/kotlin/model/SourceSetData.kt (limited to 'core/src') diff --git a/core/src/main/kotlin/DokkaGenerator.kt b/core/src/main/kotlin/DokkaGenerator.kt index 053b4cb6..6e62c033 100644 --- a/core/src/main/kotlin/DokkaGenerator.kt +++ b/core/src/main/kotlin/DokkaGenerator.kt @@ -1,23 +1,20 @@ package org.jetbrains.dokka -import com.intellij.openapi.vfs.VirtualFileManager -import com.intellij.psi.PsiJavaFile -import com.intellij.psi.PsiManager import org.jetbrains.dokka.analysis.AnalysisEnvironment import org.jetbrains.dokka.analysis.DokkaResolutionFacade import org.jetbrains.dokka.model.DModule -import org.jetbrains.dokka.pages.PlatformData +import org.jetbrains.dokka.model.SourceSetCache +import org.jetbrains.dokka.model.SourceSetData +import org.jetbrains.dokka.model.sourceSet import org.jetbrains.dokka.pages.RootPageNode import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.plugability.DokkaPlugin import org.jetbrains.dokka.utilities.DokkaLogger -import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.common.messages.MessageRenderer import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment -import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot import org.jetbrains.kotlin.utils.PathUtil import java.io.File @@ -31,13 +28,14 @@ class DokkaGenerator( ) { fun generate() = timed { report("Setting up analysis environments") - val platforms: Map = setUpAnalysis(configuration) + val sourceSetsCache = SourceSetCache() + val sourceSets: Map = setUpAnalysis(configuration, sourceSetsCache) report("Initializing plugins") - val context = initializePlugins(configuration, logger, platforms) + val context = initializePlugins(configuration, logger, sourceSets, sourceSetsCache) report("Creating documentation models") - val modulesFromPlatforms = createDocumentationModels(platforms, context) + val modulesFromPlatforms = createDocumentationModels(sourceSets, context) report("Transforming documentation model before merging") val transformedDocumentationBeforeMerge = transformDocumentationModelBeforeMerge(modulesFromPlatforms, context) @@ -62,27 +60,31 @@ class DokkaGenerator( logger.report() }.dump("\n\n === TIME MEASUREMENT ===\n") - fun setUpAnalysis(configuration: DokkaConfiguration): Map = + fun setUpAnalysis( + configuration: DokkaConfiguration, + sourceSetsCache: SourceSetCache + ): Map = configuration.passesConfigurations.map { - it.platformData to createEnvironmentAndFacade(it) + sourceSetsCache.getSourceSet(it) to createEnvironmentAndFacade(it) }.toMap() fun initializePlugins( configuration: DokkaConfiguration, logger: DokkaLogger, - platforms: Map, + sourceSets: Map, + sourceSetsCache: SourceSetCache, pluginOverrides: List = emptyList() - ) = DokkaContext.create(configuration, logger, platforms, pluginOverrides) + ) = DokkaContext.create(configuration, logger, sourceSets, sourceSetsCache, pluginOverrides) fun createDocumentationModels( - platforms: Map, + platforms: Map, context: DokkaContext ) = platforms.flatMap { (pdata, _) -> translateSources(pdata, context) } fun transformDocumentationModelBeforeMerge( modulesFromPlatforms: List, context: DokkaContext - ) = context[CoreExtensions.preMergeDocumentableTransformer].fold(modulesFromPlatforms) { acc, t -> t(acc, context) } + ) = context[CoreExtensions.preMergeDocumentableTransformer].fold(modulesFromPlatforms) { acc, t -> t(acc) } fun mergeDocumentationModels( modulesFromPlatforms: List, @@ -119,7 +121,7 @@ class DokkaGenerator( } pass.classpath.forEach { addClasspath(File(it)) } - addSources(pass.sourceRoots.map { it.path }) + addSources((pass.sourceRoots + pass.dependentSourceRoots).map { it.path }) loadLanguageVersionSettings(pass.languageVersion, pass.apiVersion) @@ -128,7 +130,7 @@ class DokkaGenerator( EnvironmentAndFacade(environment, facade) } - private fun translateSources(platformData: PlatformData, context: DokkaContext) = + private fun translateSources(platformData: SourceSetData, context: DokkaContext) = context[CoreExtensions.sourceToDocumentableTranslator].map { it.invoke(platformData, context) } diff --git a/core/src/main/kotlin/configuration.kt b/core/src/main/kotlin/configuration.kt index 34671c4e..88924924 100644 --- a/core/src/main/kotlin/configuration.kt +++ b/core/src/main/kotlin/configuration.kt @@ -1,6 +1,5 @@ package org.jetbrains.dokka -import org.jetbrains.dokka.pages.PlatformData import java.io.File import java.net.URL @@ -37,8 +36,10 @@ interface DokkaConfiguration { interface PassConfiguration { val moduleName: String + val sourceSetName: String val classpath: List val sourceRoots: List + val dependentSourceRoots: List val samples: List val includes: List val includeNonPublic: Boolean @@ -59,9 +60,6 @@ interface DokkaConfiguration { val analysisPlatform: Platform val targets: List val sinceKotlin: String? - - val platformData: PlatformData - get() = PlatformData(moduleName, analysisPlatform, targets) } interface SourceRoot { diff --git a/core/src/main/kotlin/defaultConfiguration.kt b/core/src/main/kotlin/defaultConfiguration.kt index ae674ea1..08f70b45 100644 --- a/core/src/main/kotlin/defaultConfiguration.kt +++ b/core/src/main/kotlin/defaultConfiguration.kt @@ -16,8 +16,10 @@ data class DokkaConfigurationImpl( data class PassConfigurationImpl ( override val moduleName: String, + override val sourceSetName: String, override val classpath: List, override val sourceRoots: List, + override val dependentSourceRoots: List, override val samples: List, override val includes: List, override val includeNonPublic: Boolean, diff --git a/core/src/main/kotlin/model/Documentable.kt b/core/src/main/kotlin/model/Documentable.kt index 313f4cd4..85487725 100644 --- a/core/src/main/kotlin/model/Documentable.kt +++ b/core/src/main/kotlin/model/Documentable.kt @@ -1,11 +1,12 @@ package org.jetbrains.dokka.model import com.intellij.psi.PsiNamedElement +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.Platform import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.doc.DocumentationNode import org.jetbrains.dokka.model.properties.PropertyContainer import org.jetbrains.dokka.model.properties.WithExtraProperties -import org.jetbrains.dokka.pages.PlatformData import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.load.kotlin.toSourceElement @@ -13,8 +14,9 @@ abstract class Documentable { abstract val name: String? abstract val dri: DRI abstract val children: List - abstract val documentation: PlatformDependent - abstract val platformData: List + abstract val documentation: SourceSetDependent + abstract val sourceSets: List + abstract val expectPresentInSet: SourceSetData? override fun toString(): String = "${javaClass.simpleName}($dri)" @@ -25,45 +27,10 @@ abstract class Documentable { override fun hashCode() = dri.hashCode() } -data class PlatformDependent( - val map: Map, - val expect: T? = null -) : Map by map { - val prevalentValue: T? - get() = map.values.distinct().singleOrNull() - - val allValues: Sequence = sequence { - expect?.also { yield(it) } - yieldAll(map.values) - } - - val allEntries: Sequence> = sequence { - expect?.also { yield(null to it) } - map.forEach { (k, v) -> yield(k to v) } - } - - fun getOrExpect(platform: PlatformData): T? = map[platform] ?: expect - - companion object { - fun empty(): PlatformDependent = PlatformDependent(emptyMap()) - - fun from(platformData: PlatformData, element: T) = PlatformDependent(mapOf(platformData to element)) - - @Suppress("UNCHECKED_CAST") - fun from(pairs: Iterable>) = - PlatformDependent( - pairs.filter { it.first != null }.toMap() as Map, - pairs.firstOrNull { it.first == null }?.second - ) - - fun from(vararg pairs: Pair) = from(pairs.asIterable()) - - fun expectFrom(element: T) = PlatformDependent(map = emptyMap(), expect = element) - } -} +typealias SourceSetDependent = Map interface WithExpectActual { - val sources: PlatformDependent + val sources: SourceSetDependent } interface WithScope { @@ -73,7 +40,7 @@ interface WithScope { } interface WithVisibility { - val visibility: PlatformDependent + val visibility: SourceSetDependent } interface WithType { @@ -81,7 +48,7 @@ interface WithType { } interface WithAbstraction { - val modifier: PlatformDependent + val modifier: SourceSetDependent } sealed class Modifier(val name: String) @@ -112,7 +79,7 @@ interface WithGenerics { } interface WithSupertypes { - val supertypes: PlatformDependent> + val supertypes: SourceSetDependent> } interface Callable : WithVisibility, WithType, WithAbstraction, WithExpectActual { @@ -124,8 +91,9 @@ sealed class DClasslike : Documentable(), WithScope, WithVisibility, WithExpectA data class DModule( override val name: String, val packages: List, - override val documentation: PlatformDependent, - override val platformData: List, + override val documentation: SourceSetDependent, + override val expectPresentInSet: SourceSetData? = null, + override val sourceSets: List, override val extra: PropertyContainer = PropertyContainer.empty() ) : Documentable(), WithExtraProperties { override val dri: DRI = DRI.topLevel @@ -141,8 +109,9 @@ data class DPackage( override val properties: List, override val classlikes: List, val typealiases: List, - override val documentation: PlatformDependent, - override val platformData: List, + override val documentation: SourceSetDependent, + override val expectPresentInSet: SourceSetData? = null, + override val sourceSets: List, override val extra: PropertyContainer = PropertyContainer.empty() ) : Documentable(), WithScope, WithExtraProperties { override val name = dri.packageName.orEmpty() @@ -159,14 +128,15 @@ data class DClass( override val functions: List, override val properties: List, override val classlikes: List, - override val sources: PlatformDependent, - override val visibility: PlatformDependent, + override val sources: SourceSetDependent, + override val visibility: SourceSetDependent, override val companion: DObject?, override val generics: List, - override val supertypes: PlatformDependent>, - override val documentation: PlatformDependent, - override val modifier: PlatformDependent, - override val platformData: List, + override val supertypes: SourceSetDependent>, + override val documentation: SourceSetDependent, + override val expectPresentInSet: SourceSetData?, + override val modifier: SourceSetDependent, + override val sourceSets: List, override val extra: PropertyContainer = PropertyContainer.empty() ) : DClasslike(), WithAbstraction, WithCompanion, WithConstructors, WithGenerics, WithSupertypes, WithExtraProperties { @@ -181,16 +151,17 @@ data class DEnum( override val dri: DRI, override val name: String, val entries: List, - override val documentation: PlatformDependent, - override val sources: PlatformDependent, + override val documentation: SourceSetDependent, + override val expectPresentInSet: SourceSetData?, + override val sources: SourceSetDependent, override val functions: List, override val properties: List, override val classlikes: List, - override val visibility: PlatformDependent, + override val visibility: SourceSetDependent, override val companion: DObject?, override val constructors: List, - override val supertypes: PlatformDependent>, - override val platformData: List, + override val supertypes: SourceSetDependent>, + override val sourceSets: List, override val extra: PropertyContainer = PropertyContainer.empty() ) : DClasslike(), WithCompanion, WithConstructors, WithSupertypes, WithExtraProperties { override val children: List @@ -202,11 +173,12 @@ data class DEnum( data class DEnumEntry( override val dri: DRI, override val name: String, - override val documentation: PlatformDependent, + override val documentation: SourceSetDependent, + override val expectPresentInSet: SourceSetData?, override val functions: List, override val properties: List, override val classlikes: List, - override val platformData: List, + override val sourceSets: List, override val extra: PropertyContainer = PropertyContainer.empty() ) : Documentable(), WithScope, WithExtraProperties { override val children: List @@ -220,14 +192,15 @@ data class DFunction( override val name: String, val isConstructor: Boolean, val parameters: List, - override val documentation: PlatformDependent, - override val sources: PlatformDependent, - override val visibility: PlatformDependent, + override val documentation: SourceSetDependent, + override val expectPresentInSet: SourceSetData?, + override val sources: SourceSetDependent, + override val visibility: SourceSetDependent, override val type: Bound, override val generics: List, override val receiver: DParameter?, - override val modifier: PlatformDependent, - override val platformData: List, + override val modifier: SourceSetDependent, + override val sourceSets: List, override val extra: PropertyContainer = PropertyContainer.empty() ) : Documentable(), Callable, WithGenerics, WithExtraProperties { override val children: List @@ -239,16 +212,17 @@ data class DFunction( data class DInterface( override val dri: DRI, override val name: String, - override val documentation: PlatformDependent, - override val sources: PlatformDependent, + override val documentation: SourceSetDependent, + override val expectPresentInSet: SourceSetData?, + override val sources: SourceSetDependent, override val functions: List, override val properties: List, override val classlikes: List, - override val visibility: PlatformDependent, + override val visibility: SourceSetDependent, override val companion: DObject?, override val generics: List, - override val supertypes: PlatformDependent>, - override val platformData: List, + override val supertypes: SourceSetDependent>, + override val sourceSets: List, override val extra: PropertyContainer = PropertyContainer.empty() ) : DClasslike(), WithCompanion, WithGenerics, WithSupertypes, WithExtraProperties { override val children: List @@ -260,14 +234,15 @@ data class DInterface( data class DObject( override val name: String?, override val dri: DRI, - override val documentation: PlatformDependent, - override val sources: PlatformDependent, + override val documentation: SourceSetDependent, + override val expectPresentInSet: SourceSetData?, + override val sources: SourceSetDependent, override val functions: List, override val properties: List, override val classlikes: List, - override val visibility: PlatformDependent, - override val supertypes: PlatformDependent>, - override val platformData: List, + override val visibility: SourceSetDependent, + override val supertypes: SourceSetDependent>, + override val sourceSets: List, override val extra: PropertyContainer = PropertyContainer.empty() ) : DClasslike(), WithSupertypes, WithExtraProperties { override val children: List @@ -279,15 +254,16 @@ data class DObject( data class DAnnotation( override val name: String, override val dri: DRI, - override val documentation: PlatformDependent, - override val sources: PlatformDependent, + override val documentation: SourceSetDependent, + override val expectPresentInSet: SourceSetData?, + override val sources: SourceSetDependent, override val functions: List, override val properties: List, override val classlikes: List, - override val visibility: PlatformDependent, + override val visibility: SourceSetDependent, override val companion: DObject?, override val constructors: List, - override val platformData: List, + override val sourceSets: List, override val extra: PropertyContainer = PropertyContainer.empty() ) : DClasslike(), WithCompanion, WithConstructors, WithExtraProperties { override val children: List @@ -299,15 +275,16 @@ data class DAnnotation( data class DProperty( override val dri: DRI, override val name: String, - override val documentation: PlatformDependent, - override val sources: PlatformDependent, - override val visibility: PlatformDependent, + override val documentation: SourceSetDependent, + override val expectPresentInSet: SourceSetData?, + override val sources: SourceSetDependent, + override val visibility: SourceSetDependent, override val type: Bound, override val receiver: DParameter?, val setter: DFunction?, val getter: DFunction?, - override val modifier: PlatformDependent, - override val platformData: List, + override val modifier: SourceSetDependent, + override val sourceSets: List, override val generics: List, override val extra: PropertyContainer = PropertyContainer.empty() ) : Documentable(), Callable, WithExtraProperties, WithGenerics { @@ -321,9 +298,10 @@ data class DProperty( data class DParameter( override val dri: DRI, override val name: String?, - override val documentation: PlatformDependent, + override val documentation: SourceSetDependent, + override val expectPresentInSet: SourceSetData?, val type: Bound, - override val platformData: List, + override val sourceSets: List, override val extra: PropertyContainer = PropertyContainer.empty() ) : Documentable(), WithExtraProperties { override val children: List @@ -335,9 +313,10 @@ data class DParameter( data class DTypeParameter( override val dri: DRI, override val name: String, - override val documentation: PlatformDependent, + override val documentation: SourceSetDependent, + override val expectPresentInSet: SourceSetData?, val bounds: List, - override val platformData: List, + override val sourceSets: List, override val extra: PropertyContainer = PropertyContainer.empty() ) : Documentable(), WithExtraProperties { override val children: List @@ -350,10 +329,11 @@ data class DTypeAlias( override val dri: DRI, override val name: String, override val type: Bound, - val underlyingType: PlatformDependent, - override val visibility: PlatformDependent, - override val documentation: PlatformDependent, - override val platformData: List, + val underlyingType: SourceSetDependent, + override val visibility: SourceSetDependent, + override val documentation: SourceSetDependent, + override val expectPresentInSet: SourceSetData?, + override val sourceSets: List, override val extra: PropertyContainer = PropertyContainer.empty() ) : Documentable(), WithType, WithVisibility, WithExtraProperties { override val children: List @@ -417,7 +397,7 @@ sealed class JavaVisibility(name: String) : Visibility(name) { object Default : JavaVisibility("") } -fun PlatformDependent?.orEmpty(): PlatformDependent = this ?: PlatformDependent.empty() +fun SourceSetDependent?.orEmpty(): SourceSetDependent = this ?: emptyMap() interface DocumentableSource { val path: String @@ -429,4 +409,4 @@ class DescriptorDocumentableSource(val descriptor: DeclarationDescriptor) : Docu class PsiDocumentableSource(val psi: PsiNamedElement) : DocumentableSource { override val path = psi.containingFile.virtualFile.path -} +} \ No newline at end of file diff --git a/core/src/main/kotlin/model/SourceSetData.kt b/core/src/main/kotlin/model/SourceSetData.kt new file mode 100644 index 00000000..8f67f272 --- /dev/null +++ b/core/src/main/kotlin/model/SourceSetData.kt @@ -0,0 +1,23 @@ +package org.jetbrains.dokka.model + +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.Platform +import org.jetbrains.dokka.plugability.DokkaContext + +data class SourceSetData( + val moduleName: String, + val sourceSetName: String, + val platform: Platform, + val sourceRoots: List = emptyList() +) + +class SourceSetCache { + private val sourceSets = HashMap() + + fun getSourceSet(pass: DokkaConfiguration.PassConfiguration) = + sourceSets.getOrPut("${pass.moduleName}/${pass.sourceSetName}", + { SourceSetData(pass.moduleName, pass.sourceSetName, pass.analysisPlatform, pass.sourceRoots) } + ) +} + +fun DokkaContext.sourceSet(pass: DokkaConfiguration.PassConfiguration) : SourceSetData = sourceSetCache.getSourceSet(pass) \ No newline at end of file diff --git a/core/src/main/kotlin/model/aditionalExtras.kt b/core/src/main/kotlin/model/aditionalExtras.kt index 58209939..27ad8a55 100644 --- a/core/src/main/kotlin/model/aditionalExtras.kt +++ b/core/src/main/kotlin/model/aditionalExtras.kt @@ -41,13 +41,13 @@ object PrimaryConstructorExtra : ExtraProperty, ExtraProperty.Key = this } -data class ActualTypealias(val underlyingType: PlatformDependent) : ExtraProperty { +data class ActualTypealias(val underlyingType: SourceSetDependent) : ExtraProperty { companion object : ExtraProperty.Key { override fun mergeStrategyFor( left: ActualTypealias, right: ActualTypealias ) = - MergeStrategy.Replace(ActualTypealias(PlatformDependent(left.underlyingType + right.underlyingType))) + MergeStrategy.Replace(ActualTypealias(left.underlyingType + right.underlyingType)) } override val key: ExtraProperty.Key = ActualTypealias diff --git a/core/src/main/kotlin/model/documentableUtils.kt b/core/src/main/kotlin/model/documentableUtils.kt index 7f946344..b09260ee 100644 --- a/core/src/main/kotlin/model/documentableUtils.kt +++ b/core/src/main/kotlin/model/documentableUtils.kt @@ -1,21 +1,18 @@ package org.jetbrains.dokka.model -import org.jetbrains.dokka.pages.PlatformData +fun SourceSetDependent.filtered(platformDataList: List) = filter { it.key in platformDataList } +fun SourceSetData?.filtered(platformDataList: List) = takeIf { this in platformDataList } -fun PlatformDependent.filtered(platformDataList: List) = PlatformDependent( - map.filter { it.key in platformDataList }, - expect -) - -fun DTypeParameter.filter(filteredData: List) = - if (filteredData.containsAll(platformData)) this +fun DTypeParameter.filter(filteredData: List) = + if (filteredData.containsAll(sourceSets)) this else { - val intersection = filteredData.intersect(platformData).toList() + val intersection = filteredData.intersect(sourceSets).toList() if (intersection.isEmpty()) null else DTypeParameter( dri, name, documentation.filtered(intersection), + expectPresentInSet?.takeIf { intersection.contains(expectPresentInSet) }, bounds, intersection, extra diff --git a/core/src/main/kotlin/pages/ContentNodes.kt b/core/src/main/kotlin/pages/ContentNodes.kt index 26bcdf77..bb669199 100644 --- a/core/src/main/kotlin/pages/ContentNodes.kt +++ b/core/src/main/kotlin/pages/ContentNodes.kt @@ -1,6 +1,7 @@ package org.jetbrains.dokka.pages import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.model.SourceSetData import org.jetbrains.dokka.model.properties.PropertyContainer import org.jetbrains.dokka.model.properties.WithExtraProperties @@ -10,7 +11,7 @@ data class DCI(val dri: Set, val kind: Kind) { interface ContentNode : WithExtraProperties { val dci: DCI - val platforms: Set + val sourceSets: Set val style: Set