[Gradle] LanguageSettings now is wrapper for related compiler options
'KotlinSourceSet.LanguageSettings' is now acts as a wrapper for the related Kotlin compilation task 'compilerOptions' object, similar to how 'kotlinOptions' is working now. Source sets consistency check now will ignore shared source sets with no linked compilation to avoid users need to configure them as well. ^KT-57292 In Progress
This commit is contained in:
committed by
Space Team
parent
bed16f92b1
commit
8df905a326
+96
-3
@@ -209,11 +209,11 @@ internal class CompilerOptionsIT : KGPBaseTest() {
|
||||
""".trimMargin()
|
||||
)
|
||||
|
||||
build("compileKotlinJvm6", forceOutput = true) {
|
||||
build("compileKotlinJvm6") {
|
||||
assertTasksExecuted(":compileKotlinJvm6")
|
||||
assert(output.contains("-opt-in another.custom.UnderOptIn,my.custom.OptInAnnotation")) {
|
||||
assert(output.contains("-opt-in my.custom.OptInAnnotation,another.custom.UnderOptIn")) {
|
||||
printBuildOutput()
|
||||
"Output does not contain '-opt-in another.custom.UnderOptIn,my.custom.OptInAnnotation'!"
|
||||
"Output does not contain '-opt-in my.custom.OptInAnnotation,another.custom.UnderOptIn'!"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -528,4 +528,97 @@ internal class CompilerOptionsIT : KGPBaseTest() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@GradleTest
|
||||
@DisplayName("Syncs languageSettings changes to the related compiler options")
|
||||
@MppGradlePluginTests
|
||||
fun syncLanguageSettingsToCompilerOptions(gradleVersion: GradleVersion) {
|
||||
project("mpp-default-hierarchy", gradleVersion) {
|
||||
buildGradle.appendText(
|
||||
//language=groovy
|
||||
"""
|
||||
|
|
||||
|kotlin.sourceSets.configureEach {
|
||||
| languageSettings.apiVersion = "1.7"
|
||||
| languageSettings.languageVersion = "1.8"
|
||||
|}
|
||||
|
|
||||
|tasks.register("printCompilerOptions") {
|
||||
| dependsOn(kotlinTaskToCheck)
|
||||
| def tasksContainer = project.tasks
|
||||
| doLast {
|
||||
| def kotlinTask = tasks.getByName(kotlinTaskToCheck) as org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask<?>
|
||||
| logger.warn("###AV:${'$'}{kotlinTask.compilerOptions.apiVersion.getOrNull()}")
|
||||
| logger.warn("###LV:${'$'}{kotlinTask.compilerOptions.languageVersion.getOrNull()}")
|
||||
| }
|
||||
|}
|
||||
""".trimMargin()
|
||||
)
|
||||
|
||||
listOf(
|
||||
"compileCommonMainKotlinMetadata",
|
||||
"compileKotlinJvm",
|
||||
"compileNativeMainKotlinMetadata",
|
||||
"compileLinuxMainKotlinMetadata",
|
||||
"compileAppleMainKotlinMetadata",
|
||||
"compileIosMainKotlinMetadata",
|
||||
"compileKotlinLinuxX64",
|
||||
"compileKotlinLinuxArm64",
|
||||
"compileKotlinIosX64",
|
||||
"compileKotlinIosArm64"
|
||||
).forEach { task ->
|
||||
build("printCompilerOptions", "-PkotlinTaskToCheck=$task") {
|
||||
assertOutputContains("###AV:KOTLIN_1_7")
|
||||
assertOutputContains("###LV:KOTLIN_1_8")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@GradleTest
|
||||
@DisplayName("Syncs compiler option changes to the related language settings")
|
||||
@MppGradlePluginTests
|
||||
fun syncCompilerOptionsToLanguageSettings(gradleVersion: GradleVersion) {
|
||||
project("mpp-default-hierarchy", gradleVersion) {
|
||||
buildGradle.appendText(
|
||||
//language=groovy
|
||||
"""
|
||||
|
|
||||
|tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask.class).all {
|
||||
| compilerOptions {
|
||||
| apiVersion = org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_7
|
||||
| languageVersion = org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_8
|
||||
| }
|
||||
|}
|
||||
|
|
||||
|tasks.register("printLanguageSettingsOptions") {
|
||||
| doLast {
|
||||
| def languageSettings = kotlin.sourceSets.getByName(kotlinSourceSet).languageSettings
|
||||
| logger.warn("")
|
||||
| logger.warn("###AV:${'$'}{languageSettings.apiVersion}")
|
||||
| logger.warn("###LV:${'$'}{languageSettings.languageVersion}")
|
||||
| }
|
||||
|}
|
||||
""".trimMargin()
|
||||
)
|
||||
|
||||
listOf(
|
||||
"commonMain",
|
||||
"jvmMain",
|
||||
"nativeMain",
|
||||
"linuxMain",
|
||||
"appleMain",
|
||||
"iosMain",
|
||||
"linuxX64Main",
|
||||
"linuxArm64Main",
|
||||
"iosX64Main",
|
||||
"iosArm64Main",
|
||||
).forEach { sourceSet ->
|
||||
build("printLanguageSettingsOptions", "-PkotlinSourceSet=${sourceSet}") {
|
||||
assertOutputContains("###AV:1.7")
|
||||
assertOutputContains("###LV:1.8")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -140,7 +140,7 @@ class CompilerOptionsProjectIT : KGPBaseTest() {
|
||||
| languageVersion = '1.9'
|
||||
| apiVersion = '1.9'
|
||||
| progressiveMode = false
|
||||
| optInAnnotationsInUse.add("another.CustomOptInAnnotation")
|
||||
| optIn("another.CustomOptInAnnotation")
|
||||
| enableLanguageFeature("UnitConversionsOnArbitraryExpressions")
|
||||
| }
|
||||
| }
|
||||
|
||||
+31
-20
@@ -778,47 +778,58 @@ open class NewMultiplatformIT : BaseGradleIT() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLanguageSettingsConsistency() = with(Project("sample-lib", gradleVersion, "new-mpp-lib-and-app")) {
|
||||
fun testLanguageSettingsConsistency() = with(
|
||||
Project("sample-lib", gradleVersion, "new-mpp-lib-and-app", minLogLevel = LogLevel.INFO)
|
||||
) {
|
||||
setupWorkingDir()
|
||||
|
||||
gradleBuildScript().appendText(
|
||||
"\n" + """
|
||||
kotlin.sourceSets {
|
||||
foo { }
|
||||
bar { dependsOn foo }
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
fun testMonotonousCheck(
|
||||
initialSetupForSourceSets: String?,
|
||||
sourceSetConfigurationChange: String,
|
||||
expectedErrorHint: String,
|
||||
initialSetupForSourceSets: String? = null,
|
||||
) {
|
||||
if (initialSetupForSourceSets != null) {
|
||||
gradleBuildScript().appendText(
|
||||
"\nkotlin.sourceSets.foo.${initialSetupForSourceSets}\n" + "" +
|
||||
"kotlin.sourceSets.bar.${initialSetupForSourceSets}",
|
||||
"""
|
||||
|
|
||||
|kotlin.sourceSets.commonMain.${initialSetupForSourceSets}
|
||||
|kotlin.sourceSets.nativeMain.${initialSetupForSourceSets}
|
||||
|kotlin.sourceSets.linux64Main.${initialSetupForSourceSets}
|
||||
|kotlin.sourceSets.macos64Main.${initialSetupForSourceSets}
|
||||
|kotlin.sourceSets.jvm6Main.${initialSetupForSourceSets}
|
||||
|kotlin.sourceSets.mingw64Main.${initialSetupForSourceSets}
|
||||
|kotlin.sourceSets.nodeJsMain.${initialSetupForSourceSets}
|
||||
|kotlin.sourceSets.wasmMain.${initialSetupForSourceSets}
|
||||
""".trimMargin()
|
||||
)
|
||||
}
|
||||
gradleBuildScript().appendText("\nkotlin.sourceSets.foo.${sourceSetConfigurationChange}")
|
||||
gradleBuildScript().appendText("\nkotlin.sourceSets.commonMain.${sourceSetConfigurationChange}")
|
||||
build("tasks") {
|
||||
assertFailed()
|
||||
assertContains(expectedErrorHint)
|
||||
}
|
||||
gradleBuildScript().appendText("\nkotlin.sourceSets.bar.${sourceSetConfigurationChange}")
|
||||
gradleBuildScript().appendText(
|
||||
"""
|
||||
|
|
||||
|kotlin.sourceSets.nativeMain.${sourceSetConfigurationChange}
|
||||
|kotlin.sourceSets.linux64Main.${sourceSetConfigurationChange}
|
||||
|kotlin.sourceSets.macos64Main.${sourceSetConfigurationChange}
|
||||
|kotlin.sourceSets.jvm6Main.${sourceSetConfigurationChange}
|
||||
|kotlin.sourceSets.mingw64Main.${sourceSetConfigurationChange}
|
||||
|kotlin.sourceSets.nodeJsMain.${sourceSetConfigurationChange}
|
||||
|kotlin.sourceSets.wasmMain.${sourceSetConfigurationChange}
|
||||
""".trimMargin()
|
||||
)
|
||||
build("tasks") {
|
||||
assertSuccessful()
|
||||
}
|
||||
}
|
||||
|
||||
fun testMonotonousCheck(sourceSetConfigurationChange: String, expectedErrorHint: String): Unit =
|
||||
testMonotonousCheck(null, sourceSetConfigurationChange, expectedErrorHint)
|
||||
|
||||
testMonotonousCheck(
|
||||
"languageSettings.languageVersion = '1.3'",
|
||||
"languageSettings.languageVersion = '1.4'",
|
||||
"The language version of the dependent source set must be greater than or equal to that of its dependency."
|
||||
"The language version of the dependent source set must be greater than or equal to that of its dependency.",
|
||||
"languageSettings.languageVersion = '1.3'",
|
||||
)
|
||||
|
||||
testMonotonousCheck(
|
||||
@@ -835,7 +846,7 @@ open class NewMultiplatformIT : BaseGradleIT() {
|
||||
// don't require doing the same for dependent source sets:
|
||||
gradleBuildScript().appendText(
|
||||
"\n" + """
|
||||
kotlin.sourceSets.foo.languageSettings {
|
||||
kotlin.sourceSets.commonMain.languageSettings {
|
||||
apiVersion = '1.4'
|
||||
enableLanguageFeature('SoundSmartcastForEnumEntries')
|
||||
progressiveMode = true
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.multiplatform"
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm()
|
||||
|
||||
linuxX64()
|
||||
linuxArm64()
|
||||
|
||||
iosX64()
|
||||
iosArm64()
|
||||
|
||||
applyDefaultHierarchyTemplate()
|
||||
}
|
||||
+1
-1
@@ -165,7 +165,7 @@ class GradleProjectModuleBuilder(private val addInferredSourceSetVisibilityAsExp
|
||||
?: listOf(compilation.defaultSourceSetName)
|
||||
|
||||
variantNames.forEach { variantName ->
|
||||
val variant = KpmBasicVariant(this@apply, variantName, DefaultLanguageSettingsBuilder())
|
||||
val variant = KpmBasicVariant(this@apply, variantName, DefaultLanguageSettingsBuilder(project))
|
||||
moduleByFragment[variant] = this@apply
|
||||
variantToCompilation[variant] = compilation
|
||||
fragments.add(variant)
|
||||
|
||||
+4
-3
@@ -204,9 +204,10 @@ internal fun Project.setupGeneralKotlinExtensionParameters() {
|
||||
.awaitPlatformCompilations()
|
||||
.any { KotlinSourceSetTree.orNull(it) == KotlinSourceSetTree.main }
|
||||
|
||||
languageSettings.explicitApi = project.providers.provider {
|
||||
val explicitApiFlag = project.kotlinExtension.explicitApiModeAsCompilerArg()
|
||||
explicitApiFlag.takeIf { isMainSourceSet }
|
||||
if (isMainSourceSet) {
|
||||
languageSettings.explicitApi = project.providers.provider {
|
||||
project.kotlinExtension.explicitApiModeAsCompilerArg()
|
||||
}
|
||||
}
|
||||
|
||||
languageSettings.freeCompilerArgsProvider = project.provider {
|
||||
|
||||
+2
-1
@@ -8,5 +8,6 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinCompilationImplFactory
|
||||
|
||||
internal val DefaultKotlinCompilationPreConfigure = KotlinCompilationImplFactory.PreConfigure.composite(
|
||||
KotlinCompilationK2MultiplatformConfigurator
|
||||
KotlinCompilationK2MultiplatformConfigurator,
|
||||
KotlinCompilationLanguageSettingsConfigurator,
|
||||
)
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.plugin.mpp.compilationImpl
|
||||
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinCompilationImplFactory
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
|
||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
|
||||
|
||||
/**
|
||||
* Wires compilations compiler options into source sets [org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet.languageSettings].
|
||||
*/
|
||||
internal object KotlinCompilationLanguageSettingsConfigurator : KotlinCompilationImplFactory.PreConfigure {
|
||||
override fun configure(compilation: KotlinCompilationImpl) {
|
||||
// Ignoring non-klib common compilation as it reuses defaultSourceSet with klib common compilation
|
||||
if (compilation.platformType == KotlinPlatformType.common &&
|
||||
compilation.name == KotlinCompilation.MAIN_COMPILATION_NAME
|
||||
) return
|
||||
|
||||
// Ignoring jsLegacy as it shares a source set with jsIR
|
||||
if (compilation.platformType == KotlinPlatformType.js &&
|
||||
compilation.target is KotlinJsTarget
|
||||
) return
|
||||
|
||||
val languageSettingsBuilder = (compilation.defaultSourceSet.languageSettings as DefaultLanguageSettingsBuilder)
|
||||
if (languageSettingsBuilder.compilationCompilerOptions.isCompleted) {
|
||||
compilation.target.project.logger.warn(
|
||||
"Compiler options for compilation ${compilation.name} default source set ${compilation.defaultSourceSet.name} " +
|
||||
"'languageSettings' was already set!"
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
languageSettingsBuilder
|
||||
.compilationCompilerOptions
|
||||
.complete(compilation.compilerOptions.options)
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -9,7 +9,9 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl
|
||||
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.launchInStage
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.InternalKotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.addSourcesToKotlinCompileTask
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.defaultSourceSetLanguageSettingsChecker
|
||||
@@ -63,7 +65,9 @@ internal class KotlinCompilationSourceSetInclusion(
|
||||
// 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(compilation.defaultSourceSet, sourceSet)
|
||||
compilation.project.launchInStage(KotlinPluginLifecycle.Stage.FinaliseCompilations) {
|
||||
defaultSourceSetLanguageSettingsChecker.runAllChecks(compilation.defaultSourceSet, sourceSet)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ abstract class GradleKpmFragmentInternal @Inject constructor(
|
||||
// TODO pull up to KotlinModuleFragment
|
||||
// FIXME apply to compilation
|
||||
// FIXME check for consistency
|
||||
override val languageSettings: LanguageSettingsBuilder = DefaultLanguageSettingsBuilder()
|
||||
override val languageSettings: LanguageSettingsBuilder = DefaultLanguageSettingsBuilder(project)
|
||||
|
||||
override fun refines(other: GradleKpmFragment) {
|
||||
checkCanRefine(other)
|
||||
|
||||
+1
-1
@@ -81,7 +81,7 @@ internal fun buildSyntheticPlainModule(
|
||||
): GradleKpmExternalPlainModule {
|
||||
val moduleDependency = resolvedComponentResult.toKpmModuleDependency()
|
||||
return GradleKpmExternalPlainModule(KpmBasicModule(moduleDependency.moduleIdentifier).apply {
|
||||
KpmBasicVariant(this@apply, singleVariantName, DefaultLanguageSettingsBuilder()).apply {
|
||||
KpmBasicVariant(this@apply, singleVariantName, DefaultLanguageSettingsBuilder(TODO())).apply {
|
||||
fragments.add(this)
|
||||
this.declaredModuleDependencies.addAll(
|
||||
resolvedComponentResult.dependencies
|
||||
|
||||
+36
-13
@@ -7,7 +7,7 @@ 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.dsl.KotlinVersion
|
||||
import org.jetbrains.kotlin.project.model.LanguageSettings
|
||||
|
||||
internal class ConsistencyCheck<T, S>(
|
||||
@@ -21,45 +21,68 @@ internal class FragmentConsistencyChecks<T>(
|
||||
unitName: String, // "fragment" or "source set"
|
||||
private val languageSettings: T.() -> LanguageSettings
|
||||
) {
|
||||
private val defaultLanguageVersion = LanguageVersion.LATEST_STABLE
|
||||
private val defaultLanguageVersion = KotlinVersion.DEFAULT
|
||||
|
||||
private val languageVersionCheckHint =
|
||||
"The language version of the dependent $unitName must be greater than or equal to that of its dependency."
|
||||
|
||||
val languageVersionCheck = ConsistencyCheck<T, LanguageVersion>(
|
||||
private val languageVersionCheck = ConsistencyCheck<T, KotlinVersion?>(
|
||||
name = "language version",
|
||||
getValue = { unit ->
|
||||
unit.languageSettings().languageVersion?.let { parseLanguageVersionSetting(it) } ?: defaultLanguageVersion
|
||||
unit.languageSettings().getValueIfExists {
|
||||
languageVersion?.let { KotlinVersion.fromVersion(it) } ?: defaultLanguageVersion
|
||||
}
|
||||
},
|
||||
leftExtendsRightConsistently = { left, right ->
|
||||
if (left == null || right == null) true else left >= right
|
||||
},
|
||||
leftExtendsRightConsistently = { left, right -> left >= right },
|
||||
consistencyConditionHint = languageVersionCheckHint
|
||||
)
|
||||
|
||||
private val unstableFeaturesHint = "The dependent $unitName must enable all unstable language features that its dependency has."
|
||||
|
||||
val unstableFeaturesCheck = ConsistencyCheck<T, Set<LanguageFeature>>(
|
||||
private val unstableFeaturesCheck = ConsistencyCheck<T, Set<LanguageFeature>?>(
|
||||
name = "unstable language feature set",
|
||||
getValue = { unit ->
|
||||
unit.languageSettings().enabledLanguageFeatures
|
||||
.map { parseLanguageFeature(it)!! }
|
||||
.filterTo(mutableSetOf()) { it.kind == LanguageFeature.Kind.UNSTABLE_FEATURE }
|
||||
unit.languageSettings().getValueIfExists {
|
||||
enabledLanguageFeatures
|
||||
.mapNotNull { parseLanguageFeature(it) }
|
||||
.filterTo(mutableSetOf()) { it.kind == LanguageFeature.Kind.UNSTABLE_FEATURE }
|
||||
}
|
||||
},
|
||||
leftExtendsRightConsistently = { left, right ->
|
||||
if (left == null || right == null) true else left.containsAll(right)
|
||||
},
|
||||
leftExtendsRightConsistently = { left, right -> left.containsAll(right) },
|
||||
consistencyConditionHint = unstableFeaturesHint
|
||||
)
|
||||
|
||||
private val optInAnnotationsInUseHint = "The dependent $unitName must use all opt-in annotations that its dependency uses."
|
||||
|
||||
val optInAnnotationsCheck = ConsistencyCheck<T, Set<String>>(
|
||||
private val optInAnnotationsCheck = ConsistencyCheck<T, Set<String>?>(
|
||||
name = "set of opt-in annotations in use",
|
||||
getValue = { unit -> unit.languageSettings().optInAnnotationsInUse },
|
||||
leftExtendsRightConsistently = { left, right -> left.containsAll(right) },
|
||||
getValue = { unit -> unit.languageSettings().getValueIfExists { optInAnnotationsInUse } },
|
||||
leftExtendsRightConsistently = { left, right ->
|
||||
if (left == null || right == null) true else left.containsAll(right)
|
||||
},
|
||||
consistencyConditionHint = optInAnnotationsInUseHint
|
||||
)
|
||||
|
||||
val allChecks = listOf(languageVersionCheck, unstableFeaturesCheck, optInAnnotationsCheck)
|
||||
|
||||
private fun <T> LanguageSettings.getValueIfExists(
|
||||
getValue: LanguageSettings.() -> T?
|
||||
): T? {
|
||||
val defaultLanguageSettingsBuilder = this as DefaultLanguageSettingsBuilder
|
||||
return if (defaultLanguageSettingsBuilder.compilationCompilerOptions.isCompleted) {
|
||||
getValue(defaultLanguageSettingsBuilder)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun parseLanguageFeature(featureName: String) = LanguageFeature.fromString(featureName)
|
||||
|
||||
internal class FragmentConsistencyChecker<T>(
|
||||
private val unitsName: String,
|
||||
private val name: T.() -> String,
|
||||
|
||||
+5
-6
@@ -12,9 +12,8 @@ import org.gradle.api.Project
|
||||
import org.gradle.api.file.SourceDirectorySet
|
||||
import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.launchInStage
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.utils.*
|
||||
import org.jetbrains.kotlin.tooling.core.MutableExtras
|
||||
@@ -68,7 +67,7 @@ abstract class DefaultKotlinSourceSet @Inject constructor(
|
||||
|
||||
override val kotlin: SourceDirectorySet = createDefaultSourceDirectorySet(project, "$name Kotlin source")
|
||||
|
||||
override val languageSettings: LanguageSettingsBuilder = DefaultLanguageSettingsBuilder()
|
||||
override val languageSettings: LanguageSettingsBuilder = DefaultLanguageSettingsBuilder(project)
|
||||
|
||||
override val resources: SourceDirectorySet = createDefaultSourceDirectorySet(project, "$name resources")
|
||||
|
||||
@@ -95,7 +94,7 @@ abstract class DefaultKotlinSourceSet @Inject constructor(
|
||||
dependencies { configure.execute(this) }
|
||||
|
||||
override fun afterDependsOnAdded(other: KotlinSourceSet) {
|
||||
project.runProjectConfigurationHealthCheckWhenEvaluated {
|
||||
project.launchInStage(KotlinPluginLifecycle.Stage.FinaliseCompilations) {
|
||||
defaultSourceSetLanguageSettingsChecker.runAllChecks(this@DefaultKotlinSourceSet, other)
|
||||
}
|
||||
}
|
||||
@@ -175,7 +174,7 @@ abstract class DefaultKotlinSourceSet @Inject constructor(
|
||||
}
|
||||
|
||||
internal val defaultSourceSetLanguageSettingsChecker =
|
||||
FragmentConsistencyChecker<KotlinSourceSet>(
|
||||
FragmentConsistencyChecker(
|
||||
unitsName = "source sets",
|
||||
name = { name },
|
||||
checks = FragmentConsistencyChecks<KotlinSourceSet>(
|
||||
|
||||
+130
-100
@@ -5,74 +5,118 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin.sources
|
||||
|
||||
import org.gradle.api.InvalidUserDataException
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.jetbrains.kotlin.config.ApiVersion
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersion
|
||||
import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompilerOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompilerOptionsDefault
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
|
||||
import org.jetbrains.kotlin.gradle.dsl.toCompilerValue
|
||||
import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompileTool
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinNativeCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.toSingleCompilerPluginOptions
|
||||
import org.jetbrains.kotlin.project.model.LanguageSettings
|
||||
import kotlin.properties.Delegates
|
||||
import org.jetbrains.kotlin.gradle.utils.*
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultLanguageSettingsBuilder : LanguageSettingsBuilder {
|
||||
private var languageVersionImpl: LanguageVersion? = null
|
||||
internal open class DefaultLanguageSettingsBuilder @Inject constructor(
|
||||
@Transient private val project: Project
|
||||
) : LanguageSettingsBuilder {
|
||||
internal var compilationCompilerOptions: CompletableFuture<KotlinCommonCompilerOptions> = CompletableFuture()
|
||||
|
||||
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}'" }}"
|
||||
)
|
||||
init {
|
||||
project.launch {
|
||||
KotlinPluginLifecycle.Stage.AfterFinaliseCompilations.await()
|
||||
if (!compilationCompilerOptions.isCompleted) {
|
||||
// For shared source sets without any associated compilation, it would be a separate instance of common compiler options
|
||||
compilationCompilerOptions.complete(project.objects.newInstance<KotlinCommonCompilerOptionsDefault>())
|
||||
}
|
||||
}
|
||||
|
||||
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}'" }}"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// By using 'observable' delegate we are tracking value set by user and not default value,
|
||||
// so we could propagate it to the compiler options only if it was configured explicitly
|
||||
internal var setByUserProgressiveMode: Boolean? = null
|
||||
override var progressiveMode: Boolean by Delegates.observable(false) { _, _, newValue ->
|
||||
setByUserProgressiveMode = newValue
|
||||
}
|
||||
|
||||
private val enabledLanguageFeaturesImpl = mutableSetOf<LanguageFeature>()
|
||||
override var languageVersion: String? = null
|
||||
get() = if (compilationCompilerOptions.isCompleted) {
|
||||
compilationCompilerOptions.getOrThrow().languageVersion.orNull?.version
|
||||
} else {
|
||||
field
|
||||
}
|
||||
set(value) {
|
||||
field = value
|
||||
project.launch {
|
||||
compilationCompilerOptions.await()
|
||||
.languageVersion
|
||||
.set(value?.let { KotlinVersion.fromVersion(it) })
|
||||
}
|
||||
}
|
||||
|
||||
override var apiVersion: String? = null
|
||||
get() = if (compilationCompilerOptions.isCompleted) {
|
||||
compilationCompilerOptions.getOrThrow().apiVersion.orNull?.version
|
||||
} else {
|
||||
field
|
||||
}
|
||||
set(value) {
|
||||
field = value
|
||||
project.launch {
|
||||
compilationCompilerOptions.await()
|
||||
.apiVersion
|
||||
.set(value?.let { KotlinVersion.fromVersion(it) })
|
||||
}
|
||||
}
|
||||
|
||||
override var progressiveMode: Boolean = false
|
||||
get() = if (compilationCompilerOptions.isCompleted) {
|
||||
compilationCompilerOptions.getOrThrow().progressiveMode.get()
|
||||
} else {
|
||||
field
|
||||
}
|
||||
set(value) {
|
||||
field = value
|
||||
project.launch {
|
||||
compilationCompilerOptions.await()
|
||||
.progressiveMode
|
||||
.set(value)
|
||||
}
|
||||
}
|
||||
|
||||
private val enabledLanguageFeaturesField = mutableSetOf<String>()
|
||||
|
||||
override val enabledLanguageFeatures: Set<String>
|
||||
get() = enabledLanguageFeaturesImpl.map { it.name }.toSet()
|
||||
get() = if (compilationCompilerOptions.isCompleted) {
|
||||
compilationCompilerOptions.getOrThrow()
|
||||
.freeCompilerArgs
|
||||
.get()
|
||||
.filter { it.startsWith("-XXLanguage:+") }
|
||||
.map { it.substringAfter("-XXLanguage:+") }
|
||||
.toSet()
|
||||
} else {
|
||||
enabledLanguageFeaturesField.toSet()
|
||||
}
|
||||
|
||||
override fun enableLanguageFeature(name: String) {
|
||||
val languageFeature = parseLanguageFeature(name) ?: throw InvalidUserDataException(
|
||||
"Unknown language feature '${name}'"
|
||||
)
|
||||
enabledLanguageFeaturesImpl += languageFeature
|
||||
enabledLanguageFeaturesField.add(name)
|
||||
project.launch {
|
||||
compilationCompilerOptions.await()
|
||||
.freeCompilerArgs
|
||||
.add("-XXLanguage:+$name")
|
||||
}
|
||||
}
|
||||
|
||||
private val optInAnnotationsInUseImpl = mutableSetOf<String>()
|
||||
private val optInAnnotationsInUseField = mutableSetOf<String>()
|
||||
|
||||
override val optInAnnotationsInUse: Set<String> = optInAnnotationsInUseImpl
|
||||
override val optInAnnotationsInUse: Set<String>
|
||||
get() = if (compilationCompilerOptions.isCompleted) {
|
||||
compilationCompilerOptions.getOrThrow().optIn.get().toSet()
|
||||
} else {
|
||||
optInAnnotationsInUseField.toSet()
|
||||
}
|
||||
|
||||
override fun optIn(annotationName: String) {
|
||||
optInAnnotationsInUseImpl += annotationName
|
||||
optInAnnotationsInUseField.add(annotationName)
|
||||
project.launch {
|
||||
compilationCompilerOptions.await()
|
||||
.optIn.add(annotationName)
|
||||
}
|
||||
}
|
||||
|
||||
/* A Kotlin task that is responsible for code analysis of the owner of this language settings builder. */
|
||||
@@ -100,65 +144,51 @@ internal class DefaultLanguageSettingsBuilder : LanguageSettingsBuilder {
|
||||
}
|
||||
|
||||
var freeCompilerArgsProvider: Provider<List<String>>? = null
|
||||
get() = if (compilationCompilerOptions.isCompleted) {
|
||||
compilationCompilerOptions.getOrThrow().freeCompilerArgs
|
||||
} else {
|
||||
field
|
||||
}
|
||||
set(value) {
|
||||
field = value
|
||||
// Checking if the provider has value as it overwrites the convention
|
||||
// https://github.com/gradle/gradle/issues/20266
|
||||
if (value != null && value.isPresent) {
|
||||
project.launch {
|
||||
compilationCompilerOptions.await()
|
||||
.freeCompilerArgs.addAll(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Kept here for compatibility with IDEA Kotlin import. It relies on explicit api argument in `freeCompilerArgs` to enable related
|
||||
// inspections
|
||||
internal var explicitApi: Provider<String>? = null
|
||||
|
||||
internal val freeCompilerArgsForNonImport: List<String>
|
||||
get() = freeCompilerArgsProvider?.get().orEmpty()
|
||||
get() = if (compilationCompilerOptions.isCompleted) {
|
||||
val freeArgs = compilationCompilerOptions.getOrThrow()
|
||||
.freeCompilerArgs
|
||||
.get()
|
||||
freeArgs.find { it.startsWith("-Xexplicit-api") }?.let { project.providers.provider { it } }
|
||||
} else {
|
||||
field
|
||||
}
|
||||
set(value) {
|
||||
field = value
|
||||
// Checking if the provider has value as it overwrites the convention
|
||||
// https://github.com/gradle/gradle/issues/20266
|
||||
if (value != null && value.isPresent) {
|
||||
project.launch {
|
||||
compilationCompilerOptions.await()
|
||||
.freeCompilerArgs
|
||||
.add(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val freeCompilerArgs: List<String>
|
||||
get() = freeCompilerArgsProvider?.get()
|
||||
.orEmpty()
|
||||
.plus(explicitApi?.orNull)
|
||||
.filterNotNull()
|
||||
get() = if (compilationCompilerOptions.isCompleted) {
|
||||
compilationCompilerOptions.getOrThrow().freeCompilerArgs.get()
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
internal fun applyLanguageSettingsToCompilerOptions(
|
||||
languageSettingsBuilder: LanguageSettings,
|
||||
compilerOptions: KotlinCommonCompilerOptions,
|
||||
) = with(compilerOptions) {
|
||||
val languageSettingsBuilderDefault = languageSettingsBuilder as DefaultLanguageSettingsBuilder
|
||||
languageSettingsBuilderDefault.languageVersion?.let {
|
||||
languageVersion.convention(KotlinVersion.fromVersion(it))
|
||||
}
|
||||
languageSettingsBuilderDefault.apiVersion?.let {
|
||||
apiVersion.convention(KotlinVersion.fromVersion(it))
|
||||
}
|
||||
languageSettingsBuilderDefault.setByUserProgressiveMode?.let {
|
||||
progressiveMode.convention(it)
|
||||
}
|
||||
if (languageSettingsBuilder.optInAnnotationsInUse.isNotEmpty()) optIn.addAll(languageSettingsBuilder.optInAnnotationsInUse)
|
||||
|
||||
val freeArgs = mutableListOf<String>()
|
||||
languageSettingsBuilder.enabledLanguageFeatures.forEach { featureName ->
|
||||
freeArgs.add("-XXLanguage:+$featureName")
|
||||
}
|
||||
freeArgs.addAll(languageSettingsBuilderDefault.freeCompilerArgsForNonImport)
|
||||
|
||||
if (freeArgs.isNotEmpty()) {
|
||||
freeCompilerArgs.addAll(freeArgs)
|
||||
}
|
||||
}
|
||||
|
||||
private val apiVersionValues = ApiVersion.run {
|
||||
listOf(
|
||||
KOTLIN_1_0,
|
||||
KOTLIN_1_1,
|
||||
KOTLIN_1_2,
|
||||
KOTLIN_1_3,
|
||||
KOTLIN_1_4,
|
||||
KOTLIN_1_5,
|
||||
KOTLIN_1_6,
|
||||
KOTLIN_1_7,
|
||||
KOTLIN_1_8,
|
||||
KOTLIN_1_9,
|
||||
KOTLIN_2_0,
|
||||
KOTLIN_2_1,
|
||||
)
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
-9
@@ -330,15 +330,6 @@ class KotlinMetadataTargetConfigurator :
|
||||
compileDependencyFiles = project.files()
|
||||
}
|
||||
}
|
||||
|
||||
target.project.runOnceAfterEvaluated("Sync common compilation language settings to compiler options") {
|
||||
target.compilations.all { compilation ->
|
||||
applyLanguageSettingsToCompilerOptions(
|
||||
compilation.defaultSourceSet.languageSettings,
|
||||
compilation.compilerOptions.options
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-8
@@ -10,7 +10,6 @@ import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.DeprecatedTargetPresetApi
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToCompilerOptions
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.KotlinMetadataTargetConfigurator
|
||||
|
||||
@DeprecatedTargetPresetApi
|
||||
@@ -58,12 +57,5 @@ class KotlinMetadataTargetPreset(
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
mainCompilation.addSourceSet(commonMainSourceSet)
|
||||
|
||||
project.whenEvaluated {
|
||||
// Since there's no default source set, apply language settings from commonMain:
|
||||
mainCompilation.compileTaskProvider.configure { compileKotlinMetadata ->
|
||||
applyLanguageSettingsToCompilerOptions(commonMainSourceSet.languageSettings, compileKotlinMetadata.compilerOptions)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-13
@@ -35,7 +35,6 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.apple.registerEmbedAndSignAppleFra
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.version
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleKpmVariant
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.copyAttributes
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
|
||||
import org.jetbrains.kotlin.gradle.targets.native.*
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.*
|
||||
@@ -51,6 +50,7 @@ import org.jetbrains.kotlin.gradle.testing.internal.configureConventions
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
|
||||
import org.jetbrains.kotlin.gradle.testing.testTaskName
|
||||
import org.jetbrains.kotlin.gradle.utils.XcodeUtils
|
||||
import org.jetbrains.kotlin.gradle.utils.named
|
||||
import org.jetbrains.kotlin.gradle.utils.newInstance
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
@@ -95,14 +95,11 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
||||
}
|
||||
|
||||
private fun Project.syncLanguageSettingsToLinkTask(binary: NativeBinary) {
|
||||
tasks.named(binary.linkTaskName, KotlinNativeLink::class.java).configure {
|
||||
tasks.named<KotlinNativeLink>(binary.linkTaskName).configure { linkTask ->
|
||||
// We propagate compilation free args to the link task for now (see KT-33717).
|
||||
val defaultLanguageSettings = binary.compilation.defaultSourceSet.languageSettings as? DefaultLanguageSettingsBuilder
|
||||
if (defaultLanguageSettings != null && defaultLanguageSettings.freeCompilerArgsForNonImport.isNotEmpty()) {
|
||||
it.toolOptions.freeCompilerArgs.addAll(
|
||||
defaultLanguageSettings.freeCompilerArgsForNonImport
|
||||
)
|
||||
}
|
||||
linkTask.toolOptions.freeCompilerArgs.addAll(
|
||||
binary.compilation.compilerOptions.options.freeCompilerArgs
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,11 +251,6 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
||||
project.syncLanguageSettingsToLinkTask(binary)
|
||||
}
|
||||
}
|
||||
project.launchInStage(KotlinPluginLifecycle.Stage.FinaliseCompilations) {
|
||||
target.compilations.all { compilation ->
|
||||
compilation.compilerOptions.syncLanguageSettings(compilation.defaultSourceSet.languageSettings)
|
||||
}
|
||||
}
|
||||
|
||||
target.binaries.withType(Executable::class.java).all {
|
||||
project.createRunTask(it)
|
||||
|
||||
-7
@@ -6,21 +6,14 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.native
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompilerOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinNativeCompilerOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinNativeCompilerOptionsDefault
|
||||
import org.jetbrains.kotlin.gradle.plugin.HasCompilerOptions
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToCompilerOptions
|
||||
import org.jetbrains.kotlin.gradle.utils.configureExperimentalTryK2
|
||||
import org.jetbrains.kotlin.project.model.LanguageSettings
|
||||
|
||||
class NativeCompilerOptions(project: Project) : HasCompilerOptions<KotlinNativeCompilerOptions> {
|
||||
|
||||
override val options: KotlinNativeCompilerOptions = project.objects
|
||||
.newInstance(KotlinNativeCompilerOptionsDefault::class.java)
|
||||
.configureExperimentalTryK2(project)
|
||||
|
||||
internal fun syncLanguageSettings(languageSettings: LanguageSettings) {
|
||||
applyLanguageSettingsToCompilerOptions(languageSettings, options)
|
||||
}
|
||||
}
|
||||
|
||||
+13
-12
@@ -38,10 +38,8 @@ import org.jetbrains.kotlin.gradle.plugin.cocoapods.asValidFrameworkName
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleKpmMetadataCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleKpmNativeCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
|
||||
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
||||
import org.jetbrains.kotlin.gradle.targets.native.KonanPropertiesBuildService
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.isAllowCommonizer
|
||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.utils.*
|
||||
import org.jetbrains.kotlin.gradle.utils.listFilesOrEmpty
|
||||
@@ -205,16 +203,16 @@ abstract class AbstractKotlinNativeCompile<
|
||||
@get:Input
|
||||
abstract val additionalCompilerOptions: Provider<Collection<String>>
|
||||
|
||||
@Deprecated("Use implementations compilerOptions")
|
||||
@get:Internal
|
||||
val languageSettings: LanguageSettings by project.provider {
|
||||
compilation.languageSettings
|
||||
}
|
||||
val languageSettings: LanguageSettings
|
||||
get() = compilation.languageSettings
|
||||
|
||||
@Suppress("DeprecatedCallableAddReplaceWith")
|
||||
@get:Deprecated("Replaced with 'compilerOptions.progressiveMode'")
|
||||
@get:Internal
|
||||
val progressiveMode: Boolean
|
||||
get() = languageSettings.progressiveMode
|
||||
get() = compilation.compilerOptions.options.progressiveMode.get()
|
||||
// endregion.
|
||||
|
||||
@Suppress("DeprecatedCallableAddReplaceWith")
|
||||
@@ -373,17 +371,21 @@ internal constructor(
|
||||
replaceWith = ReplaceWith("kotlinOptions.languageVersion")
|
||||
)
|
||||
val languageVersion: String?
|
||||
@Optional @Input get() = languageSettings.languageVersion
|
||||
@Optional @Input get() = compilerOptions.languageVersion.orNull?.version
|
||||
|
||||
@Deprecated(
|
||||
message = "Replaced with kotlinOptions.apiVersion",
|
||||
replaceWith = ReplaceWith("kotlinOptions.apiVersion")
|
||||
)
|
||||
val apiVersion: String?
|
||||
@Optional @Input get() = languageSettings.apiVersion
|
||||
@Optional @Input get() = compilerOptions.apiVersion.orNull?.version
|
||||
|
||||
@Deprecated("Language features is internal Kotlin compiler flags and should not be used directly")
|
||||
val enabledLanguageFeatures: Set<String>
|
||||
@Input get() = languageSettings.enabledLanguageFeatures
|
||||
@Internal get() = compilerOptions
|
||||
.freeCompilerArgs.get()
|
||||
.filter { it.startsWith("-XXLanguage:+") }
|
||||
.toSet()
|
||||
|
||||
@Deprecated(
|
||||
message = "Replaced with compilerOptions.optIn",
|
||||
@@ -414,15 +416,14 @@ internal constructor(
|
||||
fn.call()
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@Deprecated(
|
||||
message = "Replaced with compilerOptions.freeCompilerArgs",
|
||||
replaceWith = ReplaceWith("compilerOptions.freeCompilerArgs.get()")
|
||||
)
|
||||
@get:Input
|
||||
override val additionalCompilerOptions: Provider<Collection<String>>
|
||||
get() = compilerOptions
|
||||
.freeCompilerArgs
|
||||
.map { it + (languageSettings as DefaultLanguageSettingsBuilder).freeCompilerArgsForNonImport }
|
||||
get() = compilerOptions.freeCompilerArgs as Provider<Collection<String>>
|
||||
|
||||
private val runnerSettings = KotlinNativeCompilerRunner.Settings.fromProject(project)
|
||||
// endregion.
|
||||
|
||||
+3
-22
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.topLevelExtension
|
||||
import org.jetbrains.kotlin.gradle.incremental.IncrementalModuleInfoBuildService
|
||||
import org.jetbrains.kotlin.gradle.internal.ClassLoadersCachingBuildService
|
||||
import org.jetbrains.kotlin.gradle.internal.KaptGenerateStubsTask
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.internal.BuildIdService
|
||||
@@ -27,13 +26,10 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithClosure
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.internal
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToCompilerOptions
|
||||
import org.jetbrains.kotlin.gradle.report.BuildMetricsService
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.KOTLIN_BUILD_DIR_NAME
|
||||
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
||||
import org.jetbrains.kotlin.gradle.utils.providerWithLazyConvention
|
||||
import org.jetbrains.kotlin.project.model.LanguageSettings
|
||||
|
||||
/**
|
||||
* Configuration for the base compile task, [org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile].
|
||||
@@ -43,25 +39,10 @@ import org.jetbrains.kotlin.project.model.LanguageSettings
|
||||
*/
|
||||
internal abstract class AbstractKotlinCompileConfig<TASK : AbstractKotlinCompile<*>>(
|
||||
project: Project,
|
||||
val ext: KotlinTopLevelExtension,
|
||||
private val languageSettings: Provider<LanguageSettings>
|
||||
val ext: KotlinTopLevelExtension
|
||||
) : TaskConfigAction<TASK>(project) {
|
||||
|
||||
init {
|
||||
configureTaskProvider { taskProvider ->
|
||||
project.launchInStage(KotlinPluginLifecycle.Stage.AfterFinaliseCompilations) {
|
||||
taskProvider.configure {
|
||||
// KaptGenerateStubs will receive value from linked KotlinCompile task
|
||||
if (it is KaptGenerateStubsTask) return@configure
|
||||
|
||||
applyLanguageSettingsToCompilerOptions(
|
||||
languageSettings.get(),
|
||||
(it as org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask<*>).compilerOptions,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val compilerSystemPropertiesService = CompilerSystemPropertiesService.registerIfAbsent(project)
|
||||
val buildMetricsService = BuildMetricsService.registerIfAbsent(project)
|
||||
val incrementalModuleInfoProvider =
|
||||
@@ -120,6 +101,7 @@ internal abstract class AbstractKotlinCompileConfig<TASK : AbstractKotlinCompile
|
||||
task.incremental = false
|
||||
task.useModuleDetection.convention(false)
|
||||
if (propertiesProvider.useK2 == true) {
|
||||
@Suppress("DEPRECATION")
|
||||
task.compilerOptions.useK2.value(true)
|
||||
}
|
||||
task.runViaBuildToolsApi.convention(propertiesProvider.runKotlinCompilerViaBuildToolsApi).finalizeValueOnRead()
|
||||
@@ -139,8 +121,7 @@ internal abstract class AbstractKotlinCompileConfig<TASK : AbstractKotlinCompile
|
||||
|
||||
constructor(compilationInfo: KotlinCompilationInfo) : this(
|
||||
compilationInfo.project,
|
||||
compilationInfo.project.topLevelExtension,
|
||||
compilationInfo.project.provider { compilationInfo.languageSettings }
|
||||
compilationInfo.project.topLevelExtension
|
||||
) {
|
||||
configureTask { task ->
|
||||
task.friendPaths.from({ compilationInfo.friendPaths })
|
||||
|
||||
+1
-8
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.gradle.tasks.configuration
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension
|
||||
@@ -17,12 +16,10 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaCompilation
|
||||
import org.jetbrains.kotlin.gradle.utils.markResolvable
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
|
||||
import org.jetbrains.kotlin.gradle.plugin.tcsOrNull
|
||||
import org.jetbrains.kotlin.gradle.report.BuildMetricsService
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.utils.providerWithLazyConvention
|
||||
import org.jetbrains.kotlin.project.model.LanguageSettings
|
||||
|
||||
internal typealias KotlinCompileConfig = BaseKotlinCompileConfig<KotlinCompile>
|
||||
|
||||
@@ -99,7 +96,7 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
|
||||
|
||||
|
||||
constructor(project: Project, ext: KotlinTopLevelExtension) : super(
|
||||
project, ext, languageSettings = getDefaultLangSetting(project)
|
||||
project, ext
|
||||
)
|
||||
|
||||
companion object {
|
||||
@@ -109,10 +106,6 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
|
||||
private const val DIRECTORY_ARTIFACT_TYPE = "directory"
|
||||
private const val JAR_ARTIFACT_TYPE = "jar"
|
||||
const val CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE = "classpath-entry-snapshot"
|
||||
|
||||
private fun getDefaultLangSetting(project: Project): Provider<LanguageSettings> {
|
||||
return project.provider { DefaultLanguageSettingsBuilder() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerTransformsOnce(project: Project) {
|
||||
|
||||
+4
-4
@@ -90,12 +90,12 @@ class ExternalKotlinTargetApiTests {
|
||||
"Expected CompilationAssociator.default being set in ${ExternalKotlinCompilationDescriptorBuilder::class.simpleName}"
|
||||
)
|
||||
|
||||
defaults(kotlin)
|
||||
defaults(kotlin, "fakeMain")
|
||||
compileTaskName = "main"
|
||||
}
|
||||
|
||||
val auxCompilation = target.createCompilation<FakeCompilation> {
|
||||
defaults(kotlin)
|
||||
defaults(kotlin, "fakeAux")
|
||||
compilationName = "aux"
|
||||
}
|
||||
|
||||
@@ -114,13 +114,13 @@ class ExternalKotlinTargetApiTests {
|
||||
}
|
||||
|
||||
val mainCompilation = target.createCompilation<FakeCompilation> {
|
||||
defaults(kotlin)
|
||||
defaults(kotlin, "fakeMain")
|
||||
this.compilationAssociator = compilationAssociator
|
||||
this.compileTaskName = "main"
|
||||
}
|
||||
|
||||
val auxCompilation = target.createCompilation<FakeCompilation> {
|
||||
defaults(kotlin)
|
||||
defaults(kotlin, "fakeAux")
|
||||
this.compilationName = "aux"
|
||||
this.compilationAssociator = compilationAssociator
|
||||
}
|
||||
|
||||
+2
-2
@@ -61,12 +61,12 @@ class ExternalKotlinTargetSourcesJarUtilsTest {
|
||||
val target = multiplatformExtension.createExternalKotlinTarget<FakeTarget> { defaults() }
|
||||
|
||||
val mainCompilation = target.createCompilation<FakeCompilation> {
|
||||
defaults(multiplatformExtension)
|
||||
defaults(multiplatformExtension, "mainFake")
|
||||
compilationName = "main"
|
||||
}
|
||||
|
||||
val auxCompilation = target.createCompilation<FakeCompilation> {
|
||||
defaults(multiplatformExtension)
|
||||
defaults(multiplatformExtension, "auxFake")
|
||||
compilationName = "aux"
|
||||
}
|
||||
|
||||
|
||||
+24
-12
@@ -8,6 +8,8 @@
|
||||
package org.jetbrains.kotlin.gradle.unitTests
|
||||
|
||||
import org.gradle.kotlin.dsl.provideDelegate
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformSourceSetConventionsImpl.jvmMain
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformSourceSetConventionsImpl.jvmTest
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.configurationResult
|
||||
@@ -50,21 +52,31 @@ class KotlinMultiplatformSourceSetConventionsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - languageSettings`() = buildProjectWithMPP().runLifecycleAwareTest {
|
||||
multiplatformExtension.apply {
|
||||
jvm()
|
||||
fun `test - languageSettings`() {
|
||||
val project = buildProjectWithMPP()
|
||||
project.runLifecycleAwareTest {
|
||||
multiplatformExtension.apply {
|
||||
jvm()
|
||||
|
||||
sourceSets.jvmMain.languageSettings {
|
||||
optIn("jvmMain.optIn")
|
||||
}
|
||||
|
||||
sourceSets.jvmTest.languageSettings {
|
||||
this.optIn("jvmTest.optIn")
|
||||
}
|
||||
|
||||
sourceSets.jvmMain.languageSettings {
|
||||
this.optIn("jvmMain.optIn")
|
||||
}
|
||||
|
||||
sourceSets.jvmTest.languageSettings {
|
||||
this.optIn("jvmTest.optIn")
|
||||
}
|
||||
|
||||
assertEquals(setOf("jvmMain.optIn"), sourceSets.jvmMain.get().languageSettings.optInAnnotationsInUse)
|
||||
assertEquals(setOf("jvmTest.optIn"), sourceSets.jvmTest.get().languageSettings.optInAnnotationsInUse)
|
||||
}
|
||||
|
||||
assertEquals(
|
||||
setOf("jvmMain.optIn"),
|
||||
project.multiplatformExtension.sourceSets.jvmMain.get().languageSettings.optInAnnotationsInUse
|
||||
)
|
||||
assertEquals(
|
||||
setOf("jvmTest.optIn"),
|
||||
project.multiplatformExtension.sourceSets.jvmTest.get().languageSettings.optInAnnotationsInUse
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.unitTests
|
||||
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.withType
|
||||
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class LanguageSettingsTests {
|
||||
|
||||
@Test
|
||||
fun languageSettingsSyncToCompilerOptions() {
|
||||
val project = buildProjectWithMPP {
|
||||
with(multiplatformExtension) {
|
||||
jvm()
|
||||
|
||||
linuxX64()
|
||||
linuxArm64()
|
||||
|
||||
iosX64()
|
||||
iosArm64()
|
||||
|
||||
applyDefaultHierarchyTemplate()
|
||||
|
||||
sourceSets.configureEach {
|
||||
it.languageSettings {
|
||||
apiVersion = "1.7"
|
||||
languageVersion = "1.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
project.evaluate()
|
||||
|
||||
listOf(
|
||||
"compileCommonMainKotlinMetadata",
|
||||
"compileKotlinJvm",
|
||||
"compileNativeMainKotlinMetadata",
|
||||
"compileLinuxMainKotlinMetadata",
|
||||
"compileAppleMainKotlinMetadata",
|
||||
"compileIosMainKotlinMetadata",
|
||||
"compileKotlinLinuxX64",
|
||||
"compileKotlinLinuxArm64",
|
||||
"compileKotlinIosX64",
|
||||
"compileKotlinIosArm64"
|
||||
).forEach { taskName ->
|
||||
val compileTask = project.tasks.getByName(taskName) as KotlinCompilationTask<*>
|
||||
with(compileTask.compilerOptions) {
|
||||
assertEquals(apiVersion.orNull, KotlinVersion.KOTLIN_1_7)
|
||||
assertEquals(languageVersion.orNull, KotlinVersion.KOTLIN_1_8)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun compilerOptionsSyncToLanguageSettings() {
|
||||
val project = buildProjectWithMPP {
|
||||
with(multiplatformExtension) {
|
||||
jvm()
|
||||
|
||||
linuxX64()
|
||||
linuxArm64()
|
||||
|
||||
iosX64()
|
||||
iosArm64()
|
||||
|
||||
applyDefaultHierarchyTemplate()
|
||||
}
|
||||
|
||||
|
||||
tasks.withType<KotlinCompilationTask<*>>().all {
|
||||
it.compilerOptions {
|
||||
apiVersion.set(KotlinVersion.KOTLIN_1_7)
|
||||
languageVersion.set(KotlinVersion.KOTLIN_1_8)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
project.evaluate()
|
||||
|
||||
listOf(
|
||||
"commonMain",
|
||||
"jvmMain",
|
||||
"nativeMain",
|
||||
"linuxMain",
|
||||
"appleMain",
|
||||
"iosMain",
|
||||
"linuxX64Main",
|
||||
"linuxArm64Main",
|
||||
"iosX64Main",
|
||||
"iosArm64Main",
|
||||
).forEach { sourceSetName ->
|
||||
with(project.multiplatformExtension.sourceSets.getByName(sourceSetName).languageSettings) {
|
||||
assertEquals("1.7", apiVersion)
|
||||
assertEquals("1.8", languageVersion)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-3
@@ -20,8 +20,11 @@ fun ExternalKotlinTargetDescriptorBuilder<FakeTarget>.defaults() {
|
||||
targetFactory = TargetFactory(::FakeTarget)
|
||||
}
|
||||
|
||||
fun ExternalKotlinCompilationDescriptorBuilder<FakeCompilation>.defaults(kotlin: KotlinMultiplatformExtension) {
|
||||
compilationName = "fake"
|
||||
fun ExternalKotlinCompilationDescriptorBuilder<FakeCompilation>.defaults(
|
||||
kotlin: KotlinMultiplatformExtension,
|
||||
name: String = "fake"
|
||||
) {
|
||||
compilationName = name
|
||||
compilationFactory = CompilationFactory(::FakeCompilation)
|
||||
defaultSourceSet = kotlin.sourceSets.maybeCreate("fake")
|
||||
defaultSourceSet = kotlin.sourceSets.maybeCreate(name)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user