From cbb8bf2debb6cb23f7fd84eeba86484b898ca350 Mon Sep 17 00:00:00 2001 From: Sergey Igushkin Date: Fri, 12 Jul 2019 18:37:34 +0300 Subject: [PATCH] Extract members from Kotlin tasks, don't iterate over them (KT-31713) Refactor: move some properties from the Kotlin tasks to the new task data model, so they can be accessed without forcing the tasks to instantiate. Don't iterate over Kotlin tasks of all projects in the IC-related code; instead, inspect the model. Issue #KT-31713 Fixed --- .../kotlin/gradle/GradleVersionRequired.kt | 2 +- .../GradleKotlinCompilerRunner.kt | 63 +++++++++-------- .../kapt/Kapt3KotlinGradleSubplugin.kt | 13 +++- .../internal/kapt/KaptGenerateStubsTask.kt | 2 +- .../kotlin/gradle/plugin/KotlinPlugin.kt | 40 ++++++----- .../gradle/plugin/mpp/kotlinCompilations.kt | 15 +++++ .../targets/jvm/KotlinWithJavaTarget.kt | 13 +++- .../tasks/InspectClassesForMultiModuleIC.kt | 8 ++- .../jetbrains/kotlin/gradle/tasks/Tasks.kt | 55 ++++++++------- .../kotlin/gradle/tasks/TasksProvider.kt | 12 ++-- .../gradle/tasks/kotlinCompileTaskData.kt | 67 +++++++++++++++++++ .../kotlin/gradle/utils/compatibiltiy.kt | 13 +++- 12 files changed, 216 insertions(+), 87 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/kotlinCompileTaskData.kt diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/GradleVersionRequired.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/GradleVersionRequired.kt index bb1815dfa79..2afcf5f35eb 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/GradleVersionRequired.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/GradleVersionRequired.kt @@ -21,7 +21,7 @@ import org.junit.Assume sealed class GradleVersionRequired(val minVersion: String, val maxVersion: String?) { companion object { - const val OLDEST_SUPPORTED = "4.1" + const val OLDEST_SUPPORTED = "4.3" } class Exact(version: String) : GradleVersionRequired(version, version) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt index 139424d5913..03b4aa68a9a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt @@ -29,18 +29,19 @@ import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.daemon.client.CompileServiceSession import org.jetbrains.kotlin.daemon.common.* -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.dsl.kotlinExtensionOrNull +import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull import org.jetbrains.kotlin.gradle.logging.kotlinDebug import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation -import org.jetbrains.kotlin.gradle.tasks.* +import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType +import org.jetbrains.kotlin.gradle.tasks.KotlinCompileTaskData +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget +import org.jetbrains.kotlin.gradle.utils.archivePathCompatible import org.jetbrains.kotlin.gradle.utils.newTmpFile import org.jetbrains.kotlin.gradle.utils.relativeToRoot import org.jetbrains.kotlin.incremental.IncrementalModuleInfo import org.jetbrains.kotlin.incremental.IncrementalModuleEntry -import org.jetbrains.kotlin.incremental.classpathAsList -import org.jetbrains.kotlin.incremental.destinationAsFile -import org.jetbrains.kotlin.incremental.makeModuleFile import java.io.File import java.lang.ref.WeakReference @@ -180,38 +181,44 @@ internal open class GradleCompilerRunner(protected val task: Task) { val jarToModule = HashMap() for (project in gradle.rootProject.allprojects) { - project.tasks.withType(AbstractKotlinCompile::class.java).toList().forEach { task -> + + if (project.kotlinExtensionOrNull == null) + continue + + val isMultiplatformProject = project.multiplatformExtensionOrNull != null + + KotlinCompileTaskData.getTaskDataContainer(project).forEach { taskData -> + val compilation = taskData.compilation + val target = taskData.compilation.target val module = IncrementalModuleEntry( project.path, - task.moduleName, + compilation.moduleName, project.buildDir, - task.buildHistoryFile + taskData.buildHistoryFile ) - dirToModule[task.destinationDir] = module - task.javaOutputDir?.let { dirToModule[it] = module } + @Suppress("UnstableApiUsage") + dirToModule[taskData.destinationDir.get()] = module + + taskData.javaOutputDir?.let { dirToModule[it] = module } nameToModules.getOrPut(module.name) { HashSet() }.add(module) - if (task is Kotlin2JsCompile) { - jarForSourceSet(project, task.sourceSetName)?.let { + if (compilation.platformType == KotlinPlatformType.js) { + jarForSourceSet(project, compilation.name)?.let { jarToModule[it] = module } } - } - project.tasks.withType(InspectClassesForMultiModuleIC::class.java).forEach { task -> - jarToClassListFile[File(task.archivePath)] = task.classesListFile - } - project.extensions.findByType(KotlinMultiplatformExtension::class.java)?.let { kotlinExt -> - for (target in kotlinExt.targets) { - val mainCompilation = target.compilations.findByName(KotlinCompilation.MAIN_COMPILATION_NAME) ?: continue - val kotlinTask = mainCompilation.compileKotlinTask as? AbstractKotlinCompile<*> ?: continue - val module = IncrementalModuleEntry( - project.path, - kotlinTask.moduleName, - project.buildDir, - kotlinTask.buildHistoryFile - ) - val jarTask = project.tasks.findByName(target.artifactsTaskName) as? AbstractArchiveTask ?: continue - jarToModule[jarTask.archivePath] = module + + if (compilation.name == KotlinCompilation.MAIN_COMPILATION_NAME) { + if (isMultiplatformProject) { + (project.tasks.findByName(target.artifactsTaskName) as? AbstractArchiveTask)?.let { jarTask -> + jarToModule[jarTask.archivePathCompatible.canonicalFile] = module + } + } else { + if (target is KotlinWithJavaTarget<*>) { + val jar = project.tasks.getByName(target.artifactsTaskName) as Jar + jarToClassListFile[jar.archivePathCompatible.canonicalFile] = target.defaultArtifactClassesListFile + } + } } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt index e26afbe6bc9..c87df48934c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.gradle.internal.kapt.incremental.StructureArtifactTr import org.jetbrains.kotlin.gradle.model.builder.KaptModelBuilder import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions +import org.jetbrains.kotlin.gradle.tasks.KotlinCompileTaskData import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.isWorkerAPISupported import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast @@ -469,17 +470,23 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin { } private fun Kapt3SubpluginContext.createKaptGenerateStubsTask(): KaptGenerateStubsTask { + val kaptTaskName = getKaptTaskName("kaptGenerateStubs") + + KotlinCompileTaskData.register(kaptTaskName, KotlinCompileTaskData.get(project, kotlinCompile.name).compilation).apply { + @Suppress("UnstableApiUsage") + useModuleDetection.set(KotlinCompileTaskData.get(project, kotlinCompile.name).useModuleDetection) + } + val kaptTask = project.tasks.create( - getKaptTaskName("kaptGenerateStubs"), + kaptTaskName, KaptGenerateStubsTask::class.java ) - kaptTask.sourceSetName = sourceSetName kaptTask.kotlinCompileTask = kotlinCompile kotlinToKaptGenerateStubsTasksMap[kotlinCompile] = kaptTask kaptTask.stubsDir = getKaptStubsDir() - kaptTask.destinationDir = getKaptIncrementalDataDir() + kaptTask.setDestinationDir { getKaptIncrementalDataDir() } kaptTask.mapClasspath { kotlinCompile.classpath } kaptTask.generatedSourcesDir = sourcesOutputDir PropertiesProvider(project).mapKotlinTaskProperties(kaptTask) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptGenerateStubsTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptGenerateStubsTask.kt index 2d9ce8ebb09..f9998cc368e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptGenerateStubsTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptGenerateStubsTask.kt @@ -61,7 +61,7 @@ open class KaptGenerateStubsTask : KotlinCompile() { @get:Input override var useModuleDetection: Boolean - get() = kotlinCompileTask.useModuleDetection + get() = super.useModuleDetection set(_) { error("KaptGenerateStubsTask.useModuleDetection setter should not be called!") } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt index 60d67653c93..da2bff9b508 100755 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt @@ -58,7 +58,7 @@ internal abstract class KotlinSourceSetProcessor>( val project: Project, val tasksProvider: KotlinTasksProvider, val taskDescription: String, - val kotlinCompilation: KotlinCompilation<*> + val kotlinCompilation: AbstractKotlinCompilation<*> ) { protected abstract fun doTargetSpecificProcessing() protected val logger = Logging.getLogger(this.javaClass)!! @@ -83,13 +83,17 @@ internal abstract class KotlinSourceSetProcessor>( private fun registerKotlinCompileTask(): TaskHolder { val name = kotlinCompilation.compileKotlinTaskName logger.kotlinDebug("Creating kotlin compile task $name") - val kotlinCompile = doRegisterTask(project, name) { + + KotlinCompileTaskData.register(name, kotlinCompilation).apply { + @Suppress("UnstableApiUsage") + destinationDir.set(project.provider { defaultKotlinDestinationDir }) + } + + return doRegisterTask(project, name) { it.description = taskDescription it.mapClasspath { kotlinCompilation.compileDependencyFiles } - it.setDestinationDir { defaultKotlinDestinationDir } kotlinCompilation.output.addClassesDir { project.files(kotlinTask.doGetTask().destinationDir).builtBy(kotlinTask.doGetTask()) } } - return kotlinCompile } open fun run() { @@ -162,7 +166,7 @@ internal abstract class KotlinSourceSetProcessor>( internal class Kotlin2JvmSourceSetProcessor( project: Project, tasksProvider: KotlinTasksProvider, - kotlinCompilation: KotlinCompilation<*>, + kotlinCompilation: AbstractKotlinCompilation<*>, private val kotlinPluginVersion: String ) : KotlinSourceSetProcessor( project, tasksProvider, "Compiles the $kotlinCompilation.", kotlinCompilation @@ -236,7 +240,7 @@ internal fun KotlinCompilationOutput.addClassesDir(classesDirProvider: () -> Fil internal class Kotlin2JsSourceSetProcessor( project: Project, tasksProvider: KotlinTasksProvider, - kotlinCompilation: KotlinCompilation<*>, + kotlinCompilation: AbstractKotlinCompilation<*>, private val kotlinPluginVersion: String ) : KotlinSourceSetProcessor( project, tasksProvider, taskDescription = "Compiles the Kotlin sources in $kotlinCompilation to JavaScript.", @@ -299,7 +303,7 @@ internal class Kotlin2JsSourceSetProcessor( internal class KotlinCommonSourceSetProcessor( project: Project, - compilation: KotlinCompilation<*>, + compilation: AbstractKotlinCompilation<*>, tasksProvider: KotlinTasksProvider, private val kotlinPluginVersion: String ) : KotlinSourceSetProcessor( @@ -338,7 +342,7 @@ internal abstract class AbstractKotlinPlugin( internal abstract fun buildSourceSetProcessor( project: Project, - compilation: KotlinCompilation<*>, + compilation: AbstractKotlinCompilation<*>, kotlinPluginVersion: String ): KotlinSourceSetProcessor<*> @@ -403,7 +407,7 @@ internal abstract class AbstractKotlinPlugin( fun configureTarget( target: KotlinWithJavaTarget<*>, - buildSourceSetProcessor: (KotlinCompilation<*>) -> KotlinSourceSetProcessor<*> + buildSourceSetProcessor: (AbstractKotlinCompilation<*>) -> KotlinSourceSetProcessor<*> ) { setUpJavaSourceSets(target) configureSourceSetDefaults(target, buildSourceSetProcessor) @@ -517,8 +521,8 @@ internal abstract class AbstractKotlinPlugin( } private fun configureSourceSetDefaults( - kotlinTarget: KotlinTarget, - buildSourceSetProcessor: (KotlinCompilation<*>) -> KotlinSourceSetProcessor<*> + kotlinTarget: KotlinWithJavaTarget<*>, + buildSourceSetProcessor: (AbstractKotlinCompilation<*>) -> KotlinSourceSetProcessor<*> ) { kotlinTarget.compilations.all { compilation -> buildSourceSetProcessor(compilation).run() @@ -566,7 +570,7 @@ internal open class KotlinPlugin( private const val targetName = "" // use empty suffix for the task names } - override fun buildSourceSetProcessor(project: Project, compilation: KotlinCompilation<*>, kotlinPluginVersion: String) = + override fun buildSourceSetProcessor(project: Project, compilation: AbstractKotlinCompilation<*>, kotlinPluginVersion: String) = Kotlin2JvmSourceSetProcessor(project, tasksProvider, compilation, kotlinPluginVersion) override fun apply(project: Project) { @@ -592,7 +596,7 @@ internal open class KotlinCommonPlugin( override fun buildSourceSetProcessor( project: Project, - compilation: KotlinCompilation<*>, + compilation: AbstractKotlinCompilation<*>, kotlinPluginVersion: String ): KotlinSourceSetProcessor<*> = KotlinCommonSourceSetProcessor(project, compilation, tasksProvider, kotlinPluginVersion) @@ -616,7 +620,7 @@ internal open class Kotlin2JsPlugin( override fun buildSourceSetProcessor( project: Project, - compilation: KotlinCompilation<*>, + compilation: AbstractKotlinCompilation<*>, kotlinPluginVersion: String ): KotlinSourceSetProcessor<*> = Kotlin2JsSourceSetProcessor( @@ -914,11 +918,15 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationT val kotlinTaskName = compilation.compileKotlinTaskName + KotlinCompileTaskData.register(kotlinTaskName, compilation).apply { + // store kotlin classes in separate directory. They will serve as class-path to java compiler + @Suppress("UnstableApiUsage") + destinationDir.set(project.provider { File(project.buildDir, "tmp/kotlin-classes/$variantDataName") }) + } + tasksProvider.registerKotlinJVMTask(project, kotlinTaskName, compilation) { it.parentKotlinOptionsImpl = rootKotlinOptions - // store kotlin classes in separate directory. They will serve as class-path to java compiler - it.destinationDir = File(project.buildDir, "tmp/kotlin-classes/$variantDataName") it.description = "Compiles the $variantDataName kotlin." } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt index 526dc664319..082e54ac7c3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt @@ -9,6 +9,7 @@ import groovy.lang.Closure import org.gradle.api.Project import org.gradle.api.attributes.AttributeContainer import org.gradle.api.file.FileCollection +import org.gradle.api.plugins.BasePluginConvention import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.gradle.dsl.* import org.jetbrains.kotlin.gradle.plugin.* @@ -183,6 +184,15 @@ abstract class AbstractKotlinCompilation( dependencies f@{ ConfigureUtil.configure(configureClosure, this@f) } override fun toString(): String = "compilation '$compilationName' ($target)" + + internal val moduleName: String + get() { + val project = target.project + val baseName = project.convention.findPlugin(BasePluginConvention::class.java)?.archivesBaseName + ?: project.name + val suffix = if (compilationName == KotlinCompilation.MAIN_COMPILATION_NAME) "" else "_$compilationName" + return filterModuleName("$baseName$suffix") + } } abstract class AbstractKotlinCompilationToRunnableFiles( @@ -263,3 +273,8 @@ internal object CompilationSourceSetUtil { sourceSet.name.takeIf { compilations.size > 1 } } } + +private val invalidModuleNameCharactersRegex = """[\\/\r\n\t]""".toRegex() + +private fun filterModuleName(moduleName: String): String = + moduleName.replace(invalidModuleNameCharactersRegex, "_") \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinWithJavaTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinWithJavaTarget.kt index 932ab96a111..2a6dcf4bc2f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinWithJavaTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinWithJavaTarget.kt @@ -10,8 +10,11 @@ import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project import org.gradle.api.artifacts.Dependency import org.gradle.api.plugins.JavaPlugin +import org.gradle.jvm.tasks.Jar import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType +import org.jetbrains.kotlin.gradle.tasks.KOTLIN_BUILD_DIR_NAME +import java.io.File open class KotlinWithJavaTarget( project: Project, @@ -39,4 +42,12 @@ open class KotlinWithJavaTarget( KotlinWithJavaCompilation::class.java as Class>, KotlinWithJavaCompilationFactory(project, this) ) -} \ No newline at end of file + + internal val defaultArtifactClassesListFile: File + get() { + val jarTask = project.tasks.getByName(artifactsTaskName) as Jar + return File(File(project.buildDir, KOTLIN_BUILD_DIR_NAME), "${sanitizeFileName(jarTask.archiveName)}-classes.txt") + } +} + +private fun sanitizeFileName(candidate: String): String = candidate.filter { it.isLetterOrDigit() } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/InspectClassesForMultiModuleIC.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/InspectClassesForMultiModuleIC.kt index e79582e8af7..063f91e01db 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/InspectClassesForMultiModuleIC.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/InspectClassesForMultiModuleIC.kt @@ -9,7 +9,11 @@ import org.gradle.api.DefaultTask import org.gradle.api.file.FileCollection import org.gradle.api.plugins.JavaPluginConvention import org.gradle.api.tasks.* +import org.gradle.api.tasks.bundling.AbstractArchiveTask import org.gradle.jvm.tasks.Jar +import org.jetbrains.kotlin.gradle.dsl.KotlinSingleJavaTargetExtension +import org.jetbrains.kotlin.gradle.dsl.kotlinExtension +import org.jetbrains.kotlin.gradle.utils.archivePathCompatible import java.io.File internal open class InspectClassesForMultiModuleIC : DefaultTask() { @@ -22,7 +26,7 @@ internal open class InspectClassesForMultiModuleIC : DefaultTask() { @Suppress("MemberVisibilityCanBePrivate") @get:OutputFile internal val classesListFile: File - get() = File(File(project.buildDir, KOTLIN_BUILD_DIR_NAME), "${sanitizeFileName(jarTask.archiveName)}-classes.txt") + get() = (project.kotlinExtension as KotlinSingleJavaTargetExtension).target.defaultArtifactClassesListFile @Suppress("MemberVisibilityCanBePrivate") @get:InputFiles @@ -37,7 +41,7 @@ internal open class InspectClassesForMultiModuleIC : DefaultTask() { @get:Input internal val archivePath: String - get() = jarTask.archivePath.canonicalPath + get() = jarTask.archivePathCompatible.canonicalPath @TaskAction fun run() { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index 6c7426fa09c..7334201a654 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -8,7 +8,7 @@ package org.jetbrains.kotlin.gradle.tasks import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.file.FileCollection -import org.gradle.api.plugins.BasePluginConvention +import org.gradle.api.provider.Provider import org.gradle.api.tasks.* import org.gradle.api.tasks.Optional import org.gradle.api.tasks.compile.AbstractCompile @@ -29,10 +29,8 @@ import org.jetbrains.kotlin.gradle.internal.prepareCompilerArguments import org.jetbrains.kotlin.gradle.internal.tasks.TaskWithLocalState import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles import org.jetbrains.kotlin.gradle.logging.* +import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.COMPILER_CLASSPATH_CONFIGURATION_NAME -import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginWrapper -import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformPluginBase -import org.jetbrains.kotlin.gradle.plugin.PLUGIN_CLASSPATH_CONFIGURATION_NAME import org.jetbrains.kotlin.gradle.report.BuildReportMode import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast import org.jetbrains.kotlin.gradle.utils.isParentOf @@ -45,7 +43,6 @@ import org.jetbrains.kotlin.utils.LibraryUtils import java.io.File import java.util.* import javax.inject.Inject -import kotlin.properties.Delegates const val KOTLIN_BUILD_DIR_NAME = "kotlin" const val USING_JVM_INCREMENTAL_COMPILATION_MESSAGE = "Using Kotlin/JVM incremental compilation" @@ -142,16 +139,20 @@ abstract class AbstractKotlinCompile() : AbstractKo @get:Internal internal var buildReportMode: BuildReportMode? = null - @get:Internal - internal val buildHistoryFile: File - get() = File(taskBuildDirectory, "build-history.bin") + private val taskData: KotlinCompileTaskData + get() = KotlinCompileTaskData.get(project, name) + @Suppress("UnstableApiUsage") @get:Input - internal open var useModuleDetection: Boolean = false + internal open var useModuleDetection: Boolean + get() = taskData.useModuleDetection.get() + set(value) { + taskData.useModuleDetection.set(value) + } @get:Internal protected val multiModuleICSettings: MultiModuleICSettings - get() = MultiModuleICSettings(buildHistoryFile, useModuleDetection) + get() = MultiModuleICSettings(taskData.buildHistoryFile, useModuleDetection) @get:Classpath @get:InputFiles @@ -183,18 +184,23 @@ abstract class AbstractKotlinCompile() : AbstractKo private val kotlinExt: KotlinProjectExtension get() = project.extensions.findByType(KotlinProjectExtension::class.java)!! - private lateinit var destinationDirProvider: Lazy + override fun getDestinationDir(): File = + @Suppress("UnstableApiUsage") + taskData.destinationDir.get() - override fun getDestinationDir(): File { - return destinationDirProvider.value + @Suppress("UnstableApiUsage") + override fun setDestinationDir(provider: Provider) { + taskData.destinationDir.set(provider) } fun setDestinationDir(provider: () -> File) { - destinationDirProvider = lazy(provider) + @Suppress("UnstableApiUsage") + taskData.destinationDir.set(project.provider(provider)) } override fun setDestinationDir(destinationDir: File) { - destinationDirProvider = lazyOf(destinationDir) + @Suppress("UnstableApiUsage") + taskData.destinationDir.set(destinationDir) } @get:Internal @@ -213,10 +219,13 @@ abstract class AbstractKotlinCompile() : AbstractKo internal var friendTaskName: String? = null @get:Internal - internal var javaOutputDir: File? = null + internal var javaOutputDir: File? + get() = taskData.javaOutputDir + set(value) { taskData.javaOutputDir = value } @get:Internal - internal var sourceSetName: String by Delegates.notNull() + internal val sourceSetName: String + get() = taskData.compilation.name @get:InputFiles @get:PathSensitive(PathSensitivity.RELATIVE) @@ -224,12 +233,7 @@ abstract class AbstractKotlinCompile() : AbstractKo @get:Input internal val moduleName: String - get() { - val baseName = project.convention.findPlugin(BasePluginConvention::class.java)?.archivesBaseName - ?: project.name - val suffix = if (sourceSetName == "main") "" else "_$sourceSetName" - return filterModuleName("${baseName}$suffix") - } + get() = taskData.compilation.moduleName @Suppress("UNCHECKED_CAST") @get:Internal @@ -635,8 +639,3 @@ open class Kotlin2JsCompile : AbstractKotlinCompile(), Ko compilerRunner.runJsCompilerAsync(sourceRoots.kotlinSourceFiles, commonSourceSet.toList(), args, environment) } } - -private val invalidModuleNameCharactersRegex = """[\\/\r\n\t]""".toRegex() - -private fun filterModuleName(moduleName: String): String = - moduleName.replace(invalidModuleNameCharactersRegex, "_") diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt index 12c443fe9dc..9e50c6e8568 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt @@ -21,6 +21,7 @@ import org.gradle.api.Task import org.gradle.api.UnknownTaskException import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.defaultSourceSetName import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinTask import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast @@ -99,7 +100,7 @@ internal open class KotlinTasksProvider(val targetName: String) { open fun registerKotlinJVMTask( project: Project, name: String, - compilation: KotlinCompilation<*>, + compilation: AbstractKotlinCompilation<*>, configureAction: (KotlinCompile) -> (Unit) ): TaskHolder { val properties = PropertiesProvider(project) @@ -114,7 +115,7 @@ internal open class KotlinTasksProvider(val targetName: String) { fun registerKotlinJSTask( project: Project, name: String, - compilation: KotlinCompilation<*>, + compilation: AbstractKotlinCompilation<*>, configureAction: (Kotlin2JsCompile) -> Unit ): TaskHolder { val properties = PropertiesProvider(project) @@ -129,7 +130,7 @@ internal open class KotlinTasksProvider(val targetName: String) { fun registerKotlinCommonTask( project: Project, name: String, - compilation: KotlinCompilation<*>, + compilation: AbstractKotlinCompilation<*>, configureAction: (KotlinCompileCommon) -> (Unit) ): TaskHolder { val properties = PropertiesProvider(project) @@ -145,7 +146,7 @@ internal open class KotlinTasksProvider(val targetName: String) { kotlinTaskHolder: TaskHolder>, project: Project, propertiesProvider: PropertiesProvider, - compilation: KotlinCompilation<*> + compilation: AbstractKotlinCompilation<*> ) { val configureAfterEvaluated = RunOnceAfterEvaluated("TaskProvider.configure") { val languageSettings = project.kotlinExtension.sourceSets.findByName(compilation.defaultSourceSetName)?.languageSettings @@ -156,7 +157,6 @@ internal open class KotlinTasksProvider(val targetName: String) { applyLanguageSettingsToKotlinTask(languageSettings, kotlinTask) } kotlinTaskHolder.configure { - it.sourceSetName = compilation.name it.friendTaskName = taskToFriendTaskMapper[it] propertiesProvider.mapKotlinTaskProperties(it) configureAfterEvaluated.onConfigure() @@ -179,7 +179,7 @@ internal class AndroidTasksProvider(targetName: String) : KotlinTasksProvider(ta kotlinTaskHolder: TaskHolder>, project: Project, propertiesProvider: PropertiesProvider, - compilation: KotlinCompilation<*> + compilation: AbstractKotlinCompilation<*> ) { super.configure(kotlinTaskHolder, project, propertiesProvider, compilation) kotlinTaskHolder.configure { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/kotlinCompileTaskData.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/kotlinCompileTaskData.kt new file mode 100644 index 00000000000..c93a1224da0 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/kotlinCompileTaskData.kt @@ -0,0 +1,67 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.tasks + +import org.gradle.api.Project +import org.gradle.api.plugins.ExtraPropertiesExtension +import org.gradle.api.provider.Property +import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilation +import java.io.File + +internal open class KotlinCompileTaskData( + val taskName: String, + val compilation: AbstractKotlinCompilation<*>, + @Suppress("UnstableApiUsage") + val destinationDir: Property, + @Suppress("UnstableApiUsage") + val useModuleDetection: Property +) { + private val taskBuildDirectory: File + get() = File(File(compilation.target.project.buildDir, KOTLIN_BUILD_DIR_NAME), taskName) + + val buildHistoryFile: File + get() = File(taskBuildDirectory, "build-history.bin") + + var javaOutputDir: File? = null + + companion object { + fun get(project: Project, taskName: String): KotlinCompileTaskData = project.getTaskDataMap().getValue(taskName) + + fun getTaskDataContainer(project: Project): Iterable = + project.getTaskDataMap().values.toSet() + + fun register( + taskName: String, + compilation: AbstractKotlinCompilation<*> + ): KotlinCompileTaskData { + val project = compilation.target.project + val container = project.getTaskDataMap() + + @Suppress("UnstableApiUsage") + return KotlinCompileTaskData( + taskName, + compilation, + project.objects.property(File::class.java).apply { + set(project.provider { error("destinationDir was not set for task ${project.path}$taskName") }) + }, + project.objects.property(Boolean::class.javaObjectType).apply { set(false) } + ).also { + container[taskName] = it + } + } + + private fun Project.getTaskDataMap(): MutableMap { + val ext = project.extensions.getByType(ExtraPropertiesExtension::class.java) + if (!ext.has(EXT_NAME)) { + ext.set(EXT_NAME, mutableMapOf()) + } + @Suppress("UNCHECKED_CAST") + return ext.get(EXT_NAME) as MutableMap + } + + private const val EXT_NAME = "kotlin.incremental.taskdata" + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/compatibiltiy.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/compatibiltiy.kt index 3ae63c17e59..bd84fd65004 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/compatibiltiy.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/compatibiltiy.kt @@ -25,6 +25,7 @@ import org.gradle.api.tasks.TaskInputs import org.gradle.api.tasks.TaskOutputs import org.gradle.api.tasks.bundling.AbstractArchiveTask import org.gradle.util.GradleVersion +import java.io.File internal val Task.inputsCompatible: TaskInputs get() = inputs @@ -50,7 +51,7 @@ internal fun TaskInputs.dirCompatible(dirPath: Any) { inputsDirMethod(this, dirPath) } -internal fun checkGradleCompatibility(minSupportedVersion: GradleVersion = GradleVersion.version("4.1")) { +internal fun checkGradleCompatibility(minSupportedVersion: GradleVersion = GradleVersion.version("4.3")) { val currentVersion = GradleVersion.current() if (currentVersion < minSupportedVersion) { throw GradleException( @@ -69,6 +70,16 @@ internal fun AbstractArchiveTask.setArchiveAppendixCompatible(appendixProvider: } } +internal val AbstractArchiveTask.archivePathCompatible: File + get() = + if (isGradleVersionAtLeast(5, 1)) { + @Suppress("UnstableApiUsage") + archiveFile.get().asFile + } else { + @Suppress("DEPRECATION") + archivePath + } + internal fun AbstractArchiveTask.setArchiveClassifierCompatible(classifierProvider: () -> String) { if (isGradleVersionAtLeast(5, 2)) { archiveClassifier.set(project.provider { classifierProvider() })