From 5815d6a70cad99ba4cc612900f9fb7abaeee7485 Mon Sep 17 00:00:00 2001 From: Sergey Igushkin Date: Thu, 9 Aug 2018 12:53:39 +0300 Subject: [PATCH] Implement language settings API for Kotlin source sets --- .../gradle/plugin/LanguageSettingsBuilder.kt | 18 +++++ .../gradle/plugin/source/KotlinSourceSet.kt | 13 +-- .../kotlin/gradle/NewMultiplatformIT.kt | 66 +++++++++++++++ .../kotlin/gradle/plugin/KotlinPlugin.kt | 8 +- .../gradle/plugin/mpp/kotlinCompilations.kt | 12 +++ .../plugin/sources/DefaultKotlinSourceSet.kt | 9 +++ .../sources/DefaultLanguageSettingsBuilder.kt | 77 ++++++++++++++++++ .../sources/SourceSetConsistencyChecker.kt | 80 +++++++++++++++++++ .../kotlin/gradle/tasks/TasksProvider.kt | 37 ++++++--- 9 files changed, 298 insertions(+), 22 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/LanguageSettingsBuilder.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultLanguageSettingsBuilder.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/SourceSetConsistencyChecker.kt diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/LanguageSettingsBuilder.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/LanguageSettingsBuilder.kt new file mode 100644 index 00000000000..9eef9c25cf0 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/LanguageSettingsBuilder.kt @@ -0,0 +1,18 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. 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.plugin + +interface LanguageSettingsBuilder { + var languageVersion: String? + + var apiVersion: String? + + var progressiveMode: Boolean + + fun enableLanguageFeature(name: String) + + val enabledLanguageFeatures: Set +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/source/KotlinSourceSet.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/source/KotlinSourceSet.kt index c496581913d..e22f1258ba1 100644 --- a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/source/KotlinSourceSet.kt +++ b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/source/KotlinSourceSet.kt @@ -9,19 +9,22 @@ import groovy.lang.Closure import org.gradle.api.Named import org.gradle.api.file.SourceDirectorySet import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies +import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder interface KotlinSourceSet : Named, HasKotlinDependencies { val kotlin: SourceDirectorySet + fun kotlin(configureClosure: Closure): SourceDirectorySet + val resources: SourceDirectorySet - fun kotlin(configureClosure: Closure): SourceDirectorySet + val languageSettings: LanguageSettingsBuilder + fun languageSettings(configureClosure: Closure): LanguageSettingsBuilder + + fun dependsOn(other: KotlinSourceSet) + val dependsOn: Set companion object { const val COMMON_MAIN_SOURCE_SET_NAME = "commonMain" const val COMMON_TEST_SOURCE_SET_NAME = "commonTest" } - - fun dependsOn(other: KotlinSourceSet) - - val dependsOn: Set } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt index 6d8c08bcedc..23eb74e6430 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.gradle +import org.jetbrains.kotlin.gradle.plugin.sources.SourceSetConsistencyChecks import org.jetbrains.kotlin.gradle.util.checkBytecodeContains import org.jetbrains.kotlin.gradle.util.modify import org.junit.Assert @@ -226,4 +227,69 @@ class NewMultiplatformIT : BaseGradleIT() { expectedKotlinOutputFiles.forEach { assertFileExists(it) } } } + + @Test + fun testLanguageSettingsApplied() = with(Project("sample-lib", gradleVersion, "new-mpp-lib-and-app")) { + setupWorkingDir() + + gradleBuildScript().appendText( + "\n" + """ + kotlin.sourceSets.jvm6Main.languageSettings { + languageVersion = '1.3' + apiVersion = '1.3' + enableLanguageFeature('InlineClasses') + progressiveMode = true + } + """.trimIndent() + ) + + build("compileKotlinJvm6") { + assertSuccessful() + assertContains("-language-version 1.3", "-api-version 1.3", "-XXLanguage:+InlineClasses", " -Xprogressive") + } + } + + @Test + fun testLanguageSettingsConsistency() = with(Project("sample-lib", gradleVersion, "new-mpp-lib-and-app")) { + setupWorkingDir() + + gradleBuildScript().appendText( + "\n" + """ + kotlin.sourceSets { + foo { } + bar { dependsOn foo } + } + """.trimIndent() + ) + + fun testMonotonousCheck(sourceSetConfigurationChange: String, expectedErrorHint: String) { + gradleBuildScript().appendText("\nkotlin.sourceSets.foo.${sourceSetConfigurationChange}") + build("tasks") { + assertFailed() + assertContains(expectedErrorHint) + } + gradleBuildScript().appendText("\nkotlin.sourceSets.bar.${sourceSetConfigurationChange}") + build("tasks") { + assertSuccessful() + } + } + + testMonotonousCheck("languageSettings.languageVersion = '1.4'", SourceSetConsistencyChecks.languageVersionCheckHint) + testMonotonousCheck("languageSettings.enableLanguageFeature('InlineClasses')", SourceSetConsistencyChecks.unstableFeaturesHint) + + // check that enabling a bugfix feature and progressive mode or advancing API level + // don't require doing the same for dependent source sets: + gradleBuildScript().appendText( + "\n" + """ + kotlin.sourceSets.foo.languageSettings { + apiVersion = '1.3' + enableLanguageFeature('SoundSmartcastForEnumEntries') + progressiveMode = true + } + """.trimIndent() + ) + build("tasks") { + assertSuccessful() + } + } } \ No newline at end of file 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 5c379226e83..bcf00f8253b 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 @@ -164,7 +164,7 @@ internal class Kotlin2JvmSourceSetProcessor( super.defaultKotlinDestinationDir override fun doCreateTask(project: Project, taskName: String): KotlinCompile = - tasksProvider.createKotlinJVMTask(project, taskName, kotlinCompilation.compilationName) + tasksProvider.createKotlinJVMTask(project, taskName, kotlinCompilation) override fun doTargetSpecificProcessing() { Kapt3KotlinGradleSubplugin.createAptConfigurationIfNeeded(project, kotlinCompilation.compilationName) @@ -254,7 +254,7 @@ internal class Kotlin2JsSourceSetProcessor( kotlinCompilation = kotlinCompilation ) { override fun doCreateTask(project: Project, taskName: String): Kotlin2JsCompile = - tasksProvider.createKotlinJSTask(project, taskName, kotlinCompilation.compilationName) + tasksProvider.createKotlinJSTask(project, taskName, kotlinCompilation) override fun doTargetSpecificProcessing() { project.tasks.findByName(kotlinCompilation.compileAllTaskName)!!.dependsOn(kotlinTask) @@ -332,7 +332,7 @@ internal class KotlinCommonSourceSetProcessor( } override fun doCreateTask(project: Project, taskName: String): KotlinCompileCommon = - tasksProvider.createKotlinCommonTask(project, taskName, kotlinCompilation.compilationName) + tasksProvider.createKotlinCommonTask(project, taskName, kotlinCompilation) } internal abstract class AbstractKotlinPlugin( @@ -712,7 +712,7 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationT val kotlinTaskName = compilation.compileKotlinTaskName // todo: Investigate possibility of creating and configuring kotlinTask before evaluation - val kotlinTask = tasksProvider.createKotlinJVMTask(project, kotlinTaskName, variantDataName) + val kotlinTask = tasksProvider.createKotlinJVMTask(project, kotlinTaskName, compilation) kotlinTask.parentKotlinOptionsImpl = rootKotlinOptions // store kotlin classes in separate directory. They will serve as class-path to java compiler 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 27ab6c66042..adae5df53aa 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 @@ -22,8 +22,10 @@ import org.gradle.api.file.FileCollection import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.SourceSetOutput import org.gradle.util.ConfigureUtil +import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.source.KotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.sources.defaultSourceSetLanguageSettingsChecker import org.jetbrains.kotlin.gradle.plugin.sources.getSourceSetHierarchy import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation @@ -82,6 +84,16 @@ abstract class AbstractKotlinCompilation( if (this is KotlinCompilationToRunnableFiles) { addExtendsFromRelation(runtimeOnlyConfigurationName, sourceSet.runtimeOnlyConfigurationName, forced = false) } + + if (sourceSet.name != defaultSourceSetName) { + // Temporary solution for checking consistency across source sets participating in a compilation that may + // not be interconnected with the dependsOn relation: check the settings as if the default source set of + // the compilation depends on the one added to the compilation: + defaultSourceSetLanguageSettingsChecker.runAllChecks( + kotlinExtension.sourceSets.getByName(defaultSourceSetName), + sourceSet + ) + } } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultKotlinSourceSet.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultKotlinSourceSet.kt index 107c3957dac..11a0254c086 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultKotlinSourceSet.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultKotlinSourceSet.kt @@ -13,6 +13,7 @@ import org.gradle.api.internal.file.DefaultSourceDirectorySet import org.gradle.api.internal.file.FileResolver import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler +import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinDependencyHandler import org.jetbrains.kotlin.gradle.plugin.source.KotlinSourceSet import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName @@ -41,10 +42,16 @@ class DefaultKotlinSourceSet( filter.include("**/*.java", "**/*.kt", "**/*.kts") } + override val languageSettings: LanguageSettingsBuilder = DefaultLanguageSettingsBuilder() + override val resources: SourceDirectorySet = createDefaultSourceDirectorySet(displayName + " resources", fileResolver) override fun kotlin(configureClosure: Closure): SourceDirectorySet = kotlin.apply { ConfigureUtil.configure(configureClosure, this) } + override fun languageSettings(configureClosure: Closure): LanguageSettingsBuilder = languageSettings.apply { + ConfigureUtil.configure(configureClosure, this) + } + override fun getName(): String = displayName override fun dependencies(configure: KotlinDependencyHandler.() -> Unit): Unit = @@ -58,6 +65,8 @@ class DefaultKotlinSourceSet( // Fail-fast approach: check on each new added edge and report a circular dependency at once when the edge is added. checkForCircularDependencies() + + project.afterEvaluate { defaultSourceSetLanguageSettingsChecker.runAllChecks(this, other) } } private val dependsOnSourceSetsImpl = mutableSetOf() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultLanguageSettingsBuilder.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultLanguageSettingsBuilder.kt new file mode 100644 index 00000000000..285888e4fcb --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultLanguageSettingsBuilder.kt @@ -0,0 +1,77 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. 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.plugin.sources + +import org.gradle.api.InvalidUserDataException +import org.jetbrains.kotlin.config.ApiVersion +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.LanguageVersion +import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder + +internal class DefaultLanguageSettingsBuilder : LanguageSettingsBuilder { + private var languageVersionImpl: LanguageVersion? = null + + override var languageVersion: String? + get() = languageVersionImpl?.versionString + set(value) { + languageVersionImpl = value?.let { versionString -> + LanguageVersion.fromVersionString(versionString) ?: throw InvalidUserDataException( + "Incorrect language version. Expected one of: ${LanguageVersion.values().joinToString { "'${it.versionString}'" }}" + ) + } + } + + private var apiVersionImpl: ApiVersion? = null + + override var apiVersion: String? + get() = apiVersionImpl?.versionString + set(value) { + apiVersionImpl = value ?.let { versionString -> + parseApiVersionSettings(versionString) ?: throw InvalidUserDataException( + "Incorrect API version. Expected one of: ${apiVersionValues.joinToString { "'${it.versionString}'" }}" + ) + } + } + + override var progressiveMode: Boolean = false + + private val enabledLanguageFeaturesImpl = mutableSetOf() + + override val enabledLanguageFeatures: Set + get() = enabledLanguageFeaturesImpl.map { it.name }.toSet() + + override fun enableLanguageFeature(name: String) { + val languageFeature = parseLanguageFeature(name) ?: throw InvalidUserDataException( + "Unknown language feature '${name}'" + ) + enabledLanguageFeaturesImpl += languageFeature + } + + companion object { + } +} + +internal fun applyLanguageSettingsToKotlinTask( + languageSettingsBuilder: LanguageSettingsBuilder, + kotlinTask: org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*> +) = with(kotlinTask.kotlinOptions) { + languageVersion = languageVersion ?: languageSettingsBuilder.languageVersion + apiVersion = apiVersion ?: languageSettingsBuilder.apiVersion + + if (languageSettingsBuilder.progressiveMode) { + freeCompilerArgs += "-Xprogressive" + } + + languageSettingsBuilder.enabledLanguageFeatures.forEach { featureName -> + freeCompilerArgs += "-XXLanguage:+$featureName" + } +} + +private val apiVersionValues = ApiVersion.run { listOf(KOTLIN_1_0, KOTLIN_1_1, KOTLIN_1_2, KOTLIN_1_3) } + +internal fun parseLanguageVersionSetting(versionString: String) = LanguageVersion.fromVersionString(versionString) +internal fun parseApiVersionSettings(versionString: String) = apiVersionValues.find { it.versionString == versionString } +internal fun parseLanguageFeature(featureName: String) = LanguageFeature.fromString(featureName) \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/SourceSetConsistencyChecker.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/SourceSetConsistencyChecker.kt new file mode 100644 index 00000000000..dd9b76d27ca --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/SourceSetConsistencyChecker.kt @@ -0,0 +1,80 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. 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.plugin.sources + +import org.gradle.api.InvalidUserDataException +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.LanguageVersion +import org.jetbrains.kotlin.gradle.plugin.source.KotlinSourceSet + +internal class ConsistencyCheck( + val name: String, + val getValue: (T) -> S, + val leftExtendsRightConsistently: (S, S) -> Boolean, + val consistencyConditionHint: String +) + +object SourceSetConsistencyChecks { + private val defaultLanguageVersion = LanguageVersion.LATEST_STABLE + + const val languageVersionCheckHint = + "The language version of the dependent source set must be greater than or equal to that of its dependency." + + internal val languageVersionCheck = ConsistencyCheck( + name = "language version", + getValue = { sourceSet -> + sourceSet.languageSettings.languageVersion?.let { parseLanguageVersionSetting(it) } ?: defaultLanguageVersion + }, + leftExtendsRightConsistently = { left, right -> left >= right }, + consistencyConditionHint = languageVersionCheckHint + ) + + const val unstableFeaturesHint = "The dependent source set must enable all unstable language features that its dependency has." + + internal val unstableFeaturesCheck = ConsistencyCheck>( + name = "unstable language feature set", + getValue = { sourceSet -> + sourceSet.languageSettings.enabledLanguageFeatures + .map { parseLanguageFeature(it)!! } + .filterTo(mutableSetOf()) { it.kind == LanguageFeature.Kind.UNSTABLE_FEATURE } + }, + leftExtendsRightConsistently = { left, right -> left.containsAll(right) }, + consistencyConditionHint = unstableFeaturesHint + ) +} + +internal class SourceSetConsistencyChecker( + val checks: List> +) { + fun runSingleCheck( + dependent: KotlinSourceSet, + dependency: KotlinSourceSet, + check: ConsistencyCheck + ) { + val leftValue = check.getValue(dependent) + val rightValue = check.getValue(dependency) + + if (!check.leftExtendsRightConsistently(leftValue, rightValue)) { + throw InvalidUserDataException( + "Inconsistent settings for Kotlin source sets: '${dependent.name}' depends on '${dependency.name}'\n" + + "'${dependent.name}': ${check.name} is ${leftValue}\n" + + "'${dependency.name}': ${check.name} is ${rightValue}\n" + + check.consistencyConditionHint + ) + } + } + + fun runAllChecks(dependent: KotlinSourceSet, dependency: KotlinSourceSet) { + for (check in checks) { + runSingleCheck(dependent, dependency, check) + } + } +} + +internal val defaultSourceSetLanguageSettingsChecker = with(SourceSetConsistencyChecks) { + // We don't check the progressive mode, since the features it enables are bugfixes + SourceSetConsistencyChecker(listOf(languageVersionCheck, unstableFeaturesCheck)) +} \ No newline at end of file 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 f746b249daf..efc4173106f 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 @@ -17,34 +17,45 @@ package org.jetbrains.kotlin.gradle.tasks import org.gradle.api.Project -import org.jetbrains.kotlin.gradle.plugin.RegexTaskToFriendTaskMapper -import org.jetbrains.kotlin.gradle.plugin.TaskToFriendTaskMapper -import org.jetbrains.kotlin.gradle.plugin.mapKotlinTaskProperties +import org.jetbrains.kotlin.gradle.dsl.kotlinExtension +import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.mpp.defaultSourceSetName +import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinTask internal open class KotlinTasksProvider(val targetName: String) { - open fun createKotlinJVMTask(project: Project, name: String, sourceSetName: String): KotlinCompile = + open fun createKotlinJVMTask( + project: Project, + name: String, + compilation: KotlinCompilation + ): KotlinCompile = project.tasks.create(name, KotlinCompile::class.java).apply { - configure(this, project, sourceSetName) + configure(this, project, compilation) } - fun createKotlinJSTask(project: Project, name: String, sourceSetName: String): Kotlin2JsCompile = + fun createKotlinJSTask(project: Project, name: String, compilation: KotlinCompilation): Kotlin2JsCompile = project.tasks.create(name, Kotlin2JsCompile::class.java).apply { - configure(this, project, sourceSetName) + configure(this, project, compilation) } - fun createKotlinCommonTask(project: Project, name: String, sourceSetName: String): KotlinCompileCommon = + fun createKotlinCommonTask(project: Project, name: String, compilation: KotlinCompilation): KotlinCompileCommon = project.tasks.create(name, KotlinCompileCommon::class.java).apply { - configure(this, project, sourceSetName) + configure(this, project, compilation) } open fun configure( kotlinTask: AbstractKotlinCompile<*>, project: Project, - sourceSetName: String + compilation: KotlinCompilation ) { - kotlinTask.sourceSetName = sourceSetName + kotlinTask.sourceSetName = compilation.name kotlinTask.friendTaskName = taskToFriendTaskMapper[kotlinTask] mapKotlinTaskProperties(project, kotlinTask) + + project.whenEvaluated { + val languageSettings = project.kotlinExtension.sourceSets.getByName(compilation.defaultSourceSetName).languageSettings + kotlinTask as org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*> + applyLanguageSettingsToKotlinTask(languageSettings, kotlinTask) + } } protected open val taskToFriendTaskMapper: TaskToFriendTaskMapper = @@ -55,8 +66,8 @@ internal class AndroidTasksProvider(targetName: String) : KotlinTasksProvider(ta override val taskToFriendTaskMapper: TaskToFriendTaskMapper = RegexTaskToFriendTaskMapper.Android(targetName) - override fun configure(kotlinTask: AbstractKotlinCompile<*>, project: Project, sourceSetName: String) { - super.configure(kotlinTask, project, sourceSetName) + override fun configure(kotlinTask: AbstractKotlinCompile<*>, project: Project, compilation: KotlinCompilation) { + super.configure(kotlinTask, project, compilation) kotlinTask.useModuleDetection = true } } \ No newline at end of file