From 7c56f29fcf550faaf22b81bed4afed8e2f803be1 Mon Sep 17 00:00:00 2001 From: Kamil Doległo Date: Wed, 10 Apr 2019 16:04:02 +0200 Subject: Rework Gradle plugin, autoconfiguration not working yet --- .../main/kotlin/configurationImplementations.kt | 128 +++++ runners/gradle-plugin/src/main/kotlin/dokkaTask.kt | 291 ++++++++++ runners/gradle-plugin/src/main/kotlin/main.kt | 585 +-------------------- 3 files changed, 425 insertions(+), 579 deletions(-) create mode 100644 runners/gradle-plugin/src/main/kotlin/configurationImplementations.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/dokkaTask.kt (limited to 'runners/gradle-plugin/src/main/kotlin') diff --git a/runners/gradle-plugin/src/main/kotlin/configurationImplementations.kt b/runners/gradle-plugin/src/main/kotlin/configurationImplementations.kt new file mode 100644 index 00000000..ccfa0b12 --- /dev/null +++ b/runners/gradle-plugin/src/main/kotlin/configurationImplementations.kt @@ -0,0 +1,128 @@ +package org.jetbrains.dokka.gradle + +import groovy.lang.Closure +import org.gradle.api.Action +import org.gradle.util.ConfigureUtil +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.Platform +import org.jetbrains.dokka.SourceLinkDefinitionImpl +import java.io.File +import java.io.Serializable +import java.net.URL + +class GradleSourceRootImpl: DokkaConfiguration.SourceRoot, Serializable{ + override var path: String = "" + set(value) { + field = File(value).absolutePath + } + + override fun toString(): String = path +} + +class GradlePassConfigurationImpl(@Transient val name: String = ""): DokkaConfiguration.PassConfiguration { + override var classpath: List = emptyList() + override var moduleName: String = "" + override var sourceRoots: MutableList = mutableListOf() + override var samples: List = emptyList() + override var includes: List = emptyList() + override var includeNonPublic: Boolean = false + override var includeRootPackage: Boolean = false + override var reportUndocumented: Boolean = false + override var skipEmptyPackages: Boolean = false + override var skipDeprecated: Boolean = false + override var jdkVersion: Int = 6 + override var sourceLinks: MutableList = mutableListOf() + override var perPackageOptions: MutableList = mutableListOf() + override var externalDocumentationLinks: MutableList = mutableListOf() + override var languageVersion: String? = null + override var apiVersion: String? = null + override var noStdlibLink: Boolean = false + override var noJdkLink: Boolean = false + override var suppressedFiles: List = emptyList() + override var collectInheritedExtensionsFromLibraries: Boolean = false + override var analysisPlatform: Platform = Platform.DEFAULT + override var targets: List = listOf("JVM") + override var sinceKotlin: String = "1.0" + + fun sourceRoot(c: Closure){ + val configured = ConfigureUtil.configure(c, GradleSourceRootImpl()) + sourceRoots.add(configured) + } + + fun sourceRoot(action: Action){ + val sourceRoot = GradleSourceRootImpl() + action.execute(sourceRoot) + sourceRoots.add(sourceRoot) + } + + fun sourceLink(c: Closure){ + val configured = ConfigureUtil.configure(c, GradleSourceLinkDefinitionImpl()) + sourceLinks.add(configured) + } + + fun sourceLink(action: Action){ + val sourceLink = GradleSourceLinkDefinitionImpl() + action.execute(sourceLink) + sourceLinks.add(sourceLink) + } + + fun perPackageOption(c: Closure){ + val configured = ConfigureUtil.configure(c, GradlePackageOptionsImpl()) + perPackageOptions.add(configured) + } + + fun perPackageOption(action: Action){ + val option = GradlePackageOptionsImpl() + action.execute(option) + perPackageOptions.add(option) + } + + fun externalDocumentationLink(c: Closure){ + val link = ConfigureUtil.configure(c, GradleExternalDocumentationLinkImpl()) + externalDocumentationLinks.add(link) + } + + fun externalDocumentationLink(action: Action){ + val link = GradleExternalDocumentationLinkImpl() + action.execute(link) + externalDocumentationLinks.add(link) + } +} + +class GradleSourceLinkDefinitionImpl : DokkaConfiguration.SourceLinkDefinition { + override var path: String = "" + override var url: String = "" + override var lineSuffix: String? = null + + companion object { + fun parseSourceLinkDefinition(srcLink: String): SourceLinkDefinitionImpl { + val (path, urlAndLine) = srcLink.split('=') + return SourceLinkDefinitionImpl( + File(path).canonicalPath, + urlAndLine.substringBefore("#"), + urlAndLine.substringAfter("#", "").let { if (it.isEmpty()) null else "#$it" }) + } + } +} + +class GradleExternalDocumentationLinkImpl : DokkaConfiguration.ExternalDocumentationLink { + override var url: URL = URL("") + override var packageListUrl: URL = URL("") +} + +class GradleDokkaConfigurationImpl: DokkaConfiguration { + override var outputDir: String = "" + override var format: String = "html" + override var generateIndexPages: Boolean = false + override var cacheRoot: String? = null + override var impliedPlatforms: List = emptyList() + override var passesConfigurations: List = emptyList() +} + +class GradlePackageOptionsImpl: DokkaConfiguration.PackageOptions { + override var prefix: String = "" + override val includeNonPublic: Boolean = false + override val reportUndocumented: Boolean = true + override val skipDeprecated: Boolean = true + override val suppress: Boolean = false +} \ No newline at end of file diff --git a/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt new file mode 100644 index 00000000..9abd22ed --- /dev/null +++ b/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt @@ -0,0 +1,291 @@ +package org.jetbrains.dokka.gradle + +import com.google.gson.GsonBuilder +import groovy.lang.Closure +import org.gradle.api.DefaultTask +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.artifacts.Configuration +import org.gradle.api.file.FileCollection +import org.gradle.api.plugins.JavaBasePlugin +import org.gradle.api.plugins.JavaPluginConvention +import org.gradle.api.tasks.* +import org.gradle.api.tasks.compile.AbstractCompile +import org.jetbrains.dokka.DokkaBootstrap +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.ReflectDsl +import org.jetbrains.dokka.ReflectDsl.isNotInstance +import org.jetbrains.dokka.automagicTypedProxy +import java.io.File +import java.io.Serializable +import java.net.URLClassLoader +import java.util.concurrent.Callable +import java.util.function.BiConsumer + +open class DokkaTask : DefaultTask() { + + fun defaultKotlinTasks() = with(ReflectDsl) { + val abstractKotlinCompileClz = try { + project.buildscript.classLoader.loadClass(ABSTRACT_KOTLIN_COMPILE) + } catch (cnfe: ClassNotFoundException) { + logger.warn("$ABSTRACT_KOTLIN_COMPILE class not found, default kotlin tasks ignored") + return@with emptyList() + } + + return@with project.tasks.filter { it isInstance abstractKotlinCompileClz }.filter { "Test" !in it.name } + } + + init { + group = JavaBasePlugin.DOCUMENTATION_GROUP + description = "Generates dokka documentation for Kotlin" + + @Suppress("LeakingThis") + dependsOn(Callable { kotlinTasks.map { it.taskDependencies } }) + } + + @Input + var moduleName: String = "" + @Input + var outputFormat: String = "html" + @OutputDirectory + var outputDirectory: String = "" + var dokkaRuntime: Configuration? = null + + @InputFiles + var classpath: Iterable = arrayListOf() + +// @Input +// var sourceDirs: Iterable = emptyList() +// @Input +// var sourceRoots: MutableList = arrayListOf() + @Input + var dokkaFatJar: Any = "org.jetbrains.dokka:dokka-fatjar:${DokkaVersion.version}" + @Input + var impliedPlatforms: MutableList = arrayListOf() + @Optional + @Input + var cacheRoot: String? = null + @Input + var collectInheritedExtensionsFromLibraries: Boolean = false + @get:Internal + internal val kotlinCompileBasedClasspathAndSourceRoots: ClasspathAndSourceRoots by lazy { extractClasspathAndSourceRootsFromKotlinTasks() } + + protected var externalDocumentationLinks: MutableList = mutableListOf() + + private var kotlinTasksConfigurator: () -> List? = { defaultKotlinTasks() } + private val kotlinTasks: List by lazy { extractKotlinCompileTasks() } + + fun kotlinTasks(taskSupplier: Callable>) { + kotlinTasksConfigurator = { taskSupplier.call() } + } + + fun kotlinTasks(closure: Closure) { + kotlinTasksConfigurator = { closure.call() as? List } + } + +// fun sourceRoot(action: Action) { +// val sourceRoot = GradleSourceRootImpl() +// action.execute(sourceRoot) +// sourceRoots.add(sourceRoot) +// } +// +// fun sourceRoot(closure: Closure) { +// sourceRoot(Action { sourceRoot -> +// closure.delegate = sourceRoot +// closure.call() +// }) +// } + + fun tryResolveFatJar(project: Project): Set { + return try { + dokkaRuntime!!.resolve() + } catch (e: Exception) { + project.parent?.let { tryResolveFatJar(it) } ?: throw e + } + } + + fun loadFatJar() { + if (ClassloaderContainer.fatJarClassLoader == null) { + val jars = if (dokkaFatJar is File) + setOf(dokkaFatJar as File) + else + tryResolveFatJar(project) + ClassloaderContainer.fatJarClassLoader = URLClassLoader(jars.map { it.toURI().toURL() }.toTypedArray(), ClassLoader.getSystemClassLoader().parent) + } + } + + internal data class ClasspathAndSourceRoots(val classpathFileCollection: FileCollection, val sourceRoots: List) : + Serializable + + private fun extractKotlinCompileTasks(): List { + val inputList = (kotlinTasksConfigurator.invoke() ?: emptyList()).filterNotNull() + val (paths, other) = inputList.partition { it is String } + + val taskContainer = project.tasks + + val tasksByPath = paths.map { taskContainer.findByPath(it as String) ?: throw IllegalArgumentException("Task with path '$it' not found") } + + other + .filter { it !is Task || it isNotInstance getAbstractKotlinCompileFor(it) } + .forEach { throw IllegalArgumentException("Illegal entry in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE or String, but was $it") } + + tasksByPath + .filter { it == null || it isNotInstance getAbstractKotlinCompileFor(it) } + .forEach { throw IllegalArgumentException("Illegal task path in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE, but was $it") } + + + return (tasksByPath + other) as List + } + + private fun extractClasspathAndSourceRootsFromKotlinTasks(): ClasspathAndSourceRoots { + + val allTasks = kotlinTasks + + val allClasspath = mutableSetOf() + var allClasspathFileCollection: FileCollection = project.files() + val allSourceRoots = mutableSetOf() + + allTasks.forEach { + logger.debug("Dokka found AbstractKotlinCompile task: $it") + with(ReflectDsl) { + val taskSourceRoots: List = it["sourceRootsContainer"]["sourceRoots"].v() + + val abstractKotlinCompileClz = getAbstractKotlinCompileFor(it)!! + + val taskClasspath: Iterable = + (it["getClasspath", AbstractCompile::class].takeIfIsFunc()?.invoke() + ?: it["compileClasspath", abstractKotlinCompileClz].takeIfIsProp()?.v() + ?: it["getClasspath", abstractKotlinCompileClz]()) + + if (taskClasspath is FileCollection) { + allClasspathFileCollection += taskClasspath + } else { + allClasspath += taskClasspath + } + allSourceRoots += taskSourceRoots.filter { it.exists() } + } + } + + return ClasspathAndSourceRoots(allClasspathFileCollection + project.files(allClasspath), allSourceRoots.toList()) + } + + private fun Iterable.toSourceRoots(): List = this.filter { it.exists() }.map { GradleSourceRootImpl().apply { path = it.path } } + + protected open fun collectSuppressedFiles(sourceRoots: List): List = emptyList() + + @TaskAction + fun generate() { + if (dokkaRuntime == null){ + dokkaRuntime = project.configurations.getByName("dokkaRuntime") + } + + dokkaRuntime?.defaultDependencies{ dependencies -> dependencies.add(project.dependencies.create(dokkaFatJar)) } + val kotlinColorsEnabledBefore = System.getProperty(COLORS_ENABLED_PROPERTY) ?: "false" + System.setProperty(COLORS_ENABLED_PROPERTY, "false") + try { + loadFatJar() + // TODO: implement extracting source roots from kotlin tasks +// val (tasksClasspath, tasksSourceRoots) = kotlinCompileBasedClasspathAndSourceRoots + +// val sourceRoots = collectSourceRoots(sourceDirs, sourceRoots) + tasksSourceRoots.toSourceRoots() +// if (sourceRoots.isEmpty()) { +// logger.warn("No source directories found: skipping dokka generation") +// return +// } + + val bootstrapClass = ClassloaderContainer.fatJarClassLoader!!.loadClass("org.jetbrains.dokka.DokkaBootstrapImpl") + val bootstrapInstance = bootstrapClass.constructors.first().newInstance() + val bootstrapProxy: DokkaBootstrap = automagicTypedProxy(javaClass.classLoader, bootstrapInstance) + + val gson = GsonBuilder().setPrettyPrinting().create() + + val configuration = GradleDokkaConfigurationImpl() + configuration.outputDir = outputDirectory + configuration.format = outputFormat + configuration.generateIndexPages = true + configuration.cacheRoot = cacheRoot + configuration.impliedPlatforms = impliedPlatforms + configuration.passesConfigurations = + (this.extensions.getByName("passConfigurations") as Iterable) + .toList() + .map { defaultPassConfiguration(it) } + + bootstrapProxy.configure( + BiConsumer { level, message -> + when (level) { + "info" -> logger.info(message) + "warn" -> logger.warn(message) + "error" -> logger.error(message) + } + }, + gson.toJson(configuration) + ) + + bootstrapProxy.generate() + + } finally { + System.setProperty(COLORS_ENABLED_PROPERTY, kotlinColorsEnabledBefore) + } + } + + private fun defaultPassConfiguration(passConfig: GradlePassConfigurationImpl): GradlePassConfigurationImpl{ + val (tasksClasspath, tasksSourceRoots) = kotlinCompileBasedClasspathAndSourceRoots + + val fullClasspath = tasksClasspath + classpath + passConfig.moduleName = moduleName + passConfig.classpath = fullClasspath.map { it.absolutePath } + passConfig.samples = passConfig.samples.map { project.file(it).absolutePath } + passConfig.includes = passConfig.includes.map { project.file(it).absolutePath } + passConfig.collectInheritedExtensionsFromLibraries = collectInheritedExtensionsFromLibraries + passConfig.suppressedFiles = collectSuppressedFiles(passConfig.sourceRoots) + passConfig.externalDocumentationLinks.addAll(externalDocumentationLinks) + + return passConfig + } + + private fun collectSourceRoots(sourceDirs: Iterable, sourceRoots: List): List { + val sourceDirs = when { + sourceDirs.any() -> { + logger.info("Dokka: Taking source directories provided by the user") + sourceDirs.toSet() + } + kotlinTasks.isEmpty() -> project.convention.findPlugin(JavaPluginConvention::class.java)?.let { javaPluginConvention -> + logger.info("Dokka: Taking source directories from default java plugin") + val sourceSets = javaPluginConvention.sourceSets.findByName(SourceSet.MAIN_SOURCE_SET_NAME) + sourceSets?.allSource?.srcDirs + } + else -> emptySet() + } + + return sourceRoots + (sourceDirs?.toSourceRoots() ?: emptyList()) + } + +// @Classpath +// fun getInputClasspath(): FileCollection { +// val (classpathFileCollection) = extractClasspathAndSourceRootsFromKotlinTasks() +// return project.files(classpath) + classpathFileCollection +// } + +// @InputFiles +// fun getInputFiles(): FileCollection { +// val (_, tasksSourceRoots) = extractClasspathAndSourceRootsFromKotlinTasks() +// return project.files(tasksSourceRoots.map { project.fileTree(it) }) + +// project.files(collectSourceRoots().map { project.fileTree(File(it.path)) }) + +// project.files(includes) + +// project.files(samples.filterNotNull().map { project.fileTree(it) }) +// } + +// @OutputDirectory +// fun getOutputDirectoryAsFile(): File = project.file(outputDirectory) + + companion object { + const val COLORS_ENABLED_PROPERTY = "kotlin.colors.enabled" + const val ABSTRACT_KOTLIN_COMPILE = "org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile" + + private fun getAbstractKotlinCompileFor(task: Task) = try { + task.project.buildscript.classLoader.loadClass(ABSTRACT_KOTLIN_COMPILE) + } catch (e: ClassNotFoundException) { + null + } + } +} diff --git a/runners/gradle-plugin/src/main/kotlin/main.kt b/runners/gradle-plugin/src/main/kotlin/main.kt index 555dece4..bde6458a 100644 --- a/runners/gradle-plugin/src/main/kotlin/main.kt +++ b/runners/gradle-plugin/src/main/kotlin/main.kt @@ -1,46 +1,28 @@ package org.jetbrains.dokka.gradle -import com.google.gson.GsonBuilder -import groovy.lang.Closure -import org.gradle.api.* -import org.gradle.api.artifacts.Configuration -import org.gradle.api.file.FileCollection -import org.gradle.api.plugins.JavaBasePlugin -import org.gradle.api.plugins.JavaPluginConvention -import org.gradle.api.tasks.* -import org.gradle.api.tasks.Optional -import org.gradle.api.tasks.compile.AbstractCompile -import org.jetbrains.dokka.* -import org.jetbrains.dokka.ReflectDsl.isNotInstance -import org.jetbrains.dokka.gradle.ClassloaderContainer.fatJarClassLoader -import org.jetbrains.dokka.gradle.DokkaVersion.version - +import org.gradle.api.Plugin +import org.gradle.api.Project import java.io.File import java.io.InputStream -import java.io.Serializable -import java.net.URL -import java.net.URLClassLoader import java.util.* -import java.util.concurrent.Callable -import java.util.function.BiConsumer open class DokkaPlugin : Plugin { override fun apply(project: Project) { DokkaVersion.loadFrom(javaClass.getResourceAsStream("/META-INF/gradle-plugins/org.jetbrains.dokka.properties")) - val passConfiguration= project.container(GradlePassConfigurationImpl::class.java) - project.extensions.add("passConfigurations", passConfiguration) - project.tasks.create("dokka", DokkaTask::class.java).apply { dokkaRuntime = project.configurations.create("dokkaRuntime") moduleName = project.name outputDirectory = File(project.buildDir, "dokka").absolutePath } + project.tasks.withType(DokkaTask::class.java) { task -> + val passConfiguration = project.container(GradlePassConfigurationImpl::class.java) + task.extensions.add("passConfigurations", passConfiguration) + } } } - object DokkaVersion { var version: String? = null @@ -51,562 +33,7 @@ object DokkaVersion { } } - object ClassloaderContainer { @JvmField var fatJarClassLoader: ClassLoader? = null -} - - -open class DokkaTask : DefaultTask() { - - fun defaultKotlinTasks() = with(ReflectDsl) { - val abstractKotlinCompileClz = try { - project.buildscript.classLoader.loadClass(ABSTRACT_KOTLIN_COMPILE) - } catch (cnfe: ClassNotFoundException) { - logger.warn("$ABSTRACT_KOTLIN_COMPILE class not found, default kotlin tasks ignored") - return@with emptyList() - } - - return@with project.tasks.filter { it isInstance abstractKotlinCompileClz }.filter { "Test" !in it.name } - } - - init { - group = JavaBasePlugin.DOCUMENTATION_GROUP - description = "Generates dokka documentation for Kotlin" - - @Suppress("LeakingThis") - dependsOn(Callable { kotlinTasks.map { it.taskDependencies } }) - } - - @Input - var moduleName: String = "" - @Input - var outputFormat: String = "html" - var outputDirectory: String = "" - var dokkaRuntime: Configuration? = null - - @InputFiles var classpath: Iterable = arrayListOf() - - @Input - var includes: List = arrayListOf() - @Input - var linkMappings: ArrayList = arrayListOf() - @Input - var samples: List = arrayListOf() - @Input - var jdkVersion: Int = 6 - @Input - var sourceDirs: Iterable = emptyList() - - @Input - var sourceRoots: MutableList = arrayListOf() - - @Input - var dokkaFatJar: Any = "org.jetbrains.dokka:dokka-fatjar:$version" - - @Input var includeNonPublic = false - @Input var skipDeprecated = false - @Input var skipEmptyPackages = true - @Input var reportUndocumented = true - @Input var perPackageOptions: MutableList = arrayListOf() - @Input var impliedPlatforms: MutableList = arrayListOf() - - @Input var externalDocumentationLinks = mutableListOf() - - @Input var noStdlibLink: Boolean = false - - @Input - var noJdkLink: Boolean = false - - @Optional @Input - var cacheRoot: String? = null - - - @Optional @Input - var languageVersion: String? = null - - @Optional @Input - var apiVersion: String? = null - - @Input - var collectInheritedExtensionsFromLibraries: Boolean = false - - @get:Internal - internal val kotlinCompileBasedClasspathAndSourceRoots: ClasspathAndSourceRoots by lazy { extractClasspathAndSourceRootsFromKotlinTasks() } - - @Optional @Input - var targets: List = listOf() - -// @Input var passConfigurations: MutableList = arrayListOf() - -// fun passConfiguration(action: Action) { -// val passConfig = GradlePassConfigurationImpl() -// action.execute(passConfig) -// passConfigurations.add(passConfig) -// } -// -// fun passConfiguration(closure: Closure) { -// passConfiguration(Action { -// closure.delegate = it -// closure.call() -// }) -// } - -// fun passConfiguration(closure: Closure) { -// closure.call() -// passConfiguration = mutableListOf(PassConfigurationImpl(targets = closure.getProperty("targets") as List)) -// } - - private var kotlinTasksConfigurator: () -> List? = { defaultKotlinTasks() } - private val kotlinTasks: List by lazy { extractKotlinCompileTasks() } - - fun kotlinTasks(taskSupplier: Callable>) { - kotlinTasksConfigurator = { taskSupplier.call() } - } - - fun kotlinTasks(closure: Closure) { - kotlinTasksConfigurator = { closure.call() as? List } - } - - fun linkMapping(action: Action) { - val mapping = LinkMapping() - action.execute(mapping) - - if (mapping.path.isEmpty()) { - throw IllegalArgumentException("Link mapping should have dir") - } - if (mapping.url.isEmpty()) { - throw IllegalArgumentException("Link mapping should have url") - } - - linkMappings.add(mapping) - } - - fun linkMapping(closure: Closure) { - linkMapping(Action { mapping -> - closure.delegate = mapping - closure.call() - }) - } - - fun sourceRoot(action: Action) { - val sourceRoot = SourceRoot() - action.execute(sourceRoot) - sourceRoots.add(sourceRoot) - } - - fun sourceRoot(closure: Closure) { - sourceRoot(Action { sourceRoot -> - closure.delegate = sourceRoot - closure.call() - }) - } - - fun packageOptions(action: Action) { - val packageOptions = PackageOptions() - action.execute(packageOptions) - perPackageOptions.add(packageOptions) - } - - fun packageOptions(closure: Closure) { - packageOptions(Action { packageOptions -> - closure.delegate = packageOptions - closure.call() - }) - } - - fun externalDocumentationLink(action: Action) { - val builder = DokkaConfiguration.ExternalDocumentationLink.Builder() - action.execute(builder) - externalDocumentationLinks.add(builder.build()) - } - - fun externalDocumentationLink(closure: Closure) { - externalDocumentationLink(Action { builder -> - closure.delegate = builder - closure.call() - }) - } - - fun tryResolveFatJar(project: Project): Set { - return try { - dokkaRuntime!!.resolve() - } catch (e: Exception) { - project.parent?.let { tryResolveFatJar(it) } ?: throw e - } - } - - fun loadFatJar() { - if (fatJarClassLoader == null) { - val jars = if (dokkaFatJar is File) - setOf(dokkaFatJar as File) - else - tryResolveFatJar(project) - fatJarClassLoader = URLClassLoader(jars.map { it.toURI().toURL() }.toTypedArray(), ClassLoader.getSystemClassLoader().parent) - } - } - - internal data class ClasspathAndSourceRoots(val classpathFileCollection: FileCollection, val sourceRoots: List) : Serializable - - private fun extractKotlinCompileTasks(): List { - val inputList = (kotlinTasksConfigurator.invoke() ?: emptyList()).filterNotNull() - val (paths, other) = inputList.partition { it is String } - - val taskContainer = project.tasks - - val tasksByPath = paths.map { taskContainer.findByPath(it as String) ?: throw IllegalArgumentException("Task with path '$it' not found") } - - other - .filter { it !is Task || it isNotInstance getAbstractKotlinCompileFor(it) } - .forEach { throw IllegalArgumentException("Illegal entry in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE or String, but was $it") } - - tasksByPath - .filter { it == null || it isNotInstance getAbstractKotlinCompileFor(it) } - .forEach { throw IllegalArgumentException("Illegal task path in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE, but was $it") } - - - return (tasksByPath + other) as List - } - - private fun extractClasspathAndSourceRootsFromKotlinTasks(): ClasspathAndSourceRoots { - - val allTasks = kotlinTasks - - val allClasspath = mutableSetOf() - var allClasspathFileCollection: FileCollection = project.files() - val allSourceRoots = mutableSetOf() - - allTasks.forEach { - - logger.debug("Dokka found AbstractKotlinCompile task: $it") - with(ReflectDsl) { - val taskSourceRoots: List = it["sourceRootsContainer"]["sourceRoots"].v() - - val abstractKotlinCompileClz = getAbstractKotlinCompileFor(it)!! - - val taskClasspath: Iterable = - (it["getClasspath", AbstractCompile::class].takeIfIsFunc()?.invoke() - ?: it["compileClasspath", abstractKotlinCompileClz].takeIfIsProp()?.v() - ?: it["getClasspath", abstractKotlinCompileClz]()) - - if (taskClasspath is FileCollection) { - allClasspathFileCollection += taskClasspath - } else { - allClasspath += taskClasspath - } - allSourceRoots += taskSourceRoots.filter { it.exists() } - } - } - - return ClasspathAndSourceRoots(allClasspathFileCollection + project.files(allClasspath), allSourceRoots.toList()) - } - - private fun Iterable.toSourceRoots(): List = this.filter { it.exists() }.map { SourceRoot().apply { path = it.path } } - - protected open fun collectSuppressedFiles(sourceRoots: List): List = emptyList() - - @TaskAction - fun generate() { - if (dokkaRuntime == null){ - dokkaRuntime = project.configurations.getByName("dokkaRuntime") - } - - - dokkaRuntime?.defaultDependencies{ dependencies -> dependencies.add(project.dependencies.create(dokkaFatJar)) } - val kotlinColorsEnabledBefore = System.getProperty(COLORS_ENABLED_PROPERTY) ?: "false" - System.setProperty(COLORS_ENABLED_PROPERTY, "false") - try { - loadFatJar() - - val (tasksClasspath, tasksSourceRoots) = kotlinCompileBasedClasspathAndSourceRoots - - val sourceRoots = collectSourceRoots() + tasksSourceRoots.toSourceRoots() - if (sourceRoots.isEmpty()) { - logger.warn("No source directories found: skipping dokka generation") - return - } - - val fullClasspath = tasksClasspath + classpath - - val bootstrapClass = fatJarClassLoader!!.loadClass("org.jetbrains.dokka.DokkaBootstrapImpl") - val bootstrapInstance = bootstrapClass.constructors.first().newInstance() - val bootstrapProxy: DokkaBootstrap = automagicTypedProxy(javaClass.classLoader, bootstrapInstance) - - val gson = GsonBuilder().setPrettyPrinting().create() - - - val configuration = GradleDokkaConfigurationImpl() - configuration.outputDir = outputDirectory - configuration.format = outputFormat - configuration.generateIndexPages = true - configuration.cacheRoot = cacheRoot - configuration.impliedPlatforms = impliedPlatforms - configuration.passesConfigurations = - (project.extensions.getByName("passConfigurations") as Iterable) - .toList() - .map { defaultPassConfiguration(it) } - -// listOf(PassConfigurationImpl( -// classpath= fullClasspath.map { it.absolutePath }, -// sourceRoots = sourceRoots.map { SourceRootImpl(it.path) }, -// samples = samples.filterNotNull().map { project.file(it).absolutePath }, -// includes = includes.filterNotNull().map { project.file(it).absolutePath }, -// collectInheritedExtensionsFromLibraries = collectInheritedExtensionsFromLibraries, -// perPackageOptions = perPackageOptions.map{PackageOptionsImpl( -// prefix = it.prefix, -// includeNonPublic = it.includeNonPublic, -// reportUndocumented = it.reportUndocumented, -// skipDeprecated = it.skipDeprecated, -// suppress = it.suppress -// )}, -// moduleName = moduleName, -// includeNonPublic = includeNonPublic, -// includeRootPackage = false, -// reportUndocumented = reportUndocumented, -// skipEmptyPackages = skipEmptyPackages, -// skipDeprecated = skipDeprecated, -// jdkVersion = jdkVersion, -// languageVersion = languageVersion, -// apiVersion = apiVersion, -// noStdlibLink = noStdlibLink, -// noJdkLink = noJdkLink, -// suppressedFiles = collectSuppressedFiles(sourceRoots), -// sinceKotlin = "1.0", -// analysisPlatform = Platform.DEFAULT, -// targets = emptyList(), -// sourceLinks = mutableListOf(), // TODO: check this line -// externalDocumentationLinks = externalDocumentationLinks.map { -// ExternalDocumentationLinkImpl(it.url, it.packageListUrl) -// } -// ) -// ) -// ) - - bootstrapProxy.configure( - BiConsumer { level, message -> - when (level) { - "info" -> logger.info(message) - "warn" -> logger.warn(message) - "error" -> logger.error(message) - } - }, - gson.toJson(configuration) - ) - - bootstrapProxy.generate() - - } finally { - System.setProperty(COLORS_ENABLED_PROPERTY, kotlinColorsEnabledBefore) - } - } - - private fun defaultPassConfiguration(passConfig: GradlePassConfigurationImpl): GradlePassConfigurationImpl{ - - fun Closure.setDelegateAndCall(delegate: Any) { - this.delegate = delegate - this.call() - this.delegate - } - - val (tasksClasspath, tasksSourceRoots) = kotlinCompileBasedClasspathAndSourceRoots - - val fullClasspath = tasksClasspath + classpath - passConfig.moduleName = moduleName - passConfig.classpath = fullClasspath.map { it.absolutePath } - passConfig.sourceRoots = sourceRoots.map { SourceRootImpl(it.path) } - passConfig.samples = samples.filterNotNull().map { project.file(it).absolutePath } - passConfig.includes = includes.filterNotNull().map { project.file(it).absolutePath } - passConfig.collectInheritedExtensionsFromLibraries = collectInheritedExtensionsFromLibraries - - passConfig.perPackageOptions = ((passConfig.perPackageOptions as List>).map { - it.setDelegateAndCall(GradlePackageOptionsImpl()) - }) as List - - passConfig.suppressedFiles = collectSuppressedFiles(sourceRoots) - passConfig.sourceLinks = ((passConfig.sourceLinks as List>).map { - it.setDelegateAndCall(GradleSourceLinkDefinitionImpl()) - }) as MutableList // TODO: Parse source links? - - passConfig.externalDocumentationLinks = ((passConfig.externalDocumentationLinks as List>).map { - it.setDelegateAndCall(GradleExternalDocumentationLinkImpl()) - }) as List - - return passConfig - } - - - private fun collectSourceRoots(): List { - val sourceDirs = if (sourceDirs.any()) { - logger.info("Dokka: Taking source directories provided by the user") - sourceDirs.toSet() - } else if (kotlinTasks.isEmpty()) { - project.convention.findPlugin(JavaPluginConvention::class.java)?.let { javaPluginConvention -> - logger.info("Dokka: Taking source directories from default java plugin") - val sourceSets = javaPluginConvention.sourceSets.findByName(SourceSet.MAIN_SOURCE_SET_NAME) - sourceSets?.allSource?.srcDirs - } - } else { - emptySet() - } - - return sourceRoots + (sourceDirs?.toSourceRoots() ?: emptyList()) - } - - - @Classpath - fun getInputClasspath(): FileCollection { - val (classpathFileCollection) = extractClasspathAndSourceRootsFromKotlinTasks() - return project.files(classpath) + classpathFileCollection - } - - @InputFiles - fun getInputFiles(): FileCollection { - val (_, tasksSourceRoots) = extractClasspathAndSourceRootsFromKotlinTasks() - return project.files(tasksSourceRoots.map { project.fileTree(it) }) + - project.files(collectSourceRoots().map { project.fileTree(File(it.path)) }) + - project.files(includes) + - project.files(samples.filterNotNull().map { project.fileTree(it) }) - } - - @OutputDirectory - fun getOutputDirectoryAsFile(): File = project.file(outputDirectory) - - companion object { - const val COLORS_ENABLED_PROPERTY = "kotlin.colors.enabled" - const val ABSTRACT_KOTLIN_COMPILE = "org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile" - - private fun getAbstractKotlinCompileFor(task: Task) = try { - task.project.buildscript.classLoader.loadClass(ABSTRACT_KOTLIN_COMPILE) - } catch (e: ClassNotFoundException) { - null - } - } - -} - -class SourceRoot : DokkaConfiguration.SourceRoot, Serializable { - override var path: String = "" - set(value) { - field = File(value).absolutePath - } - - override fun toString(): String = path -} - -open class LinkMapping : Serializable, DokkaConfiguration.SourceLinkDefinition { - var dir: String - get() = path - set(value) { - if (value.contains("\\")) - throw java.lang.IllegalArgumentException("Incorrect dir property, only Unix based path allowed.") - else path = value - } - - override var path: String = "" - override var url: String = "" - - var suffix: String? - get() = lineSuffix - set(value) { - lineSuffix = value - } - - override var lineSuffix: String? = null - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other?.javaClass != javaClass) return false - - other as LinkMapping - - if (path != other.path) return false - if (url != other.url) return false - if (lineSuffix != other.lineSuffix) return false - - return true - } - - override fun hashCode(): Int { - var result = path.hashCode() - result = 31 * result + url.hashCode() - result = 31 * result + (lineSuffix?.hashCode() ?: 0) - return result - } - - companion object { - const val serialVersionUID: Long = -8133501684312445981L - } -} - -class PackageOptions : Serializable, DokkaConfiguration.PackageOptions { - override var prefix: String = "" - override var includeNonPublic: Boolean = false - override var reportUndocumented: Boolean = true - override var skipDeprecated: Boolean = false - override var suppress: Boolean = false -} - -open class GradlePassConfigurationImpl(@Transient val name: String = ""): DokkaConfiguration.PassConfiguration { - override var classpath: List = emptyList() - override var moduleName: String = "" - override var sourceRoots: List = emptyList() - override var samples: List = emptyList() - override var includes: List = emptyList() - override var includeNonPublic: Boolean = false - override var includeRootPackage: Boolean = false - override var reportUndocumented: Boolean = false - override var skipEmptyPackages: Boolean = false - override var skipDeprecated: Boolean = false - override var jdkVersion: Int = 6 - override var sourceLinks: List = emptyList() - override var perPackageOptions: List = emptyList() - override var externalDocumentationLinks: List = emptyList() - override var languageVersion: String? = null - override var apiVersion: String? = null - override var noStdlibLink: Boolean = false - override var noJdkLink: Boolean = false - override var suppressedFiles: List = emptyList() - override var collectInheritedExtensionsFromLibraries: Boolean = false - override var analysisPlatform: Platform = Platform.DEFAULT - override var targets: List = listOf("JVM") - override var sinceKotlin: String = "1.0" -} - -class GradleSourceLinkDefinitionImpl : DokkaConfiguration.SourceLinkDefinition { - override var path: String = "" - override var url: String = "" - override var lineSuffix: String? = null - - companion object { - fun parseSourceLinkDefinition(srcLink: String): SourceLinkDefinitionImpl { - val (path, urlAndLine) = srcLink.split('=') - return SourceLinkDefinitionImpl( - File(path).canonicalPath, - urlAndLine.substringBefore("#"), - urlAndLine.substringAfter("#", "").let { if (it.isEmpty()) null else "#$it" }) - } - } -} - -class GradleExternalDocumentationLinkImpl : DokkaConfiguration.ExternalDocumentationLink { - override var url: URL = URL("") - override var packageListUrl: URL = URL("") -} - -class GradleDokkaConfigurationImpl: DokkaConfiguration { - override var outputDir: String = "" - override var format: String = "html" - override var generateIndexPages: Boolean = false - override var cacheRoot: String? = null - override var impliedPlatforms: List = emptyList() - override var passesConfigurations: List = emptyList() -} - -class GradlePackageOptionsImpl: DokkaConfiguration.PackageOptions { - override var prefix: String = "" - override val includeNonPublic: Boolean = false - override val reportUndocumented: Boolean = true - override val skipDeprecated: Boolean = true - override val suppress: Boolean = false } \ No newline at end of file -- cgit From 34e4d760d4928a9d97179652764b8d74f99436d3 Mon Sep 17 00:00:00 2001 From: Kamil Doległo Date: Wed, 10 Apr 2019 16:55:17 +0200 Subject: Add extension for configuring dokka with one block less when not using multiplatform --- .../src/main/kotlin/configurationImplementations.kt | 2 +- runners/gradle-plugin/src/main/kotlin/dokkaTask.kt | 11 +++++++---- runners/gradle-plugin/src/main/kotlin/main.kt | 1 + 3 files changed, 9 insertions(+), 5 deletions(-) (limited to 'runners/gradle-plugin/src/main/kotlin') diff --git a/runners/gradle-plugin/src/main/kotlin/configurationImplementations.kt b/runners/gradle-plugin/src/main/kotlin/configurationImplementations.kt index ccfa0b12..3e9db147 100644 --- a/runners/gradle-plugin/src/main/kotlin/configurationImplementations.kt +++ b/runners/gradle-plugin/src/main/kotlin/configurationImplementations.kt @@ -19,7 +19,7 @@ class GradleSourceRootImpl: DokkaConfiguration.SourceRoot, Serializable{ override fun toString(): String = path } -class GradlePassConfigurationImpl(@Transient val name: String = ""): DokkaConfiguration.PassConfiguration { +open class GradlePassConfigurationImpl(@Transient val name: String = ""): DokkaConfiguration.PassConfiguration { override var classpath: List = emptyList() override var moduleName: String = "" override var sourceRoots: MutableList = mutableListOf() diff --git a/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt index 9abd22ed..ed16a909 100644 --- a/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt @@ -199,16 +199,19 @@ open class DokkaTask : DefaultTask() { val gson = GsonBuilder().setPrettyPrinting().create() + val passConfigurationList = + ((this.extensions.getByName("passConfigurations") as Iterable) + + (this.extensions.getByName("passConfiguration") as GradlePassConfigurationImpl)) + .toList() + .map { defaultPassConfiguration(it) } + val configuration = GradleDokkaConfigurationImpl() configuration.outputDir = outputDirectory configuration.format = outputFormat configuration.generateIndexPages = true configuration.cacheRoot = cacheRoot configuration.impliedPlatforms = impliedPlatforms - configuration.passesConfigurations = - (this.extensions.getByName("passConfigurations") as Iterable) - .toList() - .map { defaultPassConfiguration(it) } + configuration.passesConfigurations = passConfigurationList bootstrapProxy.configure( BiConsumer { level, message -> diff --git a/runners/gradle-plugin/src/main/kotlin/main.kt b/runners/gradle-plugin/src/main/kotlin/main.kt index bde6458a..a5918b0b 100644 --- a/runners/gradle-plugin/src/main/kotlin/main.kt +++ b/runners/gradle-plugin/src/main/kotlin/main.kt @@ -19,6 +19,7 @@ open class DokkaPlugin : Plugin { project.tasks.withType(DokkaTask::class.java) { task -> val passConfiguration = project.container(GradlePassConfigurationImpl::class.java) task.extensions.add("passConfigurations", passConfiguration) + task.extensions.create("passConfiguration", GradlePassConfigurationImpl::class.java, "") } } } -- cgit From a6a96e0316fc754c47118fd61b2eac5d4cad1998 Mon Sep 17 00:00:00 2001 From: Kamil Doległo Date: Wed, 10 Apr 2019 17:31:13 +0200 Subject: Add automatic sourceDirs resolving when not using multiproject --- runners/gradle-plugin/src/main/kotlin/dokkaTask.kt | 40 ++++++++-------------- 1 file changed, 14 insertions(+), 26 deletions(-) (limited to 'runners/gradle-plugin/src/main/kotlin') diff --git a/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt index ed16a909..ef9cfd19 100644 --- a/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt @@ -54,10 +54,10 @@ open class DokkaTask : DefaultTask() { @InputFiles var classpath: Iterable = arrayListOf() -// @Input -// var sourceDirs: Iterable = emptyList() -// @Input -// var sourceRoots: MutableList = arrayListOf() + @Input + var sourceDirs: Iterable = emptyList() + @Input + var sourceRoots: MutableList = arrayListOf() @Input var dokkaFatJar: Any = "org.jetbrains.dokka:dokka-fatjar:${DokkaVersion.version}" @Input @@ -83,18 +83,6 @@ open class DokkaTask : DefaultTask() { kotlinTasksConfigurator = { closure.call() as? List } } -// fun sourceRoot(action: Action) { -// val sourceRoot = GradleSourceRootImpl() -// action.execute(sourceRoot) -// sourceRoots.add(sourceRoot) -// } -// -// fun sourceRoot(closure: Closure) { -// sourceRoot(Action { sourceRoot -> -// closure.delegate = sourceRoot -// closure.call() -// }) -// } fun tryResolveFatJar(project: Project): Set { return try { @@ -185,13 +173,9 @@ open class DokkaTask : DefaultTask() { try { loadFatJar() // TODO: implement extracting source roots from kotlin tasks -// val (tasksClasspath, tasksSourceRoots) = kotlinCompileBasedClasspathAndSourceRoots + val (_, tasksSourceRoots) = kotlinCompileBasedClasspathAndSourceRoots -// val sourceRoots = collectSourceRoots(sourceDirs, sourceRoots) + tasksSourceRoots.toSourceRoots() -// if (sourceRoots.isEmpty()) { -// logger.warn("No source directories found: skipping dokka generation") -// return -// } + val sourceRoots = collectSourceRoots(sourceDirs, sourceRoots) + tasksSourceRoots.toSourceRoots() val bootstrapClass = ClassloaderContainer.fatJarClassLoader!!.loadClass("org.jetbrains.dokka.DokkaBootstrapImpl") val bootstrapInstance = bootstrapClass.constructors.first().newInstance() @@ -199,11 +183,15 @@ open class DokkaTask : DefaultTask() { val gson = GsonBuilder().setPrettyPrinting().create() + val passConfigurationExtension: GradlePassConfigurationImpl? = this.extensions.findByName("passConfiguration") as GradlePassConfigurationImpl + val passConfigurationsContainer by lazy { + (this.extensions.getByName("passConfigurations") as Iterable).toList() + } + passConfigurationExtension?.sourceRoots?.addAll(sourceRoots) + val passConfigurationList = - ((this.extensions.getByName("passConfigurations") as Iterable) + - (this.extensions.getByName("passConfiguration") as GradlePassConfigurationImpl)) - .toList() - .map { defaultPassConfiguration(it) } + (passConfigurationExtension?.let {passConfigurationsContainer + it } ?: passConfigurationsContainer) + .map { defaultPassConfiguration(it) } val configuration = GradleDokkaConfigurationImpl() configuration.outputDir = outputDirectory -- cgit From 1cfe0bb4ad850555b20620618349f02b62aac66a Mon Sep 17 00:00:00 2001 From: Kamil Doległo Date: Wed, 10 Apr 2019 17:38:42 +0200 Subject: Change Gradle extension names --- runners/gradle-plugin/src/main/kotlin/main.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'runners/gradle-plugin/src/main/kotlin') diff --git a/runners/gradle-plugin/src/main/kotlin/main.kt b/runners/gradle-plugin/src/main/kotlin/main.kt index a5918b0b..865cba2f 100644 --- a/runners/gradle-plugin/src/main/kotlin/main.kt +++ b/runners/gradle-plugin/src/main/kotlin/main.kt @@ -18,8 +18,8 @@ open class DokkaPlugin : Plugin { } project.tasks.withType(DokkaTask::class.java) { task -> val passConfiguration = project.container(GradlePassConfigurationImpl::class.java) - task.extensions.add("passConfigurations", passConfiguration) - task.extensions.create("passConfiguration", GradlePassConfigurationImpl::class.java, "") + task.extensions.add("multiplatform", passConfiguration) + task.extensions.create("configuration", GradlePassConfigurationImpl::class.java, "") } } } -- cgit From c59e7aade5a8ad1f0f93fa6650d39d3ec2fd2bfa Mon Sep 17 00:00:00 2001 From: Kamil Doległo Date: Wed, 10 Apr 2019 17:40:06 +0200 Subject: Remove some code that looks dead --- runners/gradle-plugin/src/main/kotlin/dokkaTask.kt | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'runners/gradle-plugin/src/main/kotlin') diff --git a/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt index ef9cfd19..c95d1039 100644 --- a/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt @@ -251,24 +251,6 @@ open class DokkaTask : DefaultTask() { return sourceRoots + (sourceDirs?.toSourceRoots() ?: emptyList()) } -// @Classpath -// fun getInputClasspath(): FileCollection { -// val (classpathFileCollection) = extractClasspathAndSourceRootsFromKotlinTasks() -// return project.files(classpath) + classpathFileCollection -// } - -// @InputFiles -// fun getInputFiles(): FileCollection { -// val (_, tasksSourceRoots) = extractClasspathAndSourceRootsFromKotlinTasks() -// return project.files(tasksSourceRoots.map { project.fileTree(it) }) + -// project.files(collectSourceRoots().map { project.fileTree(File(it.path)) }) + -// project.files(includes) + -// project.files(samples.filterNotNull().map { project.fileTree(it) }) -// } - -// @OutputDirectory -// fun getOutputDirectoryAsFile(): File = project.file(outputDirectory) - companion object { const val COLORS_ENABLED_PROPERTY = "kotlin.colors.enabled" const val ABSTRACT_KOTLIN_COMPILE = "org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile" -- cgit From 5de1d68ca8510f7bc3601c3516ecb111f7abe44b Mon Sep 17 00:00:00 2001 From: Kamil Doległo Date: Thu, 11 Apr 2019 14:46:58 +0200 Subject: Extract extension names to consts --- runners/gradle-plugin/src/main/kotlin/dokkaTask.kt | 5 +++-- runners/gradle-plugin/src/main/kotlin/main.kt | 7 +++++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'runners/gradle-plugin/src/main/kotlin') diff --git a/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt index c95d1039..825830c5 100644 --- a/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt @@ -183,9 +183,10 @@ open class DokkaTask : DefaultTask() { val gson = GsonBuilder().setPrettyPrinting().create() - val passConfigurationExtension: GradlePassConfigurationImpl? = this.extensions.findByName("passConfiguration") as GradlePassConfigurationImpl + val passConfigurationExtension: GradlePassConfigurationImpl? = this.extensions.findByName( + CONFIGURATION_EXTENSION_NAME) as GradlePassConfigurationImpl? val passConfigurationsContainer by lazy { - (this.extensions.getByName("passConfigurations") as Iterable).toList() + (this.extensions.getByName(MULTIPLATFORM_EXTENSION_NAME) as Iterable).toList() } passConfigurationExtension?.sourceRoots?.addAll(sourceRoots) diff --git a/runners/gradle-plugin/src/main/kotlin/main.kt b/runners/gradle-plugin/src/main/kotlin/main.kt index 865cba2f..dd216f89 100644 --- a/runners/gradle-plugin/src/main/kotlin/main.kt +++ b/runners/gradle-plugin/src/main/kotlin/main.kt @@ -6,6 +6,9 @@ import java.io.File import java.io.InputStream import java.util.* +internal const val CONFIGURATION_EXTENSION_NAME = "configuration" +internal const val MULTIPLATFORM_EXTENSION_NAME = "multiplatform" + open class DokkaPlugin : Plugin { override fun apply(project: Project) { @@ -18,8 +21,8 @@ open class DokkaPlugin : Plugin { } project.tasks.withType(DokkaTask::class.java) { task -> val passConfiguration = project.container(GradlePassConfigurationImpl::class.java) - task.extensions.add("multiplatform", passConfiguration) - task.extensions.create("configuration", GradlePassConfigurationImpl::class.java, "") + task.extensions.add(MULTIPLATFORM_EXTENSION_NAME, passConfiguration) + task.extensions.create(CONFIGURATION_EXTENSION_NAME, GradlePassConfigurationImpl::class.java, "") } } } -- cgit From 64305246bf6a22a4111c11dc3c671297cf223393 Mon Sep 17 00:00:00 2001 From: Kamil Doległo Date: Thu, 11 Apr 2019 14:56:38 +0200 Subject: Remove dead code, create package, add comment --- .../gradle-plugin/src/main/kotlin/ProxyUtils.kt | 46 ---- .../main/kotlin/configurationImplementations.kt | 128 ---------- runners/gradle-plugin/src/main/kotlin/dokkaTask.kt | 265 --------------------- runners/gradle-plugin/src/main/kotlin/main.kt | 43 ---- .../org/jetbrains/dokka/gradle/ProxyUtils.kt | 46 ++++ .../dokka/gradle/configurationImplementations.kt | 117 +++++++++ .../kotlin/org/jetbrains/dokka/gradle/dokkaTask.kt | 265 +++++++++++++++++++++ .../main/kotlin/org/jetbrains/dokka/gradle/main.kt | 50 ++++ 8 files changed, 478 insertions(+), 482 deletions(-) delete mode 100644 runners/gradle-plugin/src/main/kotlin/ProxyUtils.kt delete mode 100644 runners/gradle-plugin/src/main/kotlin/configurationImplementations.kt delete mode 100644 runners/gradle-plugin/src/main/kotlin/dokkaTask.kt delete mode 100644 runners/gradle-plugin/src/main/kotlin/main.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ProxyUtils.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/dokkaTask.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt (limited to 'runners/gradle-plugin/src/main/kotlin') diff --git a/runners/gradle-plugin/src/main/kotlin/ProxyUtils.kt b/runners/gradle-plugin/src/main/kotlin/ProxyUtils.kt deleted file mode 100644 index 7bdf2f9d..00000000 --- a/runners/gradle-plugin/src/main/kotlin/ProxyUtils.kt +++ /dev/null @@ -1,46 +0,0 @@ -package org.jetbrains.dokka - -import java.lang.reflect.InvocationHandler -import java.lang.reflect.InvocationTargetException -import java.lang.reflect.Method -import java.lang.reflect.Proxy - - -/** - * Warning! Hard reflection magic used here. - * - * Creates [java.lang.reflect.Proxy] with pass through invocation algorithm, - * to create access proxy for [delegate] into [targetClassLoader]. - */ -@Suppress("UNCHECKED_CAST") -inline fun automagicTypedProxy(targetClassLoader: ClassLoader, delegate: Any): T = - automagicProxy(targetClassLoader, T::class.java, delegate) as T - - -/** - * Warning! Hard reflection magic used here. - * - * Creates [java.lang.reflect.Proxy] with pass through invocation algorithm, - * to create access proxy for [delegate] into [targetClassLoader]. - * - */ -fun automagicProxy(targetClassLoader: ClassLoader, targetType: Class<*>, delegate: Any): Any = - Proxy.newProxyInstance( - targetClassLoader, - arrayOf(targetType), - DelegatedInvocationHandler(delegate) - ) - -class DelegatedInvocationHandler(private val delegate: Any) : InvocationHandler { - - @Throws(Throwable::class) - override fun invoke(proxy: Any, method: Method, args: Array?): Any? { - val delegateMethod = delegate.javaClass.getMethod(method.name, *method.parameterTypes) - try { - delegateMethod.isAccessible = true - return delegateMethod.invoke(delegate, *(args ?: emptyArray())) - } catch (ex: InvocationTargetException) { - throw ex.targetException - } - } -} diff --git a/runners/gradle-plugin/src/main/kotlin/configurationImplementations.kt b/runners/gradle-plugin/src/main/kotlin/configurationImplementations.kt deleted file mode 100644 index 3e9db147..00000000 --- a/runners/gradle-plugin/src/main/kotlin/configurationImplementations.kt +++ /dev/null @@ -1,128 +0,0 @@ -package org.jetbrains.dokka.gradle - -import groovy.lang.Closure -import org.gradle.api.Action -import org.gradle.util.ConfigureUtil -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.Platform -import org.jetbrains.dokka.SourceLinkDefinitionImpl -import java.io.File -import java.io.Serializable -import java.net.URL - -class GradleSourceRootImpl: DokkaConfiguration.SourceRoot, Serializable{ - override var path: String = "" - set(value) { - field = File(value).absolutePath - } - - override fun toString(): String = path -} - -open class GradlePassConfigurationImpl(@Transient val name: String = ""): DokkaConfiguration.PassConfiguration { - override var classpath: List = emptyList() - override var moduleName: String = "" - override var sourceRoots: MutableList = mutableListOf() - override var samples: List = emptyList() - override var includes: List = emptyList() - override var includeNonPublic: Boolean = false - override var includeRootPackage: Boolean = false - override var reportUndocumented: Boolean = false - override var skipEmptyPackages: Boolean = false - override var skipDeprecated: Boolean = false - override var jdkVersion: Int = 6 - override var sourceLinks: MutableList = mutableListOf() - override var perPackageOptions: MutableList = mutableListOf() - override var externalDocumentationLinks: MutableList = mutableListOf() - override var languageVersion: String? = null - override var apiVersion: String? = null - override var noStdlibLink: Boolean = false - override var noJdkLink: Boolean = false - override var suppressedFiles: List = emptyList() - override var collectInheritedExtensionsFromLibraries: Boolean = false - override var analysisPlatform: Platform = Platform.DEFAULT - override var targets: List = listOf("JVM") - override var sinceKotlin: String = "1.0" - - fun sourceRoot(c: Closure){ - val configured = ConfigureUtil.configure(c, GradleSourceRootImpl()) - sourceRoots.add(configured) - } - - fun sourceRoot(action: Action){ - val sourceRoot = GradleSourceRootImpl() - action.execute(sourceRoot) - sourceRoots.add(sourceRoot) - } - - fun sourceLink(c: Closure){ - val configured = ConfigureUtil.configure(c, GradleSourceLinkDefinitionImpl()) - sourceLinks.add(configured) - } - - fun sourceLink(action: Action){ - val sourceLink = GradleSourceLinkDefinitionImpl() - action.execute(sourceLink) - sourceLinks.add(sourceLink) - } - - fun perPackageOption(c: Closure){ - val configured = ConfigureUtil.configure(c, GradlePackageOptionsImpl()) - perPackageOptions.add(configured) - } - - fun perPackageOption(action: Action){ - val option = GradlePackageOptionsImpl() - action.execute(option) - perPackageOptions.add(option) - } - - fun externalDocumentationLink(c: Closure){ - val link = ConfigureUtil.configure(c, GradleExternalDocumentationLinkImpl()) - externalDocumentationLinks.add(link) - } - - fun externalDocumentationLink(action: Action){ - val link = GradleExternalDocumentationLinkImpl() - action.execute(link) - externalDocumentationLinks.add(link) - } -} - -class GradleSourceLinkDefinitionImpl : DokkaConfiguration.SourceLinkDefinition { - override var path: String = "" - override var url: String = "" - override var lineSuffix: String? = null - - companion object { - fun parseSourceLinkDefinition(srcLink: String): SourceLinkDefinitionImpl { - val (path, urlAndLine) = srcLink.split('=') - return SourceLinkDefinitionImpl( - File(path).canonicalPath, - urlAndLine.substringBefore("#"), - urlAndLine.substringAfter("#", "").let { if (it.isEmpty()) null else "#$it" }) - } - } -} - -class GradleExternalDocumentationLinkImpl : DokkaConfiguration.ExternalDocumentationLink { - override var url: URL = URL("") - override var packageListUrl: URL = URL("") -} - -class GradleDokkaConfigurationImpl: DokkaConfiguration { - override var outputDir: String = "" - override var format: String = "html" - override var generateIndexPages: Boolean = false - override var cacheRoot: String? = null - override var impliedPlatforms: List = emptyList() - override var passesConfigurations: List = emptyList() -} - -class GradlePackageOptionsImpl: DokkaConfiguration.PackageOptions { - override var prefix: String = "" - override val includeNonPublic: Boolean = false - override val reportUndocumented: Boolean = true - override val skipDeprecated: Boolean = true - override val suppress: Boolean = false -} \ No newline at end of file diff --git a/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt deleted file mode 100644 index 825830c5..00000000 --- a/runners/gradle-plugin/src/main/kotlin/dokkaTask.kt +++ /dev/null @@ -1,265 +0,0 @@ -package org.jetbrains.dokka.gradle - -import com.google.gson.GsonBuilder -import groovy.lang.Closure -import org.gradle.api.DefaultTask -import org.gradle.api.Project -import org.gradle.api.Task -import org.gradle.api.artifacts.Configuration -import org.gradle.api.file.FileCollection -import org.gradle.api.plugins.JavaBasePlugin -import org.gradle.api.plugins.JavaPluginConvention -import org.gradle.api.tasks.* -import org.gradle.api.tasks.compile.AbstractCompile -import org.jetbrains.dokka.DokkaBootstrap -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.ReflectDsl -import org.jetbrains.dokka.ReflectDsl.isNotInstance -import org.jetbrains.dokka.automagicTypedProxy -import java.io.File -import java.io.Serializable -import java.net.URLClassLoader -import java.util.concurrent.Callable -import java.util.function.BiConsumer - -open class DokkaTask : DefaultTask() { - - fun defaultKotlinTasks() = with(ReflectDsl) { - val abstractKotlinCompileClz = try { - project.buildscript.classLoader.loadClass(ABSTRACT_KOTLIN_COMPILE) - } catch (cnfe: ClassNotFoundException) { - logger.warn("$ABSTRACT_KOTLIN_COMPILE class not found, default kotlin tasks ignored") - return@with emptyList() - } - - return@with project.tasks.filter { it isInstance abstractKotlinCompileClz }.filter { "Test" !in it.name } - } - - init { - group = JavaBasePlugin.DOCUMENTATION_GROUP - description = "Generates dokka documentation for Kotlin" - - @Suppress("LeakingThis") - dependsOn(Callable { kotlinTasks.map { it.taskDependencies } }) - } - - @Input - var moduleName: String = "" - @Input - var outputFormat: String = "html" - @OutputDirectory - var outputDirectory: String = "" - var dokkaRuntime: Configuration? = null - - @InputFiles - var classpath: Iterable = arrayListOf() - - @Input - var sourceDirs: Iterable = emptyList() - @Input - var sourceRoots: MutableList = arrayListOf() - @Input - var dokkaFatJar: Any = "org.jetbrains.dokka:dokka-fatjar:${DokkaVersion.version}" - @Input - var impliedPlatforms: MutableList = arrayListOf() - @Optional - @Input - var cacheRoot: String? = null - @Input - var collectInheritedExtensionsFromLibraries: Boolean = false - @get:Internal - internal val kotlinCompileBasedClasspathAndSourceRoots: ClasspathAndSourceRoots by lazy { extractClasspathAndSourceRootsFromKotlinTasks() } - - protected var externalDocumentationLinks: MutableList = mutableListOf() - - private var kotlinTasksConfigurator: () -> List? = { defaultKotlinTasks() } - private val kotlinTasks: List by lazy { extractKotlinCompileTasks() } - - fun kotlinTasks(taskSupplier: Callable>) { - kotlinTasksConfigurator = { taskSupplier.call() } - } - - fun kotlinTasks(closure: Closure) { - kotlinTasksConfigurator = { closure.call() as? List } - } - - - fun tryResolveFatJar(project: Project): Set { - return try { - dokkaRuntime!!.resolve() - } catch (e: Exception) { - project.parent?.let { tryResolveFatJar(it) } ?: throw e - } - } - - fun loadFatJar() { - if (ClassloaderContainer.fatJarClassLoader == null) { - val jars = if (dokkaFatJar is File) - setOf(dokkaFatJar as File) - else - tryResolveFatJar(project) - ClassloaderContainer.fatJarClassLoader = URLClassLoader(jars.map { it.toURI().toURL() }.toTypedArray(), ClassLoader.getSystemClassLoader().parent) - } - } - - internal data class ClasspathAndSourceRoots(val classpathFileCollection: FileCollection, val sourceRoots: List) : - Serializable - - private fun extractKotlinCompileTasks(): List { - val inputList = (kotlinTasksConfigurator.invoke() ?: emptyList()).filterNotNull() - val (paths, other) = inputList.partition { it is String } - - val taskContainer = project.tasks - - val tasksByPath = paths.map { taskContainer.findByPath(it as String) ?: throw IllegalArgumentException("Task with path '$it' not found") } - - other - .filter { it !is Task || it isNotInstance getAbstractKotlinCompileFor(it) } - .forEach { throw IllegalArgumentException("Illegal entry in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE or String, but was $it") } - - tasksByPath - .filter { it == null || it isNotInstance getAbstractKotlinCompileFor(it) } - .forEach { throw IllegalArgumentException("Illegal task path in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE, but was $it") } - - - return (tasksByPath + other) as List - } - - private fun extractClasspathAndSourceRootsFromKotlinTasks(): ClasspathAndSourceRoots { - - val allTasks = kotlinTasks - - val allClasspath = mutableSetOf() - var allClasspathFileCollection: FileCollection = project.files() - val allSourceRoots = mutableSetOf() - - allTasks.forEach { - logger.debug("Dokka found AbstractKotlinCompile task: $it") - with(ReflectDsl) { - val taskSourceRoots: List = it["sourceRootsContainer"]["sourceRoots"].v() - - val abstractKotlinCompileClz = getAbstractKotlinCompileFor(it)!! - - val taskClasspath: Iterable = - (it["getClasspath", AbstractCompile::class].takeIfIsFunc()?.invoke() - ?: it["compileClasspath", abstractKotlinCompileClz].takeIfIsProp()?.v() - ?: it["getClasspath", abstractKotlinCompileClz]()) - - if (taskClasspath is FileCollection) { - allClasspathFileCollection += taskClasspath - } else { - allClasspath += taskClasspath - } - allSourceRoots += taskSourceRoots.filter { it.exists() } - } - } - - return ClasspathAndSourceRoots(allClasspathFileCollection + project.files(allClasspath), allSourceRoots.toList()) - } - - private fun Iterable.toSourceRoots(): List = this.filter { it.exists() }.map { GradleSourceRootImpl().apply { path = it.path } } - - protected open fun collectSuppressedFiles(sourceRoots: List): List = emptyList() - - @TaskAction - fun generate() { - if (dokkaRuntime == null){ - dokkaRuntime = project.configurations.getByName("dokkaRuntime") - } - - dokkaRuntime?.defaultDependencies{ dependencies -> dependencies.add(project.dependencies.create(dokkaFatJar)) } - val kotlinColorsEnabledBefore = System.getProperty(COLORS_ENABLED_PROPERTY) ?: "false" - System.setProperty(COLORS_ENABLED_PROPERTY, "false") - try { - loadFatJar() - // TODO: implement extracting source roots from kotlin tasks - val (_, tasksSourceRoots) = kotlinCompileBasedClasspathAndSourceRoots - - val sourceRoots = collectSourceRoots(sourceDirs, sourceRoots) + tasksSourceRoots.toSourceRoots() - - val bootstrapClass = ClassloaderContainer.fatJarClassLoader!!.loadClass("org.jetbrains.dokka.DokkaBootstrapImpl") - val bootstrapInstance = bootstrapClass.constructors.first().newInstance() - val bootstrapProxy: DokkaBootstrap = automagicTypedProxy(javaClass.classLoader, bootstrapInstance) - - val gson = GsonBuilder().setPrettyPrinting().create() - - val passConfigurationExtension: GradlePassConfigurationImpl? = this.extensions.findByName( - CONFIGURATION_EXTENSION_NAME) as GradlePassConfigurationImpl? - val passConfigurationsContainer by lazy { - (this.extensions.getByName(MULTIPLATFORM_EXTENSION_NAME) as Iterable).toList() - } - passConfigurationExtension?.sourceRoots?.addAll(sourceRoots) - - val passConfigurationList = - (passConfigurationExtension?.let {passConfigurationsContainer + it } ?: passConfigurationsContainer) - .map { defaultPassConfiguration(it) } - - val configuration = GradleDokkaConfigurationImpl() - configuration.outputDir = outputDirectory - configuration.format = outputFormat - configuration.generateIndexPages = true - configuration.cacheRoot = cacheRoot - configuration.impliedPlatforms = impliedPlatforms - configuration.passesConfigurations = passConfigurationList - - bootstrapProxy.configure( - BiConsumer { level, message -> - when (level) { - "info" -> logger.info(message) - "warn" -> logger.warn(message) - "error" -> logger.error(message) - } - }, - gson.toJson(configuration) - ) - - bootstrapProxy.generate() - - } finally { - System.setProperty(COLORS_ENABLED_PROPERTY, kotlinColorsEnabledBefore) - } - } - - private fun defaultPassConfiguration(passConfig: GradlePassConfigurationImpl): GradlePassConfigurationImpl{ - val (tasksClasspath, tasksSourceRoots) = kotlinCompileBasedClasspathAndSourceRoots - - val fullClasspath = tasksClasspath + classpath - passConfig.moduleName = moduleName - passConfig.classpath = fullClasspath.map { it.absolutePath } - passConfig.samples = passConfig.samples.map { project.file(it).absolutePath } - passConfig.includes = passConfig.includes.map { project.file(it).absolutePath } - passConfig.collectInheritedExtensionsFromLibraries = collectInheritedExtensionsFromLibraries - passConfig.suppressedFiles = collectSuppressedFiles(passConfig.sourceRoots) - passConfig.externalDocumentationLinks.addAll(externalDocumentationLinks) - - return passConfig - } - - private fun collectSourceRoots(sourceDirs: Iterable, sourceRoots: List): List { - val sourceDirs = when { - sourceDirs.any() -> { - logger.info("Dokka: Taking source directories provided by the user") - sourceDirs.toSet() - } - kotlinTasks.isEmpty() -> project.convention.findPlugin(JavaPluginConvention::class.java)?.let { javaPluginConvention -> - logger.info("Dokka: Taking source directories from default java plugin") - val sourceSets = javaPluginConvention.sourceSets.findByName(SourceSet.MAIN_SOURCE_SET_NAME) - sourceSets?.allSource?.srcDirs - } - else -> emptySet() - } - - return sourceRoots + (sourceDirs?.toSourceRoots() ?: emptyList()) - } - - companion object { - const val COLORS_ENABLED_PROPERTY = "kotlin.colors.enabled" - const val ABSTRACT_KOTLIN_COMPILE = "org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile" - - private fun getAbstractKotlinCompileFor(task: Task) = try { - task.project.buildscript.classLoader.loadClass(ABSTRACT_KOTLIN_COMPILE) - } catch (e: ClassNotFoundException) { - null - } - } -} diff --git a/runners/gradle-plugin/src/main/kotlin/main.kt b/runners/gradle-plugin/src/main/kotlin/main.kt deleted file mode 100644 index dd216f89..00000000 --- a/runners/gradle-plugin/src/main/kotlin/main.kt +++ /dev/null @@ -1,43 +0,0 @@ -package org.jetbrains.dokka.gradle - -import org.gradle.api.Plugin -import org.gradle.api.Project -import java.io.File -import java.io.InputStream -import java.util.* - -internal const val CONFIGURATION_EXTENSION_NAME = "configuration" -internal const val MULTIPLATFORM_EXTENSION_NAME = "multiplatform" - -open class DokkaPlugin : Plugin { - - override fun apply(project: Project) { - DokkaVersion.loadFrom(javaClass.getResourceAsStream("/META-INF/gradle-plugins/org.jetbrains.dokka.properties")) - - project.tasks.create("dokka", DokkaTask::class.java).apply { - dokkaRuntime = project.configurations.create("dokkaRuntime") - moduleName = project.name - outputDirectory = File(project.buildDir, "dokka").absolutePath - } - project.tasks.withType(DokkaTask::class.java) { task -> - val passConfiguration = project.container(GradlePassConfigurationImpl::class.java) - task.extensions.add(MULTIPLATFORM_EXTENSION_NAME, passConfiguration) - task.extensions.create(CONFIGURATION_EXTENSION_NAME, GradlePassConfigurationImpl::class.java, "") - } - } -} - -object DokkaVersion { - var version: String? = null - - fun loadFrom(stream: InputStream) { - version = Properties().apply { - load(stream) - }.getProperty("dokka-version") - } -} - -object ClassloaderContainer { - @JvmField - var fatJarClassLoader: ClassLoader? = null -} \ No newline at end of file diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ProxyUtils.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ProxyUtils.kt new file mode 100644 index 00000000..61c9e773 --- /dev/null +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ProxyUtils.kt @@ -0,0 +1,46 @@ +package org.jetbrains.dokka.gradle + +import java.lang.reflect.InvocationHandler +import java.lang.reflect.InvocationTargetException +import java.lang.reflect.Method +import java.lang.reflect.Proxy + + +/** + * Warning! Hard reflection magic used here. + * + * Creates [java.lang.reflect.Proxy] with pass through invocation algorithm, + * to create access proxy for [delegate] into [targetClassLoader]. + */ +@Suppress("UNCHECKED_CAST") +inline fun automagicTypedProxy(targetClassLoader: ClassLoader, delegate: Any): T = + automagicProxy(targetClassLoader, T::class.java, delegate) as T + + +/** + * Warning! Hard reflection magic used here. + * + * Creates [java.lang.reflect.Proxy] with pass through invocation algorithm, + * to create access proxy for [delegate] into [targetClassLoader]. + * + */ +fun automagicProxy(targetClassLoader: ClassLoader, targetType: Class<*>, delegate: Any): Any = + Proxy.newProxyInstance( + targetClassLoader, + arrayOf(targetType), + DelegatedInvocationHandler(delegate) + ) + +class DelegatedInvocationHandler(private val delegate: Any) : InvocationHandler { + + @Throws(Throwable::class) + override fun invoke(proxy: Any, method: Method, args: Array?): Any? { + val delegateMethod = delegate.javaClass.getMethod(method.name, *method.parameterTypes) + try { + delegateMethod.isAccessible = true + return delegateMethod.invoke(delegate, *(args ?: emptyArray())) + } catch (ex: InvocationTargetException) { + throw ex.targetException + } + } +} diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt new file mode 100644 index 00000000..bab36f29 --- /dev/null +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt @@ -0,0 +1,117 @@ +package org.jetbrains.dokka.gradle + +import groovy.lang.Closure +import org.gradle.api.Action +import org.gradle.util.ConfigureUtil +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.Platform +import java.io.File +import java.io.Serializable +import java.net.URL + +class GradleSourceRootImpl: DokkaConfiguration.SourceRoot, Serializable{ + override var path: String = "" + set(value) { + field = File(value).absolutePath + } + + override fun toString(): String = path +} + +open class GradlePassConfigurationImpl(@Transient val name: String = ""): DokkaConfiguration.PassConfiguration { + override var classpath: List = emptyList() + override var moduleName: String = "" + override var sourceRoots: MutableList = mutableListOf() + override var samples: List = emptyList() + override var includes: List = emptyList() + override var includeNonPublic: Boolean = false + override var includeRootPackage: Boolean = false + override var reportUndocumented: Boolean = false + override var skipEmptyPackages: Boolean = false + override var skipDeprecated: Boolean = false + override var jdkVersion: Int = 6 + override var sourceLinks: MutableList = mutableListOf() + override var perPackageOptions: MutableList = mutableListOf() + override var externalDocumentationLinks: MutableList = mutableListOf() + override var languageVersion: String? = null + override var apiVersion: String? = null + override var noStdlibLink: Boolean = false + override var noJdkLink: Boolean = false + override var suppressedFiles: List = emptyList() + override var collectInheritedExtensionsFromLibraries: Boolean = false + override var analysisPlatform: Platform = Platform.DEFAULT + override var targets: List = listOf("JVM") + override var sinceKotlin: String = "1.0" + + fun sourceRoot(c: Closure){ + val configured = ConfigureUtil.configure(c, GradleSourceRootImpl()) + sourceRoots.add(configured) + } + + fun sourceRoot(action: Action){ + val sourceRoot = GradleSourceRootImpl() + action.execute(sourceRoot) + sourceRoots.add(sourceRoot) + } + + fun sourceLink(c: Closure){ + val configured = ConfigureUtil.configure(c, GradleSourceLinkDefinitionImpl()) + sourceLinks.add(configured) + } + + fun sourceLink(action: Action){ + val sourceLink = GradleSourceLinkDefinitionImpl() + action.execute(sourceLink) + sourceLinks.add(sourceLink) + } + + fun perPackageOption(c: Closure){ + val configured = ConfigureUtil.configure(c, GradlePackageOptionsImpl()) + perPackageOptions.add(configured) + } + + fun perPackageOption(action: Action){ + val option = GradlePackageOptionsImpl() + action.execute(option) + perPackageOptions.add(option) + } + + fun externalDocumentationLink(c: Closure){ + val link = ConfigureUtil.configure(c, GradleExternalDocumentationLinkImpl()) + externalDocumentationLinks.add(link) + } + + fun externalDocumentationLink(action: Action){ + val link = GradleExternalDocumentationLinkImpl() + action.execute(link) + externalDocumentationLinks.add(link) + } +} + +class GradleSourceLinkDefinitionImpl : DokkaConfiguration.SourceLinkDefinition { + override var path: String = "" + override var url: String = "" + override var lineSuffix: String? = null +} + +class GradleExternalDocumentationLinkImpl : DokkaConfiguration.ExternalDocumentationLink { + override var url: URL = URL("") + override var packageListUrl: URL = URL("") +} + +class GradleDokkaConfigurationImpl: DokkaConfiguration { + override var outputDir: String = "" + override var format: String = "html" + override var generateIndexPages: Boolean = false + override var cacheRoot: String? = null + override var impliedPlatforms: List = emptyList() + override var passesConfigurations: List = emptyList() +} + +class GradlePackageOptionsImpl: DokkaConfiguration.PackageOptions { + override var prefix: String = "" + override val includeNonPublic: Boolean = false + override val reportUndocumented: Boolean = true + override val skipDeprecated: Boolean = true + override val suppress: Boolean = false +} \ No newline at end of file diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/dokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/dokkaTask.kt new file mode 100644 index 00000000..0d78461c --- /dev/null +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/dokkaTask.kt @@ -0,0 +1,265 @@ +package org.jetbrains.dokka.gradle + +import com.google.gson.GsonBuilder +import groovy.lang.Closure +import org.gradle.api.DefaultTask +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.artifacts.Configuration +import org.gradle.api.file.FileCollection +import org.gradle.api.plugins.JavaBasePlugin +import org.gradle.api.plugins.JavaPluginConvention +import org.gradle.api.tasks.* +import org.gradle.api.tasks.compile.AbstractCompile +import org.jetbrains.dokka.DokkaBootstrap +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.ReflectDsl +import org.jetbrains.dokka.ReflectDsl.isNotInstance +import java.io.File +import java.io.Serializable +import java.net.URLClassLoader +import java.util.concurrent.Callable +import java.util.function.BiConsumer + +open class DokkaTask : DefaultTask() { + + fun defaultKotlinTasks() = with(ReflectDsl) { + val abstractKotlinCompileClz = try { + project.buildscript.classLoader.loadClass(ABSTRACT_KOTLIN_COMPILE) + } catch (cnfe: ClassNotFoundException) { + logger.warn("$ABSTRACT_KOTLIN_COMPILE class not found, default kotlin tasks ignored") + return@with emptyList() + } + + return@with project.tasks.filter { it isInstance abstractKotlinCompileClz }.filter { "Test" !in it.name } + } + + init { + group = JavaBasePlugin.DOCUMENTATION_GROUP + description = "Generates dokka documentation for Kotlin" + + @Suppress("LeakingThis") + dependsOn(Callable { kotlinTasks.map { it.taskDependencies } }) + } + + @Input + var moduleName: String = "" + @Input + var outputFormat: String = "html" + @OutputDirectory + var outputDirectory: String = "" + var dokkaRuntime: Configuration? = null + + @InputFiles + var classpath: Iterable = arrayListOf() + + @Input + var sourceDirs: Iterable = emptyList() + @Input + var sourceRoots: MutableList = arrayListOf() + @Input + var dokkaFatJar: Any = "org.jetbrains.dokka:dokka-fatjar:${DokkaVersion.version}" + @Input + var impliedPlatforms: MutableList = arrayListOf() + @Optional + @Input + var cacheRoot: String? = null + @Input + var collectInheritedExtensionsFromLibraries: Boolean = false + @get:Internal + internal val kotlinCompileBasedClasspathAndSourceRoots: ClasspathAndSourceRoots by lazy { extractClasspathAndSourceRootsFromKotlinTasks() } + + protected var externalDocumentationLinks: MutableList = mutableListOf() + + private var kotlinTasksConfigurator: () -> List? = { defaultKotlinTasks() } + private val kotlinTasks: List by lazy { extractKotlinCompileTasks() } + + fun kotlinTasks(taskSupplier: Callable>) { + kotlinTasksConfigurator = { taskSupplier.call() } + } + + fun kotlinTasks(closure: Closure) { + kotlinTasksConfigurator = { closure.call() as? List } + } + + + fun tryResolveFatJar(project: Project): Set { + return try { + dokkaRuntime!!.resolve() + } catch (e: Exception) { + project.parent?.let { tryResolveFatJar(it) } ?: throw e + } + } + + fun loadFatJar() { + if (ClassloaderContainer.fatJarClassLoader == null) { + val jars = if (dokkaFatJar is File) + setOf(dokkaFatJar as File) + else + tryResolveFatJar(project) + ClassloaderContainer.fatJarClassLoader = URLClassLoader(jars.map { it.toURI().toURL() }.toTypedArray(), ClassLoader.getSystemClassLoader().parent) + } + } + + internal data class ClasspathAndSourceRoots(val classpathFileCollection: FileCollection, val sourceRoots: List) : + Serializable + + private fun extractKotlinCompileTasks(): List { + val inputList = (kotlinTasksConfigurator.invoke() ?: emptyList()).filterNotNull() + val (paths, other) = inputList.partition { it is String } + + val taskContainer = project.tasks + + val tasksByPath = paths.map { taskContainer.findByPath(it as String) ?: throw IllegalArgumentException("Task with path '$it' not found") } + + other + .filter { it !is Task || it isNotInstance getAbstractKotlinCompileFor(it) } + .forEach { throw IllegalArgumentException("Illegal entry in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE or String, but was $it") } + + tasksByPath + .filter { it == null || it isNotInstance getAbstractKotlinCompileFor(it) } + .forEach { throw IllegalArgumentException("Illegal task path in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE, but was $it") } + + + return (tasksByPath + other) as List + } + + private fun extractClasspathAndSourceRootsFromKotlinTasks(): ClasspathAndSourceRoots { + + val allTasks = kotlinTasks + + val allClasspath = mutableSetOf() + var allClasspathFileCollection: FileCollection = project.files() + val allSourceRoots = mutableSetOf() + + allTasks.forEach { + logger.debug("Dokka found AbstractKotlinCompile task: $it") + with(ReflectDsl) { + val taskSourceRoots: List = it["sourceRootsContainer"]["sourceRoots"].v() + + val abstractKotlinCompileClz = getAbstractKotlinCompileFor(it)!! + + val taskClasspath: Iterable = + (it["getClasspath", AbstractCompile::class].takeIfIsFunc()?.invoke() + ?: it["compileClasspath", abstractKotlinCompileClz].takeIfIsProp()?.v() + ?: it["getClasspath", abstractKotlinCompileClz]()) + + if (taskClasspath is FileCollection) { + allClasspathFileCollection += taskClasspath + } else { + allClasspath += taskClasspath + } + allSourceRoots += taskSourceRoots.filter { it.exists() } + } + } + + return ClasspathAndSourceRoots(allClasspathFileCollection + project.files(allClasspath), allSourceRoots.toList()) + } + + private fun Iterable.toSourceRoots(): List = this.filter { it.exists() }.map { GradleSourceRootImpl().apply { path = it.path } } + + protected open fun collectSuppressedFiles(sourceRoots: List): List = emptyList() + + @TaskAction + fun generate() { + if (dokkaRuntime == null){ + dokkaRuntime = project.configurations.getByName("dokkaRuntime") + } + + dokkaRuntime?.defaultDependencies{ dependencies -> dependencies.add(project.dependencies.create(dokkaFatJar)) } + val kotlinColorsEnabledBefore = System.getProperty(COLORS_ENABLED_PROPERTY) ?: "false" + System.setProperty(COLORS_ENABLED_PROPERTY, "false") + try { + loadFatJar() + // TODO: implement extracting source roots from kotlin tasks + val (_, tasksSourceRoots) = kotlinCompileBasedClasspathAndSourceRoots + + val sourceRoots = collectSourceRoots(sourceDirs, sourceRoots) + tasksSourceRoots.toSourceRoots() + + val bootstrapClass = ClassloaderContainer.fatJarClassLoader!!.loadClass("org.jetbrains.dokka.DokkaBootstrapImpl") + val bootstrapInstance = bootstrapClass.constructors.first().newInstance() + val bootstrapProxy: DokkaBootstrap = + automagicTypedProxy(javaClass.classLoader, bootstrapInstance) + + val gson = GsonBuilder().setPrettyPrinting().create() + + val passConfigurationExtension: GradlePassConfigurationImpl? = this.extensions.findByName( + CONFIGURATION_EXTENSION_NAME) as GradlePassConfigurationImpl? + val passConfigurationsContainer by lazy { + (this.extensions.getByName(MULTIPLATFORM_EXTENSION_NAME) as Iterable).toList() + } + passConfigurationExtension?.sourceRoots?.addAll(sourceRoots) + + val passConfigurationList = + (passConfigurationExtension?.let {passConfigurationsContainer + it } ?: passConfigurationsContainer) + .map { defaultPassConfiguration(it) } + + val configuration = GradleDokkaConfigurationImpl() + configuration.outputDir = outputDirectory + configuration.format = outputFormat + configuration.generateIndexPages = true + configuration.cacheRoot = cacheRoot + configuration.impliedPlatforms = impliedPlatforms + configuration.passesConfigurations = passConfigurationList + + bootstrapProxy.configure( + BiConsumer { level, message -> + when (level) { + "info" -> logger.info(message) + "warn" -> logger.warn(message) + "error" -> logger.error(message) + } + }, + gson.toJson(configuration) + ) + + bootstrapProxy.generate() + + } finally { + System.setProperty(COLORS_ENABLED_PROPERTY, kotlinColorsEnabledBefore) + } + } + + private fun defaultPassConfiguration(passConfig: GradlePassConfigurationImpl): GradlePassConfigurationImpl{ + val (tasksClasspath, tasksSourceRoots) = kotlinCompileBasedClasspathAndSourceRoots + + val fullClasspath = tasksClasspath + classpath + passConfig.moduleName = moduleName + passConfig.classpath = fullClasspath.map { it.absolutePath } + passConfig.samples = passConfig.samples.map { project.file(it).absolutePath } + passConfig.includes = passConfig.includes.map { project.file(it).absolutePath } + passConfig.collectInheritedExtensionsFromLibraries = collectInheritedExtensionsFromLibraries + passConfig.suppressedFiles = collectSuppressedFiles(passConfig.sourceRoots) + passConfig.externalDocumentationLinks.addAll(externalDocumentationLinks) + + return passConfig + } + + private fun collectSourceRoots(sourceDirs: Iterable, sourceRoots: List): List { + val sourceDirs = when { + sourceDirs.any() -> { + logger.info("Dokka: Taking source directories provided by the user") + sourceDirs.toSet() + } + kotlinTasks.isEmpty() -> project.convention.findPlugin(JavaPluginConvention::class.java)?.let { javaPluginConvention -> + logger.info("Dokka: Taking source directories from default java plugin") + val sourceSets = javaPluginConvention.sourceSets.findByName(SourceSet.MAIN_SOURCE_SET_NAME) + sourceSets?.allSource?.srcDirs + } + else -> emptySet() + } + + return sourceRoots + (sourceDirs?.toSourceRoots() ?: emptyList()) + } + + companion object { + const val COLORS_ENABLED_PROPERTY = "kotlin.colors.enabled" + const val ABSTRACT_KOTLIN_COMPILE = "org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile" + + private fun getAbstractKotlinCompileFor(task: Task) = try { + task.project.buildscript.classLoader.loadClass(ABSTRACT_KOTLIN_COMPILE) + } catch (e: ClassNotFoundException) { + null + } + } +} diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt new file mode 100644 index 00000000..defddd31 --- /dev/null +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt @@ -0,0 +1,50 @@ +package org.jetbrains.dokka.gradle + +import org.gradle.api.Plugin +import org.gradle.api.Project +import java.io.File +import java.io.InputStream +import java.util.* + +/* +* Those are extension names, which are used in a build.gradle file as closure names: +* dokka { +* configuration { <- extension name +* } +* } +* */ +internal const val CONFIGURATION_EXTENSION_NAME = "configuration" +internal const val MULTIPLATFORM_EXTENSION_NAME = "multiplatform" + +open class DokkaPlugin : Plugin { + + override fun apply(project: Project) { + DokkaVersion.loadFrom(javaClass.getResourceAsStream("/META-INF/gradle-plugins/org.jetbrains.dokka.properties")) + + project.tasks.create("dokka", DokkaTask::class.java).apply { + dokkaRuntime = project.configurations.create("dokkaRuntime") + moduleName = project.name + outputDirectory = File(project.buildDir, "dokka").absolutePath + } + project.tasks.withType(DokkaTask::class.java) { task -> + val passConfiguration = project.container(GradlePassConfigurationImpl::class.java) + task.extensions.add(MULTIPLATFORM_EXTENSION_NAME, passConfiguration) + task.extensions.create(CONFIGURATION_EXTENSION_NAME, GradlePassConfigurationImpl::class.java, "") + } + } +} + +object DokkaVersion { + var version: String? = null + + fun loadFrom(stream: InputStream) { + version = Properties().apply { + load(stream) + }.getProperty("dokka-version") + } +} + +object ClassloaderContainer { + @JvmField + var fatJarClassLoader: ClassLoader? = null +} \ No newline at end of file -- cgit From d5864c672135bd2f5c7ce4fea5aeccd861796a47 Mon Sep 17 00:00:00 2001 From: Kamil Doległo Date: Mon, 15 Apr 2019 13:26:26 +0200 Subject: Light refactoring --- .../src/main/kotlin/mainAndroid.kt | 4 +- .../kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt | 275 +++++++++++++++++++++ .../org/jetbrains/dokka/gradle/ProxyUtils.kt | 4 +- .../dokka/gradle/configurationImplementations.kt | 35 +-- .../kotlin/org/jetbrains/dokka/gradle/dokkaTask.kt | 265 -------------------- .../main/kotlin/org/jetbrains/dokka/gradle/main.kt | 5 +- 6 files changed, 300 insertions(+), 288 deletions(-) create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt delete mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/dokkaTask.kt (limited to 'runners/gradle-plugin/src/main/kotlin') diff --git a/runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt b/runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt index 2fbeaae7..367b9257 100644 --- a/runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt +++ b/runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt @@ -3,8 +3,8 @@ package org.jetbrains.dokka.gradle import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.tasks.Input -import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink.Builder +import org.jetbrains.dokka.DokkaConfiguration.SourceRoot import java.io.File open class DokkaAndroidPlugin : Plugin { @@ -24,7 +24,7 @@ open class DokkaAndroidTask : DokkaTask() { @Input var noAndroidSdkLink: Boolean = false - override fun collectSuppressedFiles(sourceRoots: List): List { + override fun collectSuppressedFiles(sourceRoots: List): List { val generatedRoot = project.buildDir.resolve("generated").absoluteFile return sourceRoots .map { File(it.path) } diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt new file mode 100644 index 00000000..e8067e4c --- /dev/null +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt @@ -0,0 +1,275 @@ +package org.jetbrains.dokka.gradle + +import com.google.gson.GsonBuilder +import groovy.lang.Closure +import org.gradle.api.DefaultTask +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.artifacts.Configuration +import org.gradle.api.file.FileCollection +import org.gradle.api.plugins.JavaBasePlugin +import org.gradle.api.plugins.JavaPluginConvention +import org.gradle.api.tasks.* +import org.gradle.api.tasks.compile.AbstractCompile +import org.jetbrains.dokka.DokkaBootstrap +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.DokkaConfiguration.SourceRoot +import org.jetbrains.dokka.ReflectDsl +import org.jetbrains.dokka.ReflectDsl.isNotInstance +import java.io.File +import java.io.Serializable +import java.net.URLClassLoader +import java.util.concurrent.Callable +import java.util.function.BiConsumer + +open class DokkaTask : DefaultTask() { + + fun defaultKotlinTasks() = with(ReflectDsl) { + val abstractKotlinCompileClz = try { + project.buildscript.classLoader.loadClass(ABSTRACT_KOTLIN_COMPILE) + } catch (cnfe: ClassNotFoundException) { + logger.warn("$ABSTRACT_KOTLIN_COMPILE class not found, default kotlin tasks ignored") + return@with emptyList() + } + + return@with project.tasks.filter { it isInstance abstractKotlinCompileClz }.filter { "Test" !in it.name } + } + + init { + group = JavaBasePlugin.DOCUMENTATION_GROUP + description = "Generates dokka documentation for Kotlin" + + @Suppress("LeakingThis") + dependsOn(Callable { kotlinTasks.map { it.taskDependencies } }) + } + + @Input + var moduleName: String = "" + + @Input + var outputFormat: String = "html" + + @OutputDirectory + var outputDirectory: String = "" + + var dokkaRuntime: Configuration? = null + + @InputFiles + var classpath: Iterable = arrayListOf() + + @Input + var sourceDirs: Iterable = emptyList() + + @Input + var sourceRoots: MutableList = arrayListOf() + + @Input + var dokkaFatJar: Any = "org.jetbrains.dokka:dokka-fatjar:${DokkaVersion.version}" + + @Input + var impliedPlatforms: MutableList = arrayListOf() + + @Optional + @Input + var cacheRoot: String? = null + + @Input + var collectInheritedExtensionsFromLibraries: Boolean = false + + @get:Internal + internal val kotlinCompileBasedClasspathAndSourceRoots: ClasspathAndSourceRoots by lazy { extractClasspathAndSourceRootsFromKotlinTasks() } + + protected var externalDocumentationLinks: MutableList = mutableListOf() + + private var kotlinTasksConfigurator: () -> List? = { defaultKotlinTasks() } + private val kotlinTasks: List by lazy { extractKotlinCompileTasks() } + + fun kotlinTasks(taskSupplier: Callable>) { + kotlinTasksConfigurator = { taskSupplier.call() } + } + + fun kotlinTasks(closure: Closure) { + kotlinTasksConfigurator = { closure.call() as? List } + } + + + fun tryResolveFatJar(project: Project): Set { + return try { + dokkaRuntime!!.resolve() + } catch (e: Exception) { + project.parent?.let { tryResolveFatJar(it) } ?: throw e + } + } + + fun loadFatJar() { + if (ClassloaderContainer.fatJarClassLoader == null) { + val jars = if (dokkaFatJar is File) + setOf(dokkaFatJar as File) + else + tryResolveFatJar(project) + ClassloaderContainer.fatJarClassLoader = URLClassLoader(jars.map { it.toURI().toURL() }.toTypedArray(), ClassLoader.getSystemClassLoader().parent) + } + } + + internal data class ClasspathAndSourceRoots(val classpathFileCollection: FileCollection, val sourceRoots: List) : + Serializable + + private fun extractKotlinCompileTasks(): List { + val inputList = (kotlinTasksConfigurator.invoke() ?: emptyList()).filterNotNull() + val (paths, other) = inputList.partition { it is String } + + val taskContainer = project.tasks + + val tasksByPath = paths.map { taskContainer.findByPath(it as String) ?: throw IllegalArgumentException("Task with path '$it' not found") } + + other + .filter { it !is Task || it isNotInstance getAbstractKotlinCompileFor(it) } + .forEach { throw IllegalArgumentException("Illegal entry in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE or String, but was $it") } + + tasksByPath + .filter { it == null || it isNotInstance getAbstractKotlinCompileFor(it) } + .forEach { throw IllegalArgumentException("Illegal task path in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE, but was $it") } + + + return (tasksByPath + other) as List + } + + private fun extractClasspathAndSourceRootsFromKotlinTasks(): ClasspathAndSourceRoots { + + val allTasks = kotlinTasks + + val allClasspath = mutableSetOf() + var allClasspathFileCollection: FileCollection = project.files() + val allSourceRoots = mutableSetOf() + + allTasks.forEach { + logger.debug("Dokka found AbstractKotlinCompile task: $it") + with(ReflectDsl) { + val taskSourceRoots: List = it["sourceRootsContainer"]["sourceRoots"].v() + + val abstractKotlinCompileClz = getAbstractKotlinCompileFor(it)!! + + val taskClasspath: Iterable = + (it["getClasspath", AbstractCompile::class].takeIfIsFunc()?.invoke() + ?: it["compileClasspath", abstractKotlinCompileClz].takeIfIsProp()?.v() + ?: it["getClasspath", abstractKotlinCompileClz]()) + + if (taskClasspath is FileCollection) { + allClasspathFileCollection += taskClasspath + } else { + allClasspath += taskClasspath + } + allSourceRoots += taskSourceRoots.filter { it.exists() } + } + } + + return ClasspathAndSourceRoots(allClasspathFileCollection + project.files(allClasspath), allSourceRoots.toList()) + } + + private fun Iterable.toSourceRoots(): List = this.filter { it.exists() }.map { GradleSourceRootImpl().apply { path = it.path } } + + protected open fun collectSuppressedFiles(sourceRoots: List): List = emptyList() + + @TaskAction + fun generate() { + if (dokkaRuntime == null){ + dokkaRuntime = project.configurations.getByName("dokkaRuntime") + } + + dokkaRuntime?.defaultDependencies{ dependencies -> dependencies.add(project.dependencies.create(dokkaFatJar)) } + val kotlinColorsEnabledBefore = System.getProperty(COLORS_ENABLED_PROPERTY) ?: "false" + System.setProperty(COLORS_ENABLED_PROPERTY, "false") + try { + loadFatJar() + // TODO: implement extracting source roots from kotlin tasks + val (_, tasksSourceRoots) = kotlinCompileBasedClasspathAndSourceRoots + + val sourceRoots = collectSourceRoots() + tasksSourceRoots.toSourceRoots() + + val bootstrapClass = ClassloaderContainer.fatJarClassLoader!!.loadClass("org.jetbrains.dokka.DokkaBootstrapImpl") + val bootstrapInstance = bootstrapClass.constructors.first().newInstance() + val bootstrapProxy: DokkaBootstrap = + automagicTypedProxy(javaClass.classLoader, bootstrapInstance) + + val gson = GsonBuilder().setPrettyPrinting().create() + + val passConfigurationExtension: GradlePassConfigurationImpl? = extensions.findByName( + CONFIGURATION_EXTENSION_NAME) as GradlePassConfigurationImpl? + val passConfigurationsContainer by lazy { + (extensions.getByName(MULTIPLATFORM_EXTENSION_NAME) as Iterable).toList() + } + passConfigurationExtension?.sourceRoots?.addAll(sourceRoots) + + val passConfigurationList = + (passConfigurationExtension?.let {passConfigurationsContainer + it } ?: passConfigurationsContainer) + .map { defaultPassConfiguration(it) } + + val configuration = GradleDokkaConfigurationImpl() + configuration.outputDir = outputDirectory + configuration.format = outputFormat + configuration.generateIndexPages = true + configuration.cacheRoot = cacheRoot + configuration.impliedPlatforms = impliedPlatforms + configuration.passesConfigurations = passConfigurationList + + bootstrapProxy.configure( + BiConsumer { level, message -> + when (level) { + "info" -> logger.info(message) + "warn" -> logger.warn(message) + "error" -> logger.error(message) + } + }, + gson.toJson(configuration) + ) + + bootstrapProxy.generate() + + } finally { + System.setProperty(COLORS_ENABLED_PROPERTY, kotlinColorsEnabledBefore) + } + } + + private fun defaultPassConfiguration(passConfig: GradlePassConfigurationImpl): GradlePassConfigurationImpl{ + val (tasksClasspath, _) = kotlinCompileBasedClasspathAndSourceRoots + + val fullClasspath = tasksClasspath + classpath + passConfig.moduleName = moduleName + passConfig.classpath = fullClasspath.map { it.absolutePath } + passConfig.samples = passConfig.samples.map { project.file(it).absolutePath } + passConfig.includes = passConfig.includes.map { project.file(it).absolutePath } + passConfig.collectInheritedExtensionsFromLibraries = collectInheritedExtensionsFromLibraries + passConfig.suppressedFiles = collectSuppressedFiles(passConfig.sourceRoots) + passConfig.externalDocumentationLinks.addAll(externalDocumentationLinks) + + return passConfig + } + + private fun collectSourceRoots(): List { + val sourceDirs = when { + sourceDirs.any() -> { + logger.info("Dokka: Taking source directories provided by the user") + sourceDirs.toSet() + } + kotlinTasks.isEmpty() -> project.convention.findPlugin(JavaPluginConvention::class.java)?.let { javaPluginConvention -> + logger.info("Dokka: Taking source directories from default java plugin") + val sourceSets = javaPluginConvention.sourceSets.findByName(SourceSet.MAIN_SOURCE_SET_NAME) + sourceSets?.allSource?.srcDirs + } + else -> emptySet() + } + + return sourceRoots + (sourceDirs?.toSourceRoots() ?: emptyList()) + } + + companion object { + const val COLORS_ENABLED_PROPERTY = "kotlin.colors.enabled" + const val ABSTRACT_KOTLIN_COMPILE = "org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile" + + private fun getAbstractKotlinCompileFor(task: Task) = try { + task.project.buildscript.classLoader.loadClass(ABSTRACT_KOTLIN_COMPILE) + } catch (e: ClassNotFoundException) { + null + } + } +} diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ProxyUtils.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ProxyUtils.kt index 61c9e773..f8965993 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ProxyUtils.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ProxyUtils.kt @@ -26,8 +26,8 @@ inline fun automagicTypedProxy(targetClassLoader: ClassLoader, */ fun automagicProxy(targetClassLoader: ClassLoader, targetType: Class<*>, delegate: Any): Any = Proxy.newProxyInstance( - targetClassLoader, - arrayOf(targetType), + targetClassLoader, + arrayOf(targetType), DelegatedInvocationHandler(delegate) ) diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt index bab36f29..56bfe262 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt @@ -4,12 +4,13 @@ import groovy.lang.Closure import org.gradle.api.Action import org.gradle.util.ConfigureUtil import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.DokkaConfiguration.* import org.jetbrains.dokka.Platform import java.io.File import java.io.Serializable import java.net.URL -class GradleSourceRootImpl: DokkaConfiguration.SourceRoot, Serializable{ +class GradleSourceRootImpl: SourceRoot, Serializable { override var path: String = "" set(value) { field = File(value).absolutePath @@ -18,10 +19,10 @@ class GradleSourceRootImpl: DokkaConfiguration.SourceRoot, Serializable{ override fun toString(): String = path } -open class GradlePassConfigurationImpl(@Transient val name: String = ""): DokkaConfiguration.PassConfiguration { +open class GradlePassConfigurationImpl(@Transient val name: String = ""): PassConfiguration { override var classpath: List = emptyList() override var moduleName: String = "" - override var sourceRoots: MutableList = mutableListOf() + override var sourceRoots: MutableList = mutableListOf() override var samples: List = emptyList() override var includes: List = emptyList() override var includeNonPublic: Boolean = false @@ -30,9 +31,9 @@ open class GradlePassConfigurationImpl(@Transient val name: String = ""): DokkaC override var skipEmptyPackages: Boolean = false override var skipDeprecated: Boolean = false override var jdkVersion: Int = 6 - override var sourceLinks: MutableList = mutableListOf() - override var perPackageOptions: MutableList = mutableListOf() - override var externalDocumentationLinks: MutableList = mutableListOf() + override var sourceLinks: MutableList = mutableListOf() + override var perPackageOptions: MutableList = mutableListOf() + override var externalDocumentationLinks: MutableList = mutableListOf() override var languageVersion: String? = null override var apiVersion: String? = null override var noStdlibLink: Boolean = false @@ -43,58 +44,58 @@ open class GradlePassConfigurationImpl(@Transient val name: String = ""): DokkaC override var targets: List = listOf("JVM") override var sinceKotlin: String = "1.0" - fun sourceRoot(c: Closure){ + fun sourceRoot(c: Closure) { val configured = ConfigureUtil.configure(c, GradleSourceRootImpl()) sourceRoots.add(configured) } - fun sourceRoot(action: Action){ + fun sourceRoot(action: Action) { val sourceRoot = GradleSourceRootImpl() action.execute(sourceRoot) sourceRoots.add(sourceRoot) } - fun sourceLink(c: Closure){ + fun sourceLink(c: Closure) { val configured = ConfigureUtil.configure(c, GradleSourceLinkDefinitionImpl()) sourceLinks.add(configured) } - fun sourceLink(action: Action){ + fun sourceLink(action: Action) { val sourceLink = GradleSourceLinkDefinitionImpl() action.execute(sourceLink) sourceLinks.add(sourceLink) } - fun perPackageOption(c: Closure){ + fun perPackageOption(c: Closure) { val configured = ConfigureUtil.configure(c, GradlePackageOptionsImpl()) perPackageOptions.add(configured) } - fun perPackageOption(action: Action){ + fun perPackageOption(action: Action) { val option = GradlePackageOptionsImpl() action.execute(option) perPackageOptions.add(option) } - fun externalDocumentationLink(c: Closure){ + fun externalDocumentationLink(c: Closure) { val link = ConfigureUtil.configure(c, GradleExternalDocumentationLinkImpl()) externalDocumentationLinks.add(link) } - fun externalDocumentationLink(action: Action){ + fun externalDocumentationLink(action: Action) { val link = GradleExternalDocumentationLinkImpl() action.execute(link) externalDocumentationLinks.add(link) } } -class GradleSourceLinkDefinitionImpl : DokkaConfiguration.SourceLinkDefinition { +class GradleSourceLinkDefinitionImpl : SourceLinkDefinition { override var path: String = "" override var url: String = "" override var lineSuffix: String? = null } -class GradleExternalDocumentationLinkImpl : DokkaConfiguration.ExternalDocumentationLink { +class GradleExternalDocumentationLinkImpl : ExternalDocumentationLink { override var url: URL = URL("") override var packageListUrl: URL = URL("") } @@ -108,7 +109,7 @@ class GradleDokkaConfigurationImpl: DokkaConfiguration { override var passesConfigurations: List = emptyList() } -class GradlePackageOptionsImpl: DokkaConfiguration.PackageOptions { +class GradlePackageOptionsImpl: PackageOptions { override var prefix: String = "" override val includeNonPublic: Boolean = false override val reportUndocumented: Boolean = true diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/dokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/dokkaTask.kt deleted file mode 100644 index 0d78461c..00000000 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/dokkaTask.kt +++ /dev/null @@ -1,265 +0,0 @@ -package org.jetbrains.dokka.gradle - -import com.google.gson.GsonBuilder -import groovy.lang.Closure -import org.gradle.api.DefaultTask -import org.gradle.api.Project -import org.gradle.api.Task -import org.gradle.api.artifacts.Configuration -import org.gradle.api.file.FileCollection -import org.gradle.api.plugins.JavaBasePlugin -import org.gradle.api.plugins.JavaPluginConvention -import org.gradle.api.tasks.* -import org.gradle.api.tasks.compile.AbstractCompile -import org.jetbrains.dokka.DokkaBootstrap -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.ReflectDsl -import org.jetbrains.dokka.ReflectDsl.isNotInstance -import java.io.File -import java.io.Serializable -import java.net.URLClassLoader -import java.util.concurrent.Callable -import java.util.function.BiConsumer - -open class DokkaTask : DefaultTask() { - - fun defaultKotlinTasks() = with(ReflectDsl) { - val abstractKotlinCompileClz = try { - project.buildscript.classLoader.loadClass(ABSTRACT_KOTLIN_COMPILE) - } catch (cnfe: ClassNotFoundException) { - logger.warn("$ABSTRACT_KOTLIN_COMPILE class not found, default kotlin tasks ignored") - return@with emptyList() - } - - return@with project.tasks.filter { it isInstance abstractKotlinCompileClz }.filter { "Test" !in it.name } - } - - init { - group = JavaBasePlugin.DOCUMENTATION_GROUP - description = "Generates dokka documentation for Kotlin" - - @Suppress("LeakingThis") - dependsOn(Callable { kotlinTasks.map { it.taskDependencies } }) - } - - @Input - var moduleName: String = "" - @Input - var outputFormat: String = "html" - @OutputDirectory - var outputDirectory: String = "" - var dokkaRuntime: Configuration? = null - - @InputFiles - var classpath: Iterable = arrayListOf() - - @Input - var sourceDirs: Iterable = emptyList() - @Input - var sourceRoots: MutableList = arrayListOf() - @Input - var dokkaFatJar: Any = "org.jetbrains.dokka:dokka-fatjar:${DokkaVersion.version}" - @Input - var impliedPlatforms: MutableList = arrayListOf() - @Optional - @Input - var cacheRoot: String? = null - @Input - var collectInheritedExtensionsFromLibraries: Boolean = false - @get:Internal - internal val kotlinCompileBasedClasspathAndSourceRoots: ClasspathAndSourceRoots by lazy { extractClasspathAndSourceRootsFromKotlinTasks() } - - protected var externalDocumentationLinks: MutableList = mutableListOf() - - private var kotlinTasksConfigurator: () -> List? = { defaultKotlinTasks() } - private val kotlinTasks: List by lazy { extractKotlinCompileTasks() } - - fun kotlinTasks(taskSupplier: Callable>) { - kotlinTasksConfigurator = { taskSupplier.call() } - } - - fun kotlinTasks(closure: Closure) { - kotlinTasksConfigurator = { closure.call() as? List } - } - - - fun tryResolveFatJar(project: Project): Set { - return try { - dokkaRuntime!!.resolve() - } catch (e: Exception) { - project.parent?.let { tryResolveFatJar(it) } ?: throw e - } - } - - fun loadFatJar() { - if (ClassloaderContainer.fatJarClassLoader == null) { - val jars = if (dokkaFatJar is File) - setOf(dokkaFatJar as File) - else - tryResolveFatJar(project) - ClassloaderContainer.fatJarClassLoader = URLClassLoader(jars.map { it.toURI().toURL() }.toTypedArray(), ClassLoader.getSystemClassLoader().parent) - } - } - - internal data class ClasspathAndSourceRoots(val classpathFileCollection: FileCollection, val sourceRoots: List) : - Serializable - - private fun extractKotlinCompileTasks(): List { - val inputList = (kotlinTasksConfigurator.invoke() ?: emptyList()).filterNotNull() - val (paths, other) = inputList.partition { it is String } - - val taskContainer = project.tasks - - val tasksByPath = paths.map { taskContainer.findByPath(it as String) ?: throw IllegalArgumentException("Task with path '$it' not found") } - - other - .filter { it !is Task || it isNotInstance getAbstractKotlinCompileFor(it) } - .forEach { throw IllegalArgumentException("Illegal entry in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE or String, but was $it") } - - tasksByPath - .filter { it == null || it isNotInstance getAbstractKotlinCompileFor(it) } - .forEach { throw IllegalArgumentException("Illegal task path in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE, but was $it") } - - - return (tasksByPath + other) as List - } - - private fun extractClasspathAndSourceRootsFromKotlinTasks(): ClasspathAndSourceRoots { - - val allTasks = kotlinTasks - - val allClasspath = mutableSetOf() - var allClasspathFileCollection: FileCollection = project.files() - val allSourceRoots = mutableSetOf() - - allTasks.forEach { - logger.debug("Dokka found AbstractKotlinCompile task: $it") - with(ReflectDsl) { - val taskSourceRoots: List = it["sourceRootsContainer"]["sourceRoots"].v() - - val abstractKotlinCompileClz = getAbstractKotlinCompileFor(it)!! - - val taskClasspath: Iterable = - (it["getClasspath", AbstractCompile::class].takeIfIsFunc()?.invoke() - ?: it["compileClasspath", abstractKotlinCompileClz].takeIfIsProp()?.v() - ?: it["getClasspath", abstractKotlinCompileClz]()) - - if (taskClasspath is FileCollection) { - allClasspathFileCollection += taskClasspath - } else { - allClasspath += taskClasspath - } - allSourceRoots += taskSourceRoots.filter { it.exists() } - } - } - - return ClasspathAndSourceRoots(allClasspathFileCollection + project.files(allClasspath), allSourceRoots.toList()) - } - - private fun Iterable.toSourceRoots(): List = this.filter { it.exists() }.map { GradleSourceRootImpl().apply { path = it.path } } - - protected open fun collectSuppressedFiles(sourceRoots: List): List = emptyList() - - @TaskAction - fun generate() { - if (dokkaRuntime == null){ - dokkaRuntime = project.configurations.getByName("dokkaRuntime") - } - - dokkaRuntime?.defaultDependencies{ dependencies -> dependencies.add(project.dependencies.create(dokkaFatJar)) } - val kotlinColorsEnabledBefore = System.getProperty(COLORS_ENABLED_PROPERTY) ?: "false" - System.setProperty(COLORS_ENABLED_PROPERTY, "false") - try { - loadFatJar() - // TODO: implement extracting source roots from kotlin tasks - val (_, tasksSourceRoots) = kotlinCompileBasedClasspathAndSourceRoots - - val sourceRoots = collectSourceRoots(sourceDirs, sourceRoots) + tasksSourceRoots.toSourceRoots() - - val bootstrapClass = ClassloaderContainer.fatJarClassLoader!!.loadClass("org.jetbrains.dokka.DokkaBootstrapImpl") - val bootstrapInstance = bootstrapClass.constructors.first().newInstance() - val bootstrapProxy: DokkaBootstrap = - automagicTypedProxy(javaClass.classLoader, bootstrapInstance) - - val gson = GsonBuilder().setPrettyPrinting().create() - - val passConfigurationExtension: GradlePassConfigurationImpl? = this.extensions.findByName( - CONFIGURATION_EXTENSION_NAME) as GradlePassConfigurationImpl? - val passConfigurationsContainer by lazy { - (this.extensions.getByName(MULTIPLATFORM_EXTENSION_NAME) as Iterable).toList() - } - passConfigurationExtension?.sourceRoots?.addAll(sourceRoots) - - val passConfigurationList = - (passConfigurationExtension?.let {passConfigurationsContainer + it } ?: passConfigurationsContainer) - .map { defaultPassConfiguration(it) } - - val configuration = GradleDokkaConfigurationImpl() - configuration.outputDir = outputDirectory - configuration.format = outputFormat - configuration.generateIndexPages = true - configuration.cacheRoot = cacheRoot - configuration.impliedPlatforms = impliedPlatforms - configuration.passesConfigurations = passConfigurationList - - bootstrapProxy.configure( - BiConsumer { level, message -> - when (level) { - "info" -> logger.info(message) - "warn" -> logger.warn(message) - "error" -> logger.error(message) - } - }, - gson.toJson(configuration) - ) - - bootstrapProxy.generate() - - } finally { - System.setProperty(COLORS_ENABLED_PROPERTY, kotlinColorsEnabledBefore) - } - } - - private fun defaultPassConfiguration(passConfig: GradlePassConfigurationImpl): GradlePassConfigurationImpl{ - val (tasksClasspath, tasksSourceRoots) = kotlinCompileBasedClasspathAndSourceRoots - - val fullClasspath = tasksClasspath + classpath - passConfig.moduleName = moduleName - passConfig.classpath = fullClasspath.map { it.absolutePath } - passConfig.samples = passConfig.samples.map { project.file(it).absolutePath } - passConfig.includes = passConfig.includes.map { project.file(it).absolutePath } - passConfig.collectInheritedExtensionsFromLibraries = collectInheritedExtensionsFromLibraries - passConfig.suppressedFiles = collectSuppressedFiles(passConfig.sourceRoots) - passConfig.externalDocumentationLinks.addAll(externalDocumentationLinks) - - return passConfig - } - - private fun collectSourceRoots(sourceDirs: Iterable, sourceRoots: List): List { - val sourceDirs = when { - sourceDirs.any() -> { - logger.info("Dokka: Taking source directories provided by the user") - sourceDirs.toSet() - } - kotlinTasks.isEmpty() -> project.convention.findPlugin(JavaPluginConvention::class.java)?.let { javaPluginConvention -> - logger.info("Dokka: Taking source directories from default java plugin") - val sourceSets = javaPluginConvention.sourceSets.findByName(SourceSet.MAIN_SOURCE_SET_NAME) - sourceSets?.allSource?.srcDirs - } - else -> emptySet() - } - - return sourceRoots + (sourceDirs?.toSourceRoots() ?: emptyList()) - } - - companion object { - const val COLORS_ENABLED_PROPERTY = "kotlin.colors.enabled" - const val ABSTRACT_KOTLIN_COMPILE = "org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile" - - private fun getAbstractKotlinCompileFor(task: Task) = try { - task.project.buildscript.classLoader.loadClass(ABSTRACT_KOTLIN_COMPILE) - } catch (e: ClassNotFoundException) { - null - } - } -} diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt index defddd31..d04ed5f0 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt @@ -7,9 +7,10 @@ import java.io.InputStream import java.util.* /* -* Those are extension names, which are used in a build.gradle file as closure names: +* Extension names, which are used in a build.gradle file as closure names: * dokka { -* configuration { <- extension name +* configuration { // extension name +* * } * } * */ -- cgit From 4f87f295e4df6da40854ebd47158829c4622f945 Mon Sep 17 00:00:00 2001 From: Kamil Doległo Date: Mon, 15 Apr 2019 14:49:35 +0200 Subject: Fix for config --- .../src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runners/gradle-plugin/src/main/kotlin') diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt index e8067e4c..a49059e5 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt @@ -201,7 +201,7 @@ open class DokkaTask : DefaultTask() { passConfigurationExtension?.sourceRoots?.addAll(sourceRoots) val passConfigurationList = - (passConfigurationExtension?.let {passConfigurationsContainer + it } ?: passConfigurationsContainer) + (passConfigurationExtension?.let { listOf(it) } ?: passConfigurationsContainer) .map { defaultPassConfiguration(it) } val configuration = GradleDokkaConfigurationImpl() -- cgit From 5c1253503c62d2401cfec9cb5c2d89f45b74ef63 Mon Sep 17 00:00:00 2001 From: Kamil Doległo Date: Tue, 16 Apr 2019 09:22:50 +0200 Subject: Fix Gradle extensions --- .../main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'runners/gradle-plugin/src/main/kotlin') diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt index a49059e5..d9094e46 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt @@ -127,7 +127,7 @@ open class DokkaTask : DefaultTask() { .forEach { throw IllegalArgumentException("Illegal entry in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE or String, but was $it") } tasksByPath - .filter { it == null || it isNotInstance getAbstractKotlinCompileFor(it) } + .filter { it isNotInstance getAbstractKotlinCompileFor(it) } .forEach { throw IllegalArgumentException("Illegal task path in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE, but was $it") } @@ -193,15 +193,15 @@ open class DokkaTask : DefaultTask() { val gson = GsonBuilder().setPrettyPrinting().create() - val passConfigurationExtension: GradlePassConfigurationImpl? = extensions.findByName( - CONFIGURATION_EXTENSION_NAME) as GradlePassConfigurationImpl? - val passConfigurationsContainer by lazy { + val passConfigurationExtension: GradlePassConfigurationImpl = extensions.findByName( + CONFIGURATION_EXTENSION_NAME) as GradlePassConfigurationImpl + val passConfigurationsContainer= (extensions.getByName(MULTIPLATFORM_EXTENSION_NAME) as Iterable).toList() - } - passConfigurationExtension?.sourceRoots?.addAll(sourceRoots) + + passConfigurationExtension.sourceRoots.addAll(sourceRoots) val passConfigurationList = - (passConfigurationExtension?.let { listOf(it) } ?: passConfigurationsContainer) + (passConfigurationsContainer + passConfigurationExtension) .map { defaultPassConfiguration(it) } val configuration = GradleDokkaConfigurationImpl() -- cgit From d841e2dd60e6a784ac1863ddba21949460320fc3 Mon Sep 17 00:00:00 2001 From: Kamil Doległo Date: Tue, 16 Apr 2019 09:56:58 +0200 Subject: Change extension behaviour --- .../src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'runners/gradle-plugin/src/main/kotlin') diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt index d9094e46..6c93188b 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt @@ -195,13 +195,13 @@ open class DokkaTask : DefaultTask() { val passConfigurationExtension: GradlePassConfigurationImpl = extensions.findByName( CONFIGURATION_EXTENSION_NAME) as GradlePassConfigurationImpl - val passConfigurationsContainer= + val passConfigurationsContainer = (extensions.getByName(MULTIPLATFORM_EXTENSION_NAME) as Iterable).toList() passConfigurationExtension.sourceRoots.addAll(sourceRoots) val passConfigurationList = - (passConfigurationsContainer + passConfigurationExtension) + (if (passConfigurationsContainer.isEmpty()) listOf(passConfigurationExtension) else passConfigurationsContainer) .map { defaultPassConfiguration(it) } val configuration = GradleDokkaConfigurationImpl() -- cgit