From eae1ce49d18c2978b49166ea502bf2c109a85504 Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Sat, 18 Jul 2020 12:18:59 +0200 Subject: Simplify Dokka Gradle Plugin --- core/src/main/kotlin/DokkaBootstrapImpl.kt | 34 +-- core/src/main/kotlin/configuration.kt | 46 ++- core/src/main/kotlin/defaultConfiguration.kt | 25 +- core/src/main/kotlin/utilities/json.kt | 4 +- .../kotlin/utilities/DokkaConfigurationJsonTest.kt | 10 +- gradle/wrapper/gradle-wrapper.properties | 5 +- integration-tests/build.gradle.kts | 1 - .../gradle/projects/it-basic-groovy/build.gradle | 13 +- .../gradle/projects/it-basic/build.gradle.kts | 8 +- .../projects/it-multiplatform-0/build.gradle.kts | 12 - .../src/jvmMain/kotlin/it/mpp0/ExpectedClass.kt | 6 + .../src/jvmMain/kotlin/it/mpp0/JvmOnlyClass.kt | 13 + .../it/gradle/Android0GradleIntegrationTest.kt | 12 +- .../dokka/it/gradle/Multimodule0IntegrationTest.kt | 7 + .../jetbrains/dokka/it/AbstractIntegrationTest.kt | 3 + .../dokka/analysis/AnalysisEnvironment.kt | 11 +- .../dokka/analysis/EnvironmentAndFacade.kt | 4 +- .../kotlin/allModulePage/MultimodulePageCreator.kt | 7 +- .../base/src/main/kotlin/renderers/FileWriter.kt | 14 +- .../ModuleAndPackageDocumentationTransformer.kt | 6 +- .../SuppressedDocumentableFilterTransformer.kt | 2 +- .../pages/samples/SamplesTransformer.kt | 10 +- .../DefaultDescriptorToDocumentableTranslator.kt | 19 +- .../psi/DefaultPsiToDocumentableTranslator.kt | 47 +-- .../src/test/kotlin/expect/AbstractExpectTest.kt | 2 +- .../renderers/html/HtmlRenderingOnlyTestBase.kt | 2 +- .../src/test/kotlin/renderers/gfm/DivergentTest.kt | 3 +- .../renderers/gfm/GfmRenderingOnlyTestBase.kt | 4 +- .../dokka/javadoc/JavadocPackageTemplateMapTest.kt | 3 +- runners/cli/src/main/kotlin/cli/main.kt | 20 +- .../dokka/gradle/AbstractDokkaParentTask.kt | 73 +++++ .../jetbrains/dokka/gradle/AbstractDokkaTask.kt | 55 ++-- .../dokka/gradle/ConfigurationExtractor.kt | 185 ------------ .../dokka/gradle/DokkaBootstrapFactory.kt | 18 -- .../jetbrains/dokka/gradle/DokkaCollectorTask.kt | 73 ++--- .../jetbrains/dokka/gradle/DokkaMultimoduleTask.kt | 78 ++--- .../dokka/gradle/DokkaSourceSetIDFactory.kt | 10 - .../kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt | 315 ++------------------- .../dokka/gradle/GradleDokkaSourceSetBuilder.kt | 298 +++++++++++++++++++ .../GradleExternalDocumentationLinkBuilder.kt | 22 ++ .../dokka/gradle/GradlePackageOptionsBuilder.kt | 36 +++ .../dokka/gradle/GradleSourceLinkBuilder.kt | 25 ++ .../dokka/gradle/GradleSourceRootBuilder.kt | 15 + .../jetbrains/dokka/gradle/KotlinSourceSetGist.kt | 105 +++++++ .../org/jetbrains/dokka/gradle/ProxyUtils.kt | 43 --- .../org/jetbrains/dokka/gradle/ReflectDsl.kt | 72 ----- .../gradle/TaskDependencyInternalWithAdditions.kt | 20 ++ .../jetbrains/dokka/gradle/automagicTypedProxy.kt | 46 +++ .../dokka/gradle/configurationImplementations.kt | 259 ----------------- .../dokka/gradle/defaultDokkaOutputDirectory.kt | 13 - .../kotlin/org/jetbrains/dokka/gradle/dokka.kt | 7 + .../dokka/gradle/dokkaBootstrapFactory.kt | 21 ++ .../jetbrains/dokka/gradle/dokkaConfigurations.kt | 41 --- .../dokka/gradle/dokkaDefaultOutputDirectory.kt | 13 + .../dokka/gradle/dokkaSourceSetIDFactory.kt | 10 + .../jetbrains/dokka/gradle/gradleConfigurations.kt | 41 +++ .../main/kotlin/org/jetbrains/dokka/gradle/main.kt | 1 - .../gradle/sourceSetKotlinGistConfiguration.kt | 21 ++ .../kotlin/org/jetbrains/dokka/gradle/utils.kt | 12 + .../dokka/gradle/AbstractDokkaParentTaskTest.kt | 107 +++++++ .../dokka/gradle/DokkaCollectorTaskTest.kt | 60 ++++ .../dokka/gradle/DokkaConfigurationJsonTest.kt | 51 +--- .../gradle/DokkaConfigurationSerializableTest.kt | 13 +- .../dokka/gradle/DokkaMultiModuleTaskTest.kt | 112 ++++++++ .../gradle/KotlinDslDokkaTaskConfigurationTest.kt | 5 +- runners/maven-plugin/src/main/kotlin/DokkaMojo.kt | 21 +- .../main/kotlin/testApi/testRunner/TestRunner.kt | 45 +-- 67 files changed, 1390 insertions(+), 1305 deletions(-) create mode 100644 integration-tests/gradle/projects/it-multiplatform-0/src/jvmMain/kotlin/it/mpp0/JvmOnlyClass.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaParentTask.kt delete mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ConfigurationExtractor.kt delete mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaBootstrapFactory.kt delete mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaSourceSetIDFactory.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleDokkaSourceSetBuilder.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleExternalDocumentationLinkBuilder.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradlePackageOptionsBuilder.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleSourceLinkBuilder.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleSourceRootBuilder.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/KotlinSourceSetGist.kt delete mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ProxyUtils.kt delete mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ReflectDsl.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/TaskDependencyInternalWithAdditions.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/automagicTypedProxy.kt delete mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt delete mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/defaultDokkaOutputDirectory.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/dokka.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/dokkaBootstrapFactory.kt delete mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/dokkaConfigurations.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/dokkaDefaultOutputDirectory.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/dokkaSourceSetIDFactory.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/gradleConfigurations.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/sourceSetKotlinGistConfiguration.kt create mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaParentTaskTest.kt create mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTaskTest.kt create mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTaskTest.kt diff --git a/core/src/main/kotlin/DokkaBootstrapImpl.kt b/core/src/main/kotlin/DokkaBootstrapImpl.kt index a2efab41..584d8b8c 100644 --- a/core/src/main/kotlin/DokkaBootstrapImpl.kt +++ b/core/src/main/kotlin/DokkaBootstrapImpl.kt @@ -70,38 +70,8 @@ class DokkaBootstrapImpl : DokkaBootstrap { private lateinit var generator: DokkaGenerator - fun configure(logger: DokkaLogger, configuration: DokkaConfigurationImpl) = with(configuration) { - - fun defaultLinks(config: DokkaSourceSetImpl): List { - val links = mutableListOf() - if (!config.noJdkLink) { - val javadocLink = - if (config.jdkVersion < 11) "https://docs.oracle.com/javase/${config.jdkVersion}/docs/api/" - else "https://docs.oracle.com/en/java/javase/${config.jdkVersion}/docs/api/java.base/" - val packageListLink = - if (config.jdkVersion < 11) "${javadocLink}/package-list" - else "https://docs.oracle.com/en/java/javase/${config.jdkVersion}/docs/api/element-list" - links += DokkaConfiguration.ExternalDocumentationLink - .Builder(javadocLink, packageListLink) - .build() as ExternalDocumentationLinkImpl - } - - if (!config.noStdlibLink) - links += DokkaConfiguration.ExternalDocumentationLink - .Builder("https://kotlinlang.org/api/latest/jvm/stdlib/") - .build() as ExternalDocumentationLinkImpl - return links - } - - val configurationWithLinks = configuration.copy( - sourceSets = sourceSets.map { - val links: List = - it.externalDocumentationLinks + defaultLinks(it) - it.copy(externalDocumentationLinks = links) - } - ) - - generator = DokkaGenerator(configurationWithLinks, logger) + fun configure(logger: DokkaLogger, configuration: DokkaConfigurationImpl) { + generator = DokkaGenerator(configuration, logger) } override fun configure(serializedConfigurationJSON: String, logger: BiConsumer) = configure( diff --git a/core/src/main/kotlin/configuration.kt b/core/src/main/kotlin/configuration.kt index 91ee4d64..67c55861 100644 --- a/core/src/main/kotlin/configuration.kt +++ b/core/src/main/kotlin/configuration.kt @@ -2,16 +2,16 @@ package org.jetbrains.dokka -import org.jetbrains.dokka.utilities.toJsonString import org.jetbrains.dokka.utilities.parseJson +import org.jetbrains.dokka.utilities.toJsonString import java.io.File import java.io.Serializable import java.net.URL object DokkaDefaults { - const val outputDir = "./dokka" + val outputDir = File("./dokka") const val format: String = "html" - val cacheRoot: String? = null + val cacheRoot: File? = null const val offlineMode: Boolean = false const val failOnWarning: Boolean = false @@ -51,6 +51,14 @@ enum class Platform(val key: String) { } } +interface DokkaConfigurationBuilder { + fun build(): T +} + +fun Iterable>.build(): List { + return this.map { it.build() } +} + data class DokkaSourceSetID( val moduleName: String, val sourceSetName: String @@ -65,8 +73,8 @@ fun DokkaConfigurationImpl(json: String): DokkaConfigurationImpl = parseJson(jso fun DokkaConfiguration.toJsonString(): String = toJsonString(this) interface DokkaConfiguration : Serializable { - val outputDir: String - val cacheRoot: String? + val outputDir: File + val cacheRoot: File? val offlineMode: Boolean val failOnWarning: Boolean val sourceSets: List @@ -78,11 +86,11 @@ interface DokkaConfiguration : Serializable { val sourceSetID: DokkaSourceSetID val displayName: String val moduleDisplayName: String - val classpath: List + val classpath: List val sourceRoots: List val dependentSourceSets: Set - val samples: List - val includes: List + val samples: List + val includes: List val includeNonPublic: Boolean val includeRootPackage: Boolean val reportUndocumented: Boolean @@ -96,12 +104,12 @@ interface DokkaConfiguration : Serializable { val apiVersion: String? val noStdlibLink: Boolean val noJdkLink: Boolean - val suppressedFiles: List + val suppressedFiles: List val analysisPlatform: Platform } interface SourceRoot : Serializable { - val path: String + val directory: File } interface SourceLinkDefinition : Serializable { @@ -112,8 +120,8 @@ interface DokkaConfiguration : Serializable { interface DokkaModuleDescription : Serializable { val name: String - val path: String - val docFile: String + val path: File + val docFile: File } interface PackageOptions : Serializable { @@ -135,7 +143,7 @@ interface DokkaConfiguration : Serializable { constructor(root: String, packageList: String? = null) : this(URL(root), packageList?.let { URL(it) }) - fun build(): ExternalDocumentationLink = + fun build(): ExternalDocumentationLinkImpl = if (packageListUrl != null && url != null) ExternalDocumentationLinkImpl(url!!, packageListUrl!!) else if (url != null) @@ -146,4 +154,16 @@ interface DokkaConfiguration : Serializable { } } +fun ExternalDocumentationLink( + url: URL? = null, + packageListUrl: URL? = null +): ExternalDocumentationLinkImpl = + DokkaConfiguration.ExternalDocumentationLink.Builder(url = url, packageListUrl = packageListUrl).build() + + +fun ExternalDocumentationLink( + url: String, packageListUrl: String? = null +): ExternalDocumentationLinkImpl = + DokkaConfiguration.ExternalDocumentationLink.Builder(root = url, packageList = packageListUrl).build() + diff --git a/core/src/main/kotlin/defaultConfiguration.kt b/core/src/main/kotlin/defaultConfiguration.kt index 8e38e8d5..384ce392 100644 --- a/core/src/main/kotlin/defaultConfiguration.kt +++ b/core/src/main/kotlin/defaultConfiguration.kt @@ -3,10 +3,12 @@ package org.jetbrains.dokka import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import java.io.File import java.net.URL +import kotlin.reflect.full.memberProperties +import kotlin.reflect.full.primaryConstructor data class DokkaConfigurationImpl( - override val outputDir: String = DokkaDefaults.outputDir, - override val cacheRoot: String? = DokkaDefaults.cacheRoot, + override val outputDir: File = DokkaDefaults.outputDir, + override val cacheRoot: File? = DokkaDefaults.cacheRoot, override val offlineMode: Boolean = DokkaDefaults.offlineMode, override val sourceSets: List = emptyList(), override val pluginsClasspath: List = emptyList(), @@ -15,15 +17,16 @@ data class DokkaConfigurationImpl( override val failOnWarning: Boolean = DokkaDefaults.failOnWarning ) : DokkaConfiguration + data class DokkaSourceSetImpl( override val moduleDisplayName: String, override val displayName: String = DokkaDefaults.sourceSetDisplayName, override val sourceSetID: DokkaSourceSetID, - override val classpath: List = emptyList(), + override val classpath: List = emptyList(), override val sourceRoots: List, override val dependentSourceSets: Set = emptySet(), - override val samples: List = emptyList(), - override val includes: List = emptyList(), + override val samples: List = emptyList(), + override val includes: List = emptyList(), override val includeNonPublic: Boolean = DokkaDefaults.includeNonPublic, override val includeRootPackage: Boolean = DokkaDefaults.includeRootPackage, override val reportUndocumented: Boolean = DokkaDefaults.reportUndocumented, @@ -37,19 +40,21 @@ data class DokkaSourceSetImpl( override val apiVersion: String? = null, override val noStdlibLink: Boolean = DokkaDefaults.noStdlibLink, override val noJdkLink: Boolean = DokkaDefaults.noJdkLink, - override val suppressedFiles: List = emptyList(), + override val suppressedFiles: List = emptyList(), override val analysisPlatform: Platform = DokkaDefaults.analysisPlatform ) : DokkaSourceSet data class DokkaModuleDescriptionImpl( override val name: String, - override val path: String, - override val docFile: String + override val path: File, + override val docFile: File ) : DokkaConfiguration.DokkaModuleDescription data class SourceRootImpl( - override val path: String -) : DokkaConfiguration.SourceRoot + override val directory: File +) : DokkaConfiguration.SourceRoot { + constructor(directoryPath: String) : this(File(directoryPath)) +} data class SourceLinkDefinitionImpl( override val path: String, diff --git a/core/src/main/kotlin/utilities/json.kt b/core/src/main/kotlin/utilities/json.kt index 9e4677aa..feac2b23 100644 --- a/core/src/main/kotlin/utilities/json.kt +++ b/core/src/main/kotlin/utilities/json.kt @@ -56,10 +56,10 @@ private object FileSerializer : StdScalarSerializer(File::class.java) { private object SourceRootSerializer : StdScalarSerializer(SourceRoot::class.java) { override fun serialize(value: SourceRoot, g: JsonGenerator, provider: SerializerProvider) { - g.writeString(value.path) + g.writeString(value.directory.path) } } private object SourceRootImplDeserializer : StdScalarDeserializer(SourceRootImpl::class.java) { - override fun deserialize(p: JsonParser, ctxt: DeserializationContext): SourceRootImpl = SourceRootImpl(p.text) + override fun deserialize(p: JsonParser, ctxt: DeserializationContext): SourceRootImpl = SourceRootImpl(File(p.text)) } diff --git a/core/src/test/kotlin/utilities/DokkaConfigurationJsonTest.kt b/core/src/test/kotlin/utilities/DokkaConfigurationJsonTest.kt index e954c82c..35755f50 100644 --- a/core/src/test/kotlin/utilities/DokkaConfigurationJsonTest.kt +++ b/core/src/test/kotlin/utilities/DokkaConfigurationJsonTest.kt @@ -9,12 +9,12 @@ class DokkaConfigurationJsonTest { @Test fun `simple configuration toJsonString then parseJson`() { val configuration = DokkaConfigurationImpl( - outputDir = "customOutputDir", + outputDir = File("customOutputDir"), pluginsClasspath = listOf(File("plugins/customPlugin.jar")), sourceSets = listOf( DokkaSourceSetImpl( moduleDisplayName = "customModuleDisplayName", - sourceRoots = listOf(SourceRootImpl("customSourceRoot")), + sourceRoots = listOf(SourceRootImpl(File("customSourceRoot"))), sourceSetID = DokkaSourceSetID("customModuleName", "customSourceSetName") ) ) @@ -48,14 +48,14 @@ class DokkaConfigurationJsonTest { val parsedConfiguration = DokkaConfigurationImpl(json) assertEquals( DokkaConfigurationImpl( - outputDir = "customOutputDir", + outputDir = File("customOutputDir"), pluginsClasspath = listOf(File("plugins/customPlugin.jar")), sourceSets = listOf( DokkaSourceSetImpl( moduleDisplayName = "customModuleDisplayName", - sourceRoots = listOf(SourceRootImpl("customSourceRoot")), + sourceRoots = listOf(SourceRootImpl(File("customSourceRoot"))), sourceSetID = DokkaSourceSetID("customModuleName", "customSourceSetName"), - classpath = listOf("classpath/custom1.jar", "classpath/custom2.jar") + classpath = listOf(File("classpath/custom1.jar"), File("classpath/custom2.jar")) ) ) ), diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index bb8b2fc2..29271bed 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Tue Jul 21 13:56:13 CEST 2020 +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-all.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-bin.zip -zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/integration-tests/build.gradle.kts b/integration-tests/build.gradle.kts index 86472aa9..aaa8b153 100644 --- a/integration-tests/build.gradle.kts +++ b/integration-tests/build.gradle.kts @@ -38,7 +38,6 @@ subprojects { ?: System.getenv("DOKKA_INTEGRATION_TEST_IS_EXHAUSTIVE")?.toBoolean() ?: false.toString() ) - } tasks.check { diff --git a/integration-tests/gradle/projects/it-basic-groovy/build.gradle b/integration-tests/gradle/projects/it-basic-groovy/build.gradle index 13a34619..405b55ed 100644 --- a/integration-tests/gradle/projects/it-basic-groovy/build.gradle +++ b/integration-tests/gradle/projects/it-basic-groovy/build.gradle @@ -10,28 +10,29 @@ dependencies { } dokkaHtml { - outputDirectory = "$buildDir/dokka/customHtml" + outputDirectory = new File(buildDir, "/dokka/customHtml") pluginsConfiguration.put("pluginA", "configA") failOnWarning = false dokkaSourceSets { customSourceSet { - sourceRoot { path = "$projectDir/src/main/java" } - sourceRoot { path = "$projectDir/src/main/kotlin" } + sourceRoot { directory = file("src/main/java") } + sourceRoot { directory = file("src/main/kotlin") } displayName = "custom" reportUndocumented = true } } + } dokkaJavadoc { - outputDirectory = "$buildDir/dokka/customJavadoc" + outputDirectory = new File(buildDir, "dokka/customJavadoc") } dokkaGfm { - outputDirectory = "$buildDir/dokka/customGfm" + outputDirectory = new File(buildDir, "dokka/customGfm") } dokkaJekyll { - outputDirectory = "$buildDir/dokka/customJekyll" + outputDirectory = new File(buildDir, "dokka/customJekyll") } diff --git a/integration-tests/gradle/projects/it-basic/build.gradle.kts b/integration-tests/gradle/projects/it-basic/build.gradle.kts index b3ddde18..45454e29 100644 --- a/integration-tests/gradle/projects/it-basic/build.gradle.kts +++ b/integration-tests/gradle/projects/it-basic/build.gradle.kts @@ -14,11 +14,11 @@ dependencies { tasks.withType { dokkaSourceSets { configureEach { - moduleDisplayName = "Basic Project" - suppressedFiles = listOf("src/main/kotlin/it/suppressedByPath") + moduleDisplayName.set("Basic Project") + suppressedFiles.from(file("src/main/kotlin/it/suppressedByPath")) perPackageOption { - prefix = "it.suppressedByPackage" - suppress = true + prefix.set("it.suppressedByPackage") + suppress.set(true) } } } diff --git a/integration-tests/gradle/projects/it-multiplatform-0/build.gradle.kts b/integration-tests/gradle/projects/it-multiplatform-0/build.gradle.kts index 52aa9d36..26200399 100644 --- a/integration-tests/gradle/projects/it-multiplatform-0/build.gradle.kts +++ b/integration-tests/gradle/projects/it-multiplatform-0/build.gradle.kts @@ -1,5 +1,3 @@ -import org.jetbrains.dokka.gradle.DokkaTask - plugins { kotlin("multiplatform") id("org.jetbrains.dokka") @@ -20,13 +18,3 @@ kotlin { } } } - -tasks.withType { - dokkaSourceSets { - create("commonMain") - create("jvmMain") - create("linuxMain") - create("macosMain") - create("jsMain") - } -} diff --git a/integration-tests/gradle/projects/it-multiplatform-0/src/jvmMain/kotlin/it/mpp0/ExpectedClass.kt b/integration-tests/gradle/projects/it-multiplatform-0/src/jvmMain/kotlin/it/mpp0/ExpectedClass.kt index 8e7fa96e..6de30de6 100644 --- a/integration-tests/gradle/projects/it-multiplatform-0/src/jvmMain/kotlin/it/mpp0/ExpectedClass.kt +++ b/integration-tests/gradle/projects/it-multiplatform-0/src/jvmMain/kotlin/it/mpp0/ExpectedClass.kt @@ -2,4 +2,10 @@ package it.mpp0 actual class ExpectedClass { actual val platform: String = "jvm" + + /** + * This function can only be used by JVM consumers + */ + fun jvmOnlyFunction() = Unit + } diff --git a/integration-tests/gradle/projects/it-multiplatform-0/src/jvmMain/kotlin/it/mpp0/JvmOnlyClass.kt b/integration-tests/gradle/projects/it-multiplatform-0/src/jvmMain/kotlin/it/mpp0/JvmOnlyClass.kt new file mode 100644 index 00000000..21101a89 --- /dev/null +++ b/integration-tests/gradle/projects/it-multiplatform-0/src/jvmMain/kotlin/it/mpp0/JvmOnlyClass.kt @@ -0,0 +1,13 @@ +@file:Suppress("unused") + +package it.mpp0 + +/** + * This class can only be used by JVM consumers + */ +class JvmOnlyClass { + /** + * This function can only be used by JVM consumers + */ + fun myJvm() = println("HI") +} diff --git a/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/Android0GradleIntegrationTest.kt b/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/Android0GradleIntegrationTest.kt index d6dfe451..a657e9c7 100644 --- a/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/Android0GradleIntegrationTest.kt +++ b/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/Android0GradleIntegrationTest.kt @@ -62,12 +62,6 @@ class Android0GradleIntegrationTest(override val versions: BuildVersions) : Abst "Expected html files in html output directory" ) - htmlOutputDir.allHtmlFiles().forEach { file -> - assertContainsNoErrorClass(file) - assertNoUnresolvedLinks(file) - assertNoHrefToMissingLocalFileOrDirectory(file) - } - assertTrue( htmlOutputDir.allHtmlFiles().any { file -> "https://developer.android.com/reference/android/content/Context.html" in file.readText() @@ -80,5 +74,11 @@ class Android0GradleIntegrationTest(override val versions: BuildVersions) : Abst file.readText() }, "Expected link to developer.android.com/.../androidx/" ) + + htmlOutputDir.allHtmlFiles().forEach { file -> + assertContainsNoErrorClass(file) + assertNoUnresolvedLinks(file) + assertNoHrefToMissingLocalFileOrDirectory(file) + } } } diff --git a/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/Multimodule0IntegrationTest.kt b/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/Multimodule0IntegrationTest.kt index fc7a6a81..70b5832d 100644 --- a/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/Multimodule0IntegrationTest.kt +++ b/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/Multimodule0IntegrationTest.kt @@ -36,6 +36,13 @@ class Multimodule0IntegrationTest(override val versions: BuildVersions) : Abstra assertEquals(TaskOutcome.SUCCESS, assertNotNull(result.task(":moduleA:dokkaHtmlMultimodule")).outcome) assertEquals(TaskOutcome.SUCCESS, assertNotNull(result.task(":moduleA:dokkaGfmMultimodule")).outcome) assertEquals(TaskOutcome.SUCCESS, assertNotNull(result.task(":moduleA:dokkaJekyllMultimodule")).outcome) + assertEquals(TaskOutcome.SUCCESS, assertNotNull(result.task(":moduleA:moduleB:dokkaHtml")).outcome) + assertEquals(TaskOutcome.SUCCESS, assertNotNull(result.task(":moduleA:moduleC:dokkaHtml")).outcome) + assertEquals(TaskOutcome.SUCCESS, assertNotNull(result.task(":moduleA:moduleB:dokkaGfm")).outcome) + assertEquals(TaskOutcome.SUCCESS, assertNotNull(result.task(":moduleA:moduleC:dokkaGfm")).outcome) + assertEquals(TaskOutcome.SUCCESS, assertNotNull(result.task(":moduleA:moduleB:dokkaJekyll")).outcome) + assertEquals(TaskOutcome.SUCCESS, assertNotNull(result.task(":moduleA:moduleC:dokkaJekyll")).outcome) + val outputDir = File(projectDir, "moduleA/build/dokka/htmlMultimodule") assertTrue(outputDir.isDirectory, "Missing dokka output directory") diff --git a/integration-tests/src/main/kotlin/org/jetbrains/dokka/it/AbstractIntegrationTest.kt b/integration-tests/src/main/kotlin/org/jetbrains/dokka/it/AbstractIntegrationTest.kt index c4914652..d21106fa 100644 --- a/integration-tests/src/main/kotlin/org/jetbrains/dokka/it/AbstractIntegrationTest.kt +++ b/integration-tests/src/main/kotlin/org/jetbrains/dokka/it/AbstractIntegrationTest.kt @@ -3,10 +3,13 @@ package org.jetbrains.dokka.it import org.jsoup.Jsoup import org.junit.Rule import org.junit.rules.TemporaryFolder +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 import java.io.File import kotlin.test.assertFalse import kotlin.test.assertTrue +@RunWith(JUnit4::class) abstract class AbstractIntegrationTest { @get:Rule diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AnalysisEnvironment.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AnalysisEnvironment.kt index 685bfe82..14067f43 100644 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AnalysisEnvironment.kt +++ b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AnalysisEnvironment.kt @@ -540,12 +540,11 @@ class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPl * Adds list of paths to source roots. * $list: collection of files to add */ - fun addSources(list: List) { - list.forEach { - configuration.addKotlinSourceRoot(it) - val file = File(it) - if (file.isDirectory || file.extension == ".java") { - configuration.addJavaSourceRoot(file) + fun addSources(sourceDirectories: List) { + sourceDirectories.forEach { directory -> + configuration.addKotlinSourceRoot(directory.path) + if (directory.isDirectory || directory.extension == ".java") { + configuration.addJavaSourceRoot(directory) } } } diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/EnvironmentAndFacade.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/EnvironmentAndFacade.kt index d9a89194..009bc66c 100644 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/EnvironmentAndFacade.kt +++ b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/EnvironmentAndFacade.kt @@ -17,12 +17,12 @@ internal fun createEnvironmentAndFacade( if (analysisPlatform == Platform.jvm) { addClasspath(PathUtil.getJdkClassesRootsFromCurrentJre()) } - sourceSet.classpath.forEach { addClasspath(File(it)) } + sourceSet.classpath.forEach(::addClasspath) addSources( (sourceSet.sourceRoots + configuration.sourceSets.filter { it.sourceSetID in sourceSet.dependentSourceSets } .flatMap { it.sourceRoots }) - .map { it.path } + .map { it.directory } ) loadLanguageVersionSettings(sourceSet.languageVersion, sourceSet.apiVersion) diff --git a/plugins/base/src/main/kotlin/allModulePage/MultimodulePageCreator.kt b/plugins/base/src/main/kotlin/allModulePage/MultimodulePageCreator.kt index de2242f2..4be84749 100644 --- a/plugins/base/src/main/kotlin/allModulePage/MultimodulePageCreator.kt +++ b/plugins/base/src/main/kotlin/allModulePage/MultimodulePageCreator.kt @@ -43,7 +43,7 @@ class MultimodulePageCreator( header(2, "All modules:") table(styles = setOf(MultimoduleTable)) { modules.mapNotNull { module -> - val paragraph = module.docFile.let(::File).readText().let { parser.parse(it).firstParagraph() } + val paragraph = module.docFile.readText().let { parser.parse(it).firstParagraph() } paragraph?.let { val dri = DRI(packageName = MULTIMODULE_PACKAGE_PLACEHOLDER, classNames = module.name) val dci = DCI(setOf(dri), ContentKind.Main) @@ -68,10 +68,9 @@ class MultimodulePageCreator( } private fun throwOnMissingModuleDocFile(module: DokkaConfiguration.DokkaModuleDescription) { - val docFile = File(module.docFile) - if (!docFile.exists() || !docFile.isFile) { + if (!module.docFile.exists() || !module.docFile.isFile) { throw DokkaException( - "Missing documentation file for module ${module.name}: ${docFile.absolutePath}" + "Missing documentation file for module ${module.name}: ${module.docFile.absolutePath}" ) } } diff --git a/plugins/base/src/main/kotlin/renderers/FileWriter.kt b/plugins/base/src/main/kotlin/renderers/FileWriter.kt index 181295c0..cd38f1b9 100644 --- a/plugins/base/src/main/kotlin/renderers/FileWriter.kt +++ b/plugins/base/src/main/kotlin/renderers/FileWriter.kt @@ -21,10 +21,10 @@ class FileWriter(val context: DokkaContext): OutputWriter { createdFiles.add(path) try { - val dir = Paths.get(root, path.dropLastWhile { it != '/' }).toFile() + val dir = Paths.get(root.absolutePath, path.dropLastWhile { it != '/' }).toFile() withContext(Dispatchers.IO) { dir.mkdirsOrFail() - Files.write(Paths.get(root, "$path$ext"), text.lines()) + Files.write(Paths.get(root.absolutePath, "$path$ext"), text.lines()) } } catch (e: Throwable) { context.logger.error("Failed to write $this. ${e.message}") @@ -41,7 +41,7 @@ class FileWriter(val context: DokkaContext): OutputWriter { private suspend fun copyFromDirectory(pathFrom: String, pathTo: String) { - val dest = Paths.get(root, pathTo).toFile() + val dest = Paths.get(root.path, pathTo).toFile() val uri = javaClass.getResource(pathFrom).toURI() withContext(Dispatchers.IO) { File(uri).copyRecursively(dest, true) @@ -51,7 +51,7 @@ class FileWriter(val context: DokkaContext): OutputWriter { private suspend fun copyFromJar(pathFrom: String, pathTo: String) { val rebase = fun(path: String) = "$pathTo/${path.removePrefix(pathFrom)}" - val dest = Paths.get(root, pathTo).toFile() + val dest = Paths.get(root.path, pathTo).toFile() dest.mkdirsOrFail() val uri = javaClass.getResource(pathFrom).toURI() val fs = getFileSystemForURI(uri) @@ -60,12 +60,12 @@ class FileWriter(val context: DokkaContext): OutputWriter { if (Files.isDirectory(file)) { val dirPath = file.toAbsolutePath().toString() withContext(Dispatchers.IO) { - Paths.get(root, rebase(dirPath)).toFile().mkdirsOrFail() + Paths.get(root.path, rebase(dirPath)).toFile().mkdirsOrFail() } } else { val filePath = file.toAbsolutePath().toString() withContext(Dispatchers.IO) { - Paths.get(root, rebase(filePath)).toFile().writeBytes( + Paths.get(root.path, rebase(filePath)).toFile().writeBytes( this@FileWriter.javaClass.getResourceAsStream(filePath).readBytes() ) } @@ -85,4 +85,4 @@ class FileWriter(val context: DokkaContext): OutputWriter { } catch (e: FileSystemAlreadyExistsException) { FileSystems.getFileSystem(uri) } -} \ No newline at end of file +} diff --git a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt index 4a98a5e0..71824922 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt @@ -22,9 +22,9 @@ internal class ModuleAndPackageDocumentationTransformer( val modulesAndPackagesDocumentation = context.configuration.sourceSets - .map { - Pair(it.moduleDisplayName, it) to - it.includes.map { Paths.get(it) } + .map { sourceSet -> + Pair(sourceSet.moduleDisplayName, sourceSet) to + sourceSet.includes.map { it.toPath() } .also { it.forEach { if (Files.notExists(it)) diff --git a/plugins/base/src/main/kotlin/transformers/documentables/SuppressedDocumentableFilterTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/SuppressedDocumentableFilterTransformer.kt index 79feb832..7febabbb 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/SuppressedDocumentableFilterTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/SuppressedDocumentableFilterTransformer.kt @@ -45,7 +45,7 @@ class SuppressedDocumentableFilterTransformer(val context: DokkaContext) : PreMe if (documentable !is WithExpectActual) return false val sourceFile = File(source(documentable).path).absoluteFile return sourceSet(documentable).suppressedFiles.any { suppressedFile -> - sourceFile.startsWith(File(suppressedFile).absoluteFile) + sourceFile.startsWith(suppressedFile.absoluteFile) } } } diff --git a/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt index 695ef050..f13e52ab 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt @@ -43,16 +43,16 @@ abstract class SamplesTransformer(val context: DokkaContext) : PageTransformer { } } - private fun setUpAnalysis(context: DokkaContext) = context.configuration.sourceSets.map { - it to AnalysisEnvironment(DokkaMessageCollector(context.logger), it.analysisPlatform).run { + private fun setUpAnalysis(context: DokkaContext) = context.configuration.sourceSets.map { sourceSet -> + sourceSet to AnalysisEnvironment(DokkaMessageCollector(context.logger), sourceSet.analysisPlatform).run { if (analysisPlatform == Platform.jvm) { addClasspath(PathUtil.getJdkClassesRootsFromCurrentJre()) } - it.classpath.forEach { addClasspath(File(it)) } + sourceSet.classpath.forEach(::addClasspath) - addSources(it.samples.map { it }) + addSources(sourceSet.samples.toList()) - loadLanguageVersionSettings(it.languageVersion, it.apiVersion) + loadLanguageVersionSettings(sourceSet.languageVersion, sourceSet.apiVersion) val environment = createCoreEnvironment() val (facade, _) = createResolutionFacade(environment) diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt index c4c6483f..1ac4edf7 100644 --- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt @@ -95,7 +95,7 @@ private class DokkaDescriptorVisitor( private fun Collection.filterDescriptorsInSourceSet() = filter { it.toSourceElement.containingFile.toString().let { path -> path.isNotBlank() && sourceSet.sourceRoots.any { root -> - Paths.get(path).startsWith(Paths.get(root.path)) + Paths.get(path).startsWith(root.directory.toPath()) } } } @@ -356,7 +356,8 @@ private class DokkaDescriptorVisitor( sources = actual, visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), generics = descriptor.typeParameters.map { it.toTypeParameter() }, - documentation = descriptor.takeIf { it.kind != CallableMemberDescriptor.Kind.SYNTHESIZED }?.resolveDescriptorData() ?: emptyMap(), + documentation = descriptor.takeIf { it.kind != CallableMemberDescriptor.Kind.SYNTHESIZED } + ?.resolveDescriptorData() ?: emptyMap(), modifier = descriptor.modifier().toSourceSetDependent(), type = descriptor.returnType!!.toBound(), sourceSets = setOf(sourceSet), @@ -746,11 +747,19 @@ private class DokkaDescriptorVisitor( private data class InheritanceLevel(val level: Int, val superclass: DRI?, val interfaces: List) - private data class ClassInfo(val inheritance: List, val docs: SourceSetDependent){ + private data class ClassInfo( + val inheritance: List, + val docs: SourceSetDependent + ) { val supertypes: List get() = inheritance.firstOrNull { it.level == 0 }?.let { - listOfNotNull(it.superclass?.let { DriWithKind(it, KotlinClassKindTypes.CLASS) }) + it.interfaces.map { DriWithKind(it, KotlinClassKindTypes.INTERFACE) } - }.orEmpty() + listOfNotNull(it.superclass?.let { + DriWithKind( + it, + KotlinClassKindTypes.CLASS + ) + }) + it.interfaces.map { DriWithKind(it, KotlinClassKindTypes.INTERFACE) } + }.orEmpty() val allImplementedInterfaces: List get() = inheritance.flatMap { it.interfaces }.distinct() diff --git a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt index 9ed37c30..cd43e635 100644 --- a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt @@ -43,8 +43,8 @@ class DefaultPsiToDocumentableTranslator( override fun invoke(sourceSet: DokkaSourceSet, context: DokkaContext): DModule { - fun isFileInSourceRoots(file: File) : Boolean { - return sourceSet.sourceRoots.any { root -> file.path.startsWith(File(root.path).absolutePath) } + fun isFileInSourceRoots(file: File): Boolean { + return sourceSet.sourceRoots.any { root -> file.startsWith(root.directory) } } val (environment, _) = kotlinAnalysis[sourceSet] @@ -133,7 +133,7 @@ class DefaultPsiToDocumentableTranslator( val superMethods = mutableListOf>() methods.forEach { superMethodsKeys.add(it.hash) } fun parseSupertypes(superTypes: Array, level: Int = 0) { - if(superTypes.isEmpty()) return + if (superTypes.isEmpty()) return val parsedClasses = superTypes.filter { !it.shouldBeIgnored }.mapNotNull { it.resolve()?.let { when { @@ -178,7 +178,8 @@ class DefaultPsiToDocumentableTranslator( }) + it.interfaces.map { DriWithKind(dri = it, kind = JavaClassKindTypes.INTERFACE) } }.toSourceSetDependent() val modifiers = getModifier().toSourceSetDependent() - val implementedInterfacesExtra = ImplementedInterfaces(inheritanceTree.flatMap { it.interfaces }.distinct().toSourceSetDependent()) + val implementedInterfacesExtra = + ImplementedInterfaces(inheritanceTree.flatMap { it.interfaces }.distinct().toSourceSetDependent()) return when { isAnnotationType -> DAnnotation( @@ -195,8 +196,11 @@ class DefaultPsiToDocumentableTranslator( constructors.map { parseFunction(it, true) }, mapTypeParameters(dri), setOf(sourceSetData), - PropertyContainer.withAll(implementedInterfacesExtra, annotations.toList().toListOfAnnotations().toSourceSetDependent() - .toAnnotations()) + PropertyContainer.withAll( + implementedInterfacesExtra, + annotations.toList().toListOfAnnotations().toSourceSetDependent() + .toAnnotations() + ) ) isEnum -> DEnum( dri, @@ -211,8 +215,11 @@ class DefaultPsiToDocumentableTranslator( emptyList(), emptyList(), setOf(sourceSetData), - PropertyContainer.withAll(implementedInterfacesExtra, annotations.toList().toListOfAnnotations().toSourceSetDependent() - .toAnnotations()) + PropertyContainer.withAll( + implementedInterfacesExtra, + annotations.toList().toListOfAnnotations().toSourceSetDependent() + .toAnnotations() + ) ) }, documentation, @@ -226,8 +233,10 @@ class DefaultPsiToDocumentableTranslator( constructors.map { parseFunction(it, true) }, ancestors, setOf(sourceSetData), - PropertyContainer.withAll(implementedInterfacesExtra, annotations.toList().toListOfAnnotations().toSourceSetDependent() - .toAnnotations()) + PropertyContainer.withAll( + implementedInterfacesExtra, annotations.toList().toListOfAnnotations().toSourceSetDependent() + .toAnnotations() + ) ) isInterface -> DInterface( dri, @@ -243,8 +252,10 @@ class DefaultPsiToDocumentableTranslator( mapTypeParameters(dri), ancestors, setOf(sourceSetData), - PropertyContainer.withAll(implementedInterfacesExtra, annotations.toList().toListOfAnnotations().toSourceSetDependent() - .toAnnotations()) + PropertyContainer.withAll( + implementedInterfacesExtra, annotations.toList().toListOfAnnotations().toSourceSetDependent() + .toAnnotations() + ) ) else -> DClass( dri, @@ -262,8 +273,10 @@ class DefaultPsiToDocumentableTranslator( null, modifiers, setOf(sourceSetData), - PropertyContainer.withAll(implementedInterfacesExtra, annotations.toList().toListOfAnnotations().toSourceSetDependent() - .toAnnotations()) + PropertyContainer.withAll( + implementedInterfacesExtra, annotations.toList().toListOfAnnotations().toSourceSetDependent() + .toAnnotations() + ) ) } } @@ -305,7 +318,8 @@ class DefaultPsiToDocumentableTranslator( PropertyContainer.withAll( InheritedFunction(inheritedFrom.toSourceSetDependent()), it.toSourceSetDependent().toAdditionalModifiers(), - (psi.annotations.toList().toListOfAnnotations() + it.toListOfAnnotations()).toSourceSetDependent() + (psi.annotations.toList() + .toListOfAnnotations() + it.toListOfAnnotations()).toSourceSetDependent() .toAnnotations() ) } @@ -434,7 +448,8 @@ class DefaultPsiToDocumentableTranslator( psi.additionalExtras().let { PropertyContainer.withAll( it.toSourceSetDependent().toAdditionalModifiers(), - (psi.annotations.toList().toListOfAnnotations() + it.toListOfAnnotations()).toSourceSetDependent() + (psi.annotations.toList() + .toListOfAnnotations() + it.toListOfAnnotations()).toSourceSetDependent() .toAnnotations() ) } diff --git a/plugins/base/src/test/kotlin/expect/AbstractExpectTest.kt b/plugins/base/src/test/kotlin/expect/AbstractExpectTest.kt index 4dfdc410..57571cd3 100644 --- a/plugins/base/src/test/kotlin/expect/AbstractExpectTest.kt +++ b/plugins/base/src/test/kotlin/expect/AbstractExpectTest.kt @@ -24,7 +24,7 @@ abstract class AbstractExpectTest( var result: Path? = null testFromData(config, cleanupOutput = false) { - renderingStage = { _, context -> result = Paths.get(context.configuration.outputDir) } + renderingStage = { _, context -> result = context.configuration.outputDir.toPath() } } return result } diff --git a/plugins/base/src/test/kotlin/renderers/html/HtmlRenderingOnlyTestBase.kt b/plugins/base/src/test/kotlin/renderers/html/HtmlRenderingOnlyTestBase.kt index b6765fda..ae494929 100644 --- a/plugins/base/src/test/kotlin/renderers/html/HtmlRenderingOnlyTestBase.kt +++ b/plugins/base/src/test/kotlin/renderers/html/HtmlRenderingOnlyTestBase.kt @@ -52,7 +52,7 @@ abstract class HtmlRenderingOnlyTestBase : RenderingOnlyTestBase() { DokkaBase().externalLocationProviderFactory to { ::DokkaExternalLocationProviderFactory }, DokkaBase().tabSortingStrategy to { DefaultTabSortingStrategy() }, testConfiguration = DokkaConfigurationImpl( - "", null, false, listOf(js, jvm, native), emptyList(), emptyMap(), emptyList(), false + sourceSets = listOf(js, jvm, native) ) ) diff --git a/plugins/gfm/src/test/kotlin/renderers/gfm/DivergentTest.kt b/plugins/gfm/src/test/kotlin/renderers/gfm/DivergentTest.kt index 0c8b942e..2381ad07 100644 --- a/plugins/gfm/src/test/kotlin/renderers/gfm/DivergentTest.kt +++ b/plugins/gfm/src/test/kotlin/renderers/gfm/DivergentTest.kt @@ -9,6 +9,7 @@ import org.jetbrains.dokka.pages.ContentDivergentGroup import org.junit.jupiter.api.Test import renderers.defaultSourceSet import renderers.TestPage +import java.io.File class DivergentTest : GfmRenderingOnlyTestBase() { private val js = defaultSourceSet.copy( @@ -371,4 +372,4 @@ class DivergentTest : GfmRenderingOnlyTestBase() { CommonmarkRenderer(context).render(page) assert(renderedContent == expect) } -} \ No newline at end of file +} diff --git a/plugins/gfm/src/test/kotlin/renderers/gfm/GfmRenderingOnlyTestBase.kt b/plugins/gfm/src/test/kotlin/renderers/gfm/GfmRenderingOnlyTestBase.kt index 6d0dd3a6..7c9590c6 100644 --- a/plugins/gfm/src/test/kotlin/renderers/gfm/GfmRenderingOnlyTestBase.kt +++ b/plugins/gfm/src/test/kotlin/renderers/gfm/GfmRenderingOnlyTestBase.kt @@ -21,9 +21,7 @@ abstract class GfmRenderingOnlyTestBase : RenderingOnlyTestBase() { DokkaBase().externalLocationProviderFactory to { ::DokkaExternalLocationProviderFactory }, GfmPlugin().gfmPreprocessors to { _ -> RootCreator }, - testConfiguration = DokkaConfigurationImpl( - "", null, false, emptyList(), emptyList(), emptyMap(), emptyList(), false - ) + testConfiguration = DokkaConfigurationImpl() ) override val renderedContent: String by lazy { diff --git a/plugins/javadoc/src/test/kotlin/org/jetbrains/dokka/javadoc/JavadocPackageTemplateMapTest.kt b/plugins/javadoc/src/test/kotlin/org/jetbrains/dokka/javadoc/JavadocPackageTemplateMapTest.kt index 447be3f8..89d5b286 100644 --- a/plugins/javadoc/src/test/kotlin/org/jetbrains/dokka/javadoc/JavadocPackageTemplateMapTest.kt +++ b/plugins/javadoc/src/test/kotlin/org/jetbrains/dokka/javadoc/JavadocPackageTemplateMapTest.kt @@ -8,6 +8,7 @@ import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.jetbrains.dokka.testApi.utils.assertIsInstance +import java.io.File internal class JavadocPackageTemplateMapTest : AbstractJavadocTemplateMapTest() { @@ -109,7 +110,7 @@ internal class JavadocPackageTemplateMapTest : AbstractJavadocTemplateMapTest() configuration = config.copy( sourceSets = config.sourceSets.map { sourceSet -> sourceSet.copy( - includes = listOf("packages.md") + includes = listOf(File("packages.md")) ) } ) diff --git a/runners/cli/src/main/kotlin/cli/main.kt b/runners/cli/src/main/kotlin/cli/main.kt index f8d5c55c..df763596 100644 --- a/runners/cli/src/main/kotlin/cli/main.kt +++ b/runners/cli/src/main/kotlin/cli/main.kt @@ -17,11 +17,11 @@ class GlobalArguments(args: Array) : DokkaConfiguration { val json: String? by parser.argument(ArgType.String, description = "Json file name").optional() - override val outputDir by parser.option(ArgType.String, description = "Output directory path") + override val outputDir by parser.option(ArgTypeFile, description = "Output directory path") .default(DokkaDefaults.outputDir) override val cacheRoot by parser.option( - ArgType.String, + ArgTypeFile, description = "Path to cache folder, or 'default' to use ~/.cache/dokka, if not provided caching is disabled" ) @@ -132,12 +132,12 @@ private fun parseSourceSet(args: Array): DokkaConfiguration.DokkaSourceS ).default(DokkaDefaults.sourceSetDisplayName) val classpath by parser.option( - ArgType.String, + ArgTypeFile, description = "Classpath for symbol resolution (allows many paths separated by the semicolon `;`)" ).delimiter(";") val sourceRoots by parser.option( - ArgType.String, + ArgTypeFile, description = "Source file or directory (allows many paths separated by the semicolon `;`)", fullName = "src" ).delimiter(";") @@ -148,12 +148,12 @@ private fun parseSourceSet(args: Array): DokkaConfiguration.DokkaSourceS ).delimiter(";") val samples by parser.option( - ArgType.String, + ArgTypeFile, description = "Source root for samples (allows many paths separated by the semicolon `;`)" ).delimiter(";") val includes by parser.option( - ArgType.String, + ArgTypeFile, description = "Markdown files to load (allows many paths separated by the semicolon `;`)" ).delimiter(";") @@ -196,7 +196,7 @@ private fun parseSourceSet(args: Array): DokkaConfiguration.DokkaSourceS .default(DokkaDefaults.noJdkLink) val suppressedFiles by parser.option( - ArgType.String, + ArgTypeFile, description = "Paths to files to be suppressed (allows many paths separated by the semicolon `;`)" ).delimiter(";") @@ -228,12 +228,12 @@ private fun parseSourceSet(args: Array): DokkaConfiguration.DokkaSourceS override val displayName = displayName override val sourceSetID = DokkaSourceSetID(moduleName, sourceSetName) override val classpath = classpath - override val sourceRoots = sourceRoots.map { SourceRootImpl(it.toAbsolutePath()) } + override val sourceRoots = sourceRoots.map { SourceRootImpl(it) } override val dependentSourceSets: Set = dependentSourceSets .map { dependentSourceSetName -> dependentSourceSetName.split('/').let { DokkaSourceSetID(it[0], it[1]) } } .toSet() - override val samples = samples.map { it.toAbsolutePath() } - override val includes = includes.map { it.toAbsolutePath() } + override val samples = samples + override val includes = includes override val includeNonPublic = includeNonPublic override val includeRootPackage = includeRootPackage override val reportUndocumented = reportUndocumented diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaParentTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaParentTask.kt new file mode 100644 index 00000000..bf8308bf --- /dev/null +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaParentTask.kt @@ -0,0 +1,73 @@ +package org.jetbrains.dokka.gradle + +import org.gradle.api.Project +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.Nested +import org.jetbrains.dokka.DokkaBootstrap +import org.jetbrains.dokka.DokkaBootstrapImpl +import kotlin.reflect.KClass + +// TODO NOW: Test UP-TO-DATE behaviour +abstract class AbstractDokkaParentTask( + bootstrapClass: KClass = DokkaBootstrapImpl::class +) : AbstractDokkaTask(bootstrapClass) { + + @Input + open var dokkaTaskNames: Set = setOf() + + @Input + var subprojectPaths: Set = project.subprojects.map { project -> project.path }.toSet() + + @get:Internal + val subprojects: List + get() = subprojectPaths.map { path -> project.project(path) }.distinct() + + @get:Nested + internal val dokkaTasks: List + get() = dokkaTaskNames.flatMap { dokkaTaskName -> findSubprojectDokkaTasks(dokkaTaskName) } + + + /** + * Will remove a single project from participating in this parent task. + * Note: This will not remove the [project]s subprojects. + * + * @see removeAllProjects + */ + fun removeSubproject(project: Project) { + subprojectPaths = subprojectPaths - project.path + } + + /** + * Will remove the [project] and all its subprojects from participating in this parent task. + * @see removeSubproject + */ + fun removeAllProjects(project: Project) { + project.allprojects.forEach(::removeSubproject) + } + + /** + * Includes the [project] to participate in this parent task. + * Note: This will not include any of the [project]s subprojects. + * @see addAllProjects + */ + fun addSubproject(project: Project) { + subprojectPaths = (subprojectPaths + project.path) + } + + /** + * Includes the [project] and all its subprojects to participate in this parent task. + * @see addSubproject + */ + fun addAllProjects(project: Project) { + project.allprojects.forEach(::addSubproject) + } + + protected fun findSubprojectDokkaTasks(dokkaTaskNames: Set): List { + return dokkaTaskNames.flatMap { dokkaTaskName -> findSubprojectDokkaTasks(dokkaTaskName) } + } + + private fun findSubprojectDokkaTasks(dokkaTaskName: String): List { + return subprojects.mapNotNull { subproject -> subproject.tasks.findByName(dokkaTaskName) as? DokkaTask } + } +} diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaTask.kt index 1269b305..6413d788 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaTask.kt @@ -1,21 +1,33 @@ package org.jetbrains.dokka.gradle import org.gradle.api.DefaultTask -import org.gradle.api.Project import org.gradle.api.artifacts.Configuration -import org.gradle.api.attributes.Usage -import org.gradle.api.tasks.Classpath -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.Internal -import org.gradle.api.tasks.TaskAction -import org.gradle.kotlin.dsl.dependencies +import org.gradle.api.plugins.JavaBasePlugin +import org.gradle.api.tasks.* import org.jetbrains.dokka.DokkaBootstrap +import org.jetbrains.dokka.DokkaConfigurationImpl import org.jetbrains.dokka.plugability.Configurable +import org.jetbrains.dokka.toJsonString +import java.io.File +import java.util.function.BiConsumer +import kotlin.reflect.KClass +abstract class AbstractDokkaTask( + private val bootstrapClass: KClass = DokkaBootstrap::class +) : DefaultTask(), Configurable { + + @OutputDirectory + var outputDirectory: File = defaultDokkaOutputDirectory() + + @Optional + @InputDirectory + var cacheRoot: File? = null + + @Input + var failOnWarning: Boolean = false -abstract class AbstractDokkaTask : DefaultTask(), Configurable { @Input - var outputDirectory: String = defaultDokkaOutputDirectory().absolutePath + var offlineMode: Boolean = false @Input override val pluginsConfiguration: MutableMap = mutableMapOf() @@ -27,19 +39,26 @@ abstract class AbstractDokkaTask : DefaultTask(), Configurable { val runtime: Configuration = project.maybeCreateDokkaRuntimeConfiguration(name) @TaskAction - protected fun run() { - val kotlinColorsEnabledBefore = System.getProperty(DokkaTask.COLORS_ENABLED_PROPERTY) ?: "false" - System.setProperty(DokkaTask.COLORS_ENABLED_PROPERTY, "false") - try { + protected open fun generateDocumentation() { + DokkaBootstrap(runtime, bootstrapClass).apply { + configure(buildDokkaConfiguration().toJsonString(), createProxyLogger()) generate() - } finally { - System.setProperty(DokkaTask.COLORS_ENABLED_PROPERTY, kotlinColorsEnabledBefore) } } - protected abstract fun generate() + internal abstract fun buildDokkaConfiguration(): DokkaConfigurationImpl + + private fun createProxyLogger(): BiConsumer = BiConsumer { level, message -> + when (level) { + "debug" -> logger.debug(message) + "info" -> logger.info(message) + "progress" -> logger.lifecycle(message) + "warn" -> logger.warn(message) + "error" -> logger.error(message) + } + } - protected fun DokkaBootstrap(bootstrapClassFQName: String): DokkaBootstrap { - return DokkaBootstrap(runtime, bootstrapClassFQName) + init { + group = JavaBasePlugin.DOCUMENTATION_GROUP } } diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ConfigurationExtractor.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ConfigurationExtractor.kt deleted file mode 100644 index 6217703f..00000000 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ConfigurationExtractor.kt +++ /dev/null @@ -1,185 +0,0 @@ -package org.jetbrains.dokka.gradle - -import org.gradle.api.Project -import org.gradle.api.Task -import org.gradle.api.UnknownDomainObjectException -import org.gradle.api.artifacts.ResolveException -import org.gradle.api.file.FileCollection -import org.gradle.api.plugins.JavaPluginConvention -import org.gradle.api.tasks.SourceSet -import org.gradle.api.tasks.compile.AbstractCompile -import org.jetbrains.dokka.ReflectDsl -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension -import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension -import org.jetbrains.kotlin.gradle.dsl.KotlinSingleTargetExtension -import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation -import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import java.io.File -import java.io.Serializable - -class ConfigurationExtractor(private val project: Project) { - fun extractConfiguration(sourceSetName: String): PlatformData? { - val projectExtension = project.extensions.findByType(KotlinProjectExtension::class.java) ?: run { - project.logger.error("Missing kotlin project extension") - return null - } - - val sourceSet = projectExtension.sourceSets.findByName(sourceSetName) ?: run { - project.logger.error("No source set with name '$sourceSetName' found") - return null - } - - val