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() })