diff options
51 files changed, 527 insertions, 378 deletions
diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 1d61e410..fc62b73d 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -6,12 +6,9 @@ plugins { } dependencies { - api(project(":coreDependencies", configuration = "shadow")) + api(project("dependencies", configuration = "shadow")) - val kotlin_version: String by project - api("org.jetbrains.kotlin:kotlin-compiler:$kotlin_version") - implementation("org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version") - implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlin_version") + implementation(kotlin("reflect")) implementation("com.google.code.gson:gson:2.8.5") implementation("org.jsoup:jsoup:1.12.1") diff --git a/core/dependencies/build.gradle.kts b/core/dependencies/build.gradle.kts new file mode 100644 index 00000000..a26d109e --- /dev/null +++ b/core/dependencies/build.gradle.kts @@ -0,0 +1,40 @@ +import org.jetbrains.configureBintrayPublication + +plugins { + id("com.github.johnrengelman.shadow") + `maven-publish` + id("com.jfrog.bintray") +} + +repositories { + maven(url = "https://kotlin.bintray.com/kotlin-plugin") +} + +dependencies { + // TODO (see https://github.com/Kotlin/dokka/issues/1009) + implementation(kotlin("stdlib")) + implementation(kotlin("reflect")) + + implementation("org.jetbrains:markdown:0.1.41") { + because("it's published only on bintray") + } +} + +tasks { + shadowJar { + val dokka_version: String by project + archiveFileName.set("dokka-dependencies-$dokka_version.jar") + archiveClassifier.set("") + } +} + +publishing { + publications { + register<MavenPublication>("dokkaCoreDependencies") { + artifactId = "dokka-core-dependencies" + project.shadow.component(this) + } + } +} + +configureBintrayPublication("dokkaCoreDependencies") diff --git a/core/src/main/kotlin/DokkaGenerator.kt b/core/src/main/kotlin/DokkaGenerator.kt index b2e572d4..b88c6223 100644 --- a/core/src/main/kotlin/DokkaGenerator.kt +++ b/core/src/main/kotlin/DokkaGenerator.kt @@ -1,7 +1,5 @@ package org.jetbrains.dokka -import org.jetbrains.dokka.analysis.AnalysisEnvironment -import org.jetbrains.dokka.analysis.DokkaResolutionFacade import org.jetbrains.dokka.model.DModule import org.jetbrains.dokka.model.SourceSetCache import org.jetbrains.dokka.model.SourceSetData @@ -9,13 +7,7 @@ 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.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.utils.PathUtil -import java.io.File + /** * DokkaGenerator is the main entry point for generating documentation @@ -26,15 +18,13 @@ class DokkaGenerator( private val logger: DokkaLogger ) { fun generate() = timed { - report("Setting up analysis environments") val sourceSetsCache = SourceSetCache() - val sourceSets: Map<SourceSetData, EnvironmentAndFacade> = setUpAnalysis(configuration, sourceSetsCache) report("Initializing plugins") - val context = initializePlugins(configuration, logger, sourceSets, sourceSetsCache) + val context = initializePlugins(configuration, logger, sourceSetsCache) report("Creating documentation models") - val modulesFromPlatforms = createDocumentationModels(sourceSets, context) + val modulesFromPlatforms = createDocumentationModels(context, sourceSetsCache) report("Transforming documentation model before merging") val transformedDocumentationBeforeMerge = transformDocumentationModelBeforeMerge(modulesFromPlatforms, context) @@ -59,9 +49,8 @@ class DokkaGenerator( fun generateAllModulesPage() = timed { val sourceSetsCache = SourceSetCache() - val sourceSets = emptyMap<SourceSetData, EnvironmentAndFacade>() report("Initializing plugins") - val context = initializePlugins(configuration, logger, sourceSets, sourceSetsCache) + val context = initializePlugins(configuration, logger, sourceSetsCache) report("Creating all modules page") val pages = createAllModulePage(context) @@ -73,26 +62,20 @@ class DokkaGenerator( render(transformedPages, context) }.dump("\n\n === TIME MEASUREMENT ===\n") - fun setUpAnalysis( - configuration: DokkaConfiguration, - sourceSetsCache: SourceSetCache - ): Map<SourceSetData, EnvironmentAndFacade> = - configuration.passesConfigurations.map { - sourceSetsCache.getSourceSet(it) to createEnvironmentAndFacade(configuration, it) - }.toMap() fun initializePlugins( configuration: DokkaConfiguration, logger: DokkaLogger, - sourceSets: Map<SourceSetData, EnvironmentAndFacade>, sourceSetsCache: SourceSetCache, pluginOverrides: List<DokkaPlugin> = emptyList() - ) = DokkaContext.create(configuration, logger, sourceSets, sourceSetsCache, pluginOverrides) + ) = DokkaContext.create(configuration, logger, sourceSetsCache, pluginOverrides) fun createDocumentationModels( - platforms: Map<SourceSetData, EnvironmentAndFacade>, - context: DokkaContext - ) = platforms.flatMap { (pdata, _) -> translateSources(pdata, context) } + context: DokkaContext, + sourceSetsCache: SourceSetCache + ) = context.configuration.passesConfigurations + .map { passConfiguration -> sourceSetsCache.getSourceSet(passConfiguration) } + .flatMap { passConfiguration -> translateSources(passConfiguration, context) } fun transformDocumentationModelBeforeMerge( modulesFromPlatforms: List<DModule>, @@ -150,56 +133,10 @@ class DokkaGenerator( } } - private fun createEnvironmentAndFacade( - configuration: DokkaConfiguration, - pass: DokkaConfiguration.PassConfiguration - ): EnvironmentAndFacade = - AnalysisEnvironment(DokkaMessageCollector(logger), pass.analysisPlatform).run { - if (analysisPlatform == Platform.jvm) { - addClasspath(PathUtil.getJdkClassesRootsFromCurrentJre()) - } - pass.classpath.forEach { addClasspath(File(it)) } - - addSources( - (pass.sourceRoots + configuration.passesConfigurations.filter { it.sourceSetID in pass.dependentSourceSets } - .flatMap { it.sourceRoots }) - .map { it.path } - ) - - loadLanguageVersionSettings(pass.languageVersion, pass.apiVersion) - - val environment = createCoreEnvironment() - val (facade, _) = createResolutionFacade(environment) - EnvironmentAndFacade(environment, facade) - } - private fun translateSources(platformData: SourceSetData, context: DokkaContext) = context[CoreExtensions.sourceToDocumentableTranslator].map { it.invoke(platformData, context) } - - class DokkaMessageCollector(private val logger: DokkaLogger) : MessageCollector { - override fun clear() { - seenErrors = false - } - - private var seenErrors = false - - override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) { - if (severity == CompilerMessageSeverity.ERROR) { - seenErrors = true - } - logger.info(MessageRenderer.PLAIN_FULL_PATHS.render(severity, message, location)) - } - - override fun hasErrors() = seenErrors - } -} - -// It is not data class due to ill-defined equals -class EnvironmentAndFacade(val environment: KotlinCoreEnvironment, val facade: DokkaResolutionFacade) { - operator fun component1() = environment - operator fun component2() = facade } private class Timer(startTime: Long, private val logger: DokkaLogger?) { diff --git a/core/src/main/kotlin/links/DRI.kt b/core/src/main/kotlin/links/DRI.kt index 9cc51fb7..3f6d886f 100644 --- a/core/src/main/kotlin/links/DRI.kt +++ b/core/src/main/kotlin/links/DRI.kt @@ -1,15 +1,5 @@ package org.jetbrains.dokka.links -import com.intellij.psi.* -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf -import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.TypeProjection -import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull - /** * [DRI] stands for DokkaResourceIdentifier */ @@ -21,33 +11,10 @@ data class DRI( val extra: String? = null ) { override fun toString(): String = - "${packageName.orEmpty()}/${classNames.orEmpty()}/${callable?.name.orEmpty()}/${callable?.signature().orEmpty()}/$target/${extra.orEmpty()}" + "${packageName.orEmpty()}/${classNames.orEmpty()}/${callable?.name.orEmpty()}/${callable?.signature() + .orEmpty()}/$target/${extra.orEmpty()}" companion object { - fun from(descriptor: DeclarationDescriptor) = descriptor.parentsWithSelf.run { - val callable = firstIsInstanceOrNull<CallableDescriptor>() - DRI( - firstIsInstanceOrNull<PackageFragmentDescriptor>()?.fqName?.asString(), - (filterIsInstance<ClassDescriptor>() + filterIsInstance<TypeAliasDescriptor>()).toList() - .takeIf { it.isNotEmpty() } - ?.asReversed() - ?.joinToString(separator = ".") { it.name.asString() }, - callable?.let { Callable.from(it) }, - DriTarget.from(descriptor) - ) - } - - fun from(psi: PsiElement) = psi.parentsWithSelf.run { - val psiMethod = firstIsInstanceOrNull<PsiMethod>() - val psiField = firstIsInstanceOrNull<PsiField>() - val classes = filterIsInstance<PsiClass>().toList() - DRI( - classes.lastOrNull()?.qualifiedName?.substringBeforeLast('.', ""), - classes.toList().takeIf { it.isNotEmpty() }?.asReversed()?.mapNotNull { it.name }?.joinToString("."), - psiMethod?.let { Callable.from(it) } ?: psiField?.let { Callable.from(it) } , - DriTarget.from(psi) - ) - } val topLevel = DRI() } } @@ -78,71 +45,11 @@ data class Callable( ) { fun signature() = "${receiver?.toString().orEmpty()}#${params.joinToString("#")}" - companion object { - fun from(descriptor: CallableDescriptor) = with(descriptor) { - Callable( - name.asString(), - extensionReceiverParameter?.let { TypeReference.from(it) }, - valueParameters.mapNotNull { TypeReference.from(it) } - ) - } - - fun from(psi: PsiMethod) = with(psi) { - Callable( - name, - null, - parameterList.parameters.map { param -> JavaClassReference(param.type.canonicalText) }) - } - - fun from(psi: PsiField): Callable { - return Callable( - name = psi.name, - receiver = null, - params = emptyList() - ) - } - } + companion object } sealed class TypeReference { - companion object { - fun from(d: ReceiverParameterDescriptor): TypeReference? = - when (d.value) { - is ExtensionReceiver -> fromPossiblyNullable(d.type) - else -> run { - println("Unknown value type for $d") - null - } - } - - fun from(d: ValueParameterDescriptor): TypeReference? = - fromPossiblyNullable(d.type) - - fun from(p: PsiClass) = TypeReference - - private fun fromPossiblyNullable(t: KotlinType, self: KotlinType? = null): TypeReference = - from(t, self).let { if (t.isMarkedNullable) Nullable(it) else it } - - private fun from(t: KotlinType, self: KotlinType? = null): TypeReference = - if (self is KotlinType && self.constructor == t.constructor && self.arguments == t.arguments) - SelfType - else when (val d = t.constructor.declarationDescriptor) { - is TypeParameterDescriptor -> TypeParam( - d.upperBounds.map { fromPossiblyNullable(it, self ?: t) } - ) - else -> TypeConstructor( - t.constructorName.orEmpty(), - t.arguments.map { fromProjection(it, self) } - ) - } - - private fun fromProjection(t: TypeProjection, r: KotlinType? = null): TypeReference = - if (t.isStarProjection) { - StarProjection - } else { - fromPossiblyNullable(t.type, r) - } - } + companion object } data class JavaClassReference(val name: String) : TypeReference() { @@ -171,39 +78,10 @@ object StarProjection : TypeReference() { override fun toString() = "*" } -private val KotlinType.constructorName - get() = constructor.declarationDescriptor?.fqNameSafe?.asString() - sealed class DriTarget { override fun toString(): String = this.javaClass.simpleName - companion object { - fun from(descriptor: DeclarationDescriptor): DriTarget = descriptor.parentsWithSelf.run { - return when (descriptor) { - is TypeParameterDescriptor -> PointingToGenericParameters(descriptor.index) - else -> { - val callable = firstIsInstanceOrNull<CallableDescriptor>() - val params = - callable?.let { listOfNotNull(it.extensionReceiverParameter) + it.valueParameters }.orEmpty() - val parameterDescriptor = firstIsInstanceOrNull<ParameterDescriptor>() - - parameterDescriptor?.let { PointingToCallableParameters(params.indexOf(it)) } - ?: PointingToDeclaration - } - } - } - - fun from(psi: PsiElement): DriTarget = psi.parentsWithSelf.run { - return when (psi) { - is PsiTypeParameter -> PointingToGenericParameters(psi.index) - else -> firstIsInstanceOrNull<PsiParameter>()?.let { - val callable = firstIsInstanceOrNull<PsiMethod>() - val params = (callable?.parameterList?.parameters).orEmpty() - PointingToCallableParameters(params.indexOf(it)) - } ?: PointingToDeclaration - } - } - } + companion object } data class PointingToGenericParameters(val parameterIndex: Int) : DriTarget() { diff --git a/core/src/main/kotlin/model/Documentable.kt b/core/src/main/kotlin/model/Documentable.kt index 90958210..768bddc5 100644 --- a/core/src/main/kotlin/model/Documentable.kt +++ b/core/src/main/kotlin/model/Documentable.kt @@ -1,12 +1,10 @@ package org.jetbrains.dokka.model -import com.intellij.psi.PsiNamedElement 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.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.load.kotlin.toSourceElement + abstract class Documentable { abstract val name: String? @@ -406,11 +404,3 @@ fun <T> SourceSetDependent<T>?.orEmpty(): SourceSetDependent<T> = this ?: emptyM interface DocumentableSource { val path: String } - -class DescriptorDocumentableSource(val descriptor: DeclarationDescriptor) : DocumentableSource { - override val path = descriptor.toSourceElement.containingFile.toString() -} - -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/properties/PropertyContainer.kt b/core/src/main/kotlin/model/properties/PropertyContainer.kt index 107bede5..e1e0250e 100644 --- a/core/src/main/kotlin/model/properties/PropertyContainer.kt +++ b/core/src/main/kotlin/model/properties/PropertyContainer.kt @@ -1,7 +1,5 @@ package org.jetbrains.dokka.model.properties -import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull - class PropertyContainer<C : Any> internal constructor( @PublishedApi internal val map: Map<ExtraProperty.Key<C, *>, ExtraProperty<C>> ) { @@ -45,7 +43,7 @@ fun <C> C.mergeExtras(left: C, right: C): C where C : Any, C : WithExtraProperti (l.key as ExtraProperty.Key<C, ExtraProperty<C>>).mergeStrategyFor(l, r) } - strategies.firstIsInstanceOrNull<MergeStrategy.Fail>()?.error?.invoke() + strategies.filterIsInstance<MergeStrategy.Fail>().firstOrNull()?.error?.invoke() val replaces: List<ExtraProperty<C>> = strategies.filterIsInstance<MergeStrategy.Replace<C>>().map { it.newProperty } diff --git a/core/src/main/kotlin/plugability/DokkaContext.kt b/core/src/main/kotlin/plugability/DokkaContext.kt index 692803dd..a2ff26c7 100644 --- a/core/src/main/kotlin/plugability/DokkaContext.kt +++ b/core/src/main/kotlin/plugability/DokkaContext.kt @@ -1,9 +1,7 @@ package org.jetbrains.dokka.plugability import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.EnvironmentAndFacade import org.jetbrains.dokka.model.SourceSetCache -import org.jetbrains.dokka.model.SourceSetData import org.jetbrains.dokka.utilities.DokkaLogger import java.io.File import java.net.URLClassLoader @@ -23,7 +21,6 @@ interface DokkaContext { val sourceSetCache: SourceSetCache val logger: DokkaLogger val configuration: DokkaConfiguration - val platforms: Map<SourceSetData, EnvironmentAndFacade> val unusedPoints: Collection<ExtensionPoint<*>> @@ -31,11 +28,10 @@ interface DokkaContext { fun create( configuration: DokkaConfiguration, logger: DokkaLogger, - sourceSets: Map<SourceSetData, EnvironmentAndFacade>, sourceSetsCache: SourceSetCache, pluginOverrides: List<DokkaPlugin> ): DokkaContext = - DokkaContextConfigurationImpl(logger, configuration, sourceSets, sourceSetsCache).apply { + DokkaContextConfigurationImpl(logger, configuration, sourceSetsCache).apply { // File(it.path) is a workaround for an incorrect filesystem in a File instance returned by Gradle. configuration.pluginsClasspath.map { File(it.path).toURI().toURL() } .toTypedArray() @@ -59,7 +55,6 @@ interface DokkaContextConfiguratio |
