Support -Xuse-experimental in the new MPP languageSettings { ... } DSL

Add the corresponding Gradle plugin DSL, consistency checks, and logic
for propagating these settings to the compiler during build.

Issue #KT-26840 In Progress
This commit is contained in:
Sergey Igushkin
2018-10-10 17:54:24 +03:00
parent bde6d841c1
commit 5db23f1a81
6 changed files with 74 additions and 17 deletions
@@ -15,4 +15,8 @@ interface LanguageSettingsBuilder {
fun enableLanguageFeature(name: String) fun enableLanguageFeature(name: String)
val enabledLanguageFeatures: Set<String> val enabledLanguageFeatures: Set<String>
fun useExperimentalAnnotation(name: String)
val experimentalAnnotationsInUse: Set<String>
} }
@@ -311,18 +311,29 @@ class NewMultiplatformIT : BaseGradleIT() {
gradleBuildScript().appendText( gradleBuildScript().appendText(
"\n" + """ "\n" + """
kotlin.sourceSets.jvm6Main.languageSettings { kotlin.sourceSets.all {
languageVersion = '1.3' it.languageSettings {
apiVersion = '1.3' languageVersion = '1.3'
enableLanguageFeature('InlineClasses') apiVersion = '1.3'
progressiveMode = true enableLanguageFeature('InlineClasses')
useExperimentalAnnotation('kotlin.ExperimentalUnsignedTypes')
useExperimentalAnnotation('kotlin.contracts.ExperimentalContracts')
progressiveMode = true
}
} }
""".trimIndent() """.trimIndent()
) )
build("compileKotlinJvm6") { listOf("compileKotlinJvm6", "compileKotlinNodeJs", "compileKotlin${nativeHostTargetName.capitalize()}").forEach {
assertSuccessful() build(it) {
assertContains("-language-version 1.3", "-api-version 1.3", "-XXLanguage:+InlineClasses", " -progressive") assertSuccessful()
assertTasksExecuted(":$it")
assertContains(
"-language-version 1.3", "-api-version 1.3", "-XXLanguage:+InlineClasses",
" -progressive", "-Xuse-experimental=kotlin.ExperimentalUnsignedTypes",
"-Xuse-experimental=kotlin.contracts.ExperimentalContracts"
)
}
} }
} }
@@ -351,8 +362,20 @@ class NewMultiplatformIT : BaseGradleIT() {
} }
} }
testMonotonousCheck("languageSettings.languageVersion = '1.4'", SourceSetConsistencyChecks.languageVersionCheckHint) testMonotonousCheck(
testMonotonousCheck("languageSettings.enableLanguageFeature('InlineClasses')", SourceSetConsistencyChecks.unstableFeaturesHint) "languageSettings.languageVersion = '1.4'",
SourceSetConsistencyChecks.languageVersionCheckHint
)
testMonotonousCheck(
"languageSettings.enableLanguageFeature('InlineClasses')",
SourceSetConsistencyChecks.unstableFeaturesHint
)
testMonotonousCheck(
"languageSettings.useExperimentalAnnotation('kotlin.ExperimentalUnsignedTypes')",
SourceSetConsistencyChecks.experimentalAnnotationsInUseHint
)
// check that enabling a bugfix feature and progressive mode or advancing API level // check that enabling a bugfix feature and progressive mode or advancing API level
// don't require doing the same for dependent source sets: // don't require doing the same for dependent source sets:
@@ -951,4 +974,4 @@ class NewMultiplatformIT : BaseGradleIT() {
assertFileExists("foo/2.txt") assertFileExists("foo/2.txt")
} }
} }
} }
@@ -38,13 +38,20 @@ kotlin {
} }
sourceSets { sourceSets {
commonMain {
dependencies {
api 'org.jetbrains.kotlin:kotlin-stdlib-common'
}
}
jvm6Main { jvm6Main {
dependencies { dependencies {
api 'org.jetbrains.kotlin:kotlin-stdlib'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.4' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.4'
} }
} }
nodeJsMain { nodeJsMain {
dependencies { dependencies {
api 'org.jetbrains.kotlin:kotlin-stdlib-js'
implementation 'org.jetbrains.kotlinx:kotlinx-html-js:0.6.11' implementation 'org.jetbrains.kotlinx:kotlinx-html-js:0.6.11'
} }
} }
@@ -50,6 +50,14 @@ internal class DefaultLanguageSettingsBuilder : LanguageSettingsBuilder {
enabledLanguageFeaturesImpl += languageFeature enabledLanguageFeaturesImpl += languageFeature
} }
private val experimentalAnnotationsInUseImpl = mutableSetOf<String>()
override val experimentalAnnotationsInUse: Set<String> = experimentalAnnotationsInUseImpl
override fun useExperimentalAnnotation(name: String) {
experimentalAnnotationsInUseImpl += name
}
companion object { companion object {
} }
} }
@@ -68,6 +76,10 @@ internal fun applyLanguageSettingsToKotlinTask(
languageSettingsBuilder.enabledLanguageFeatures.forEach { featureName -> languageSettingsBuilder.enabledLanguageFeatures.forEach { featureName ->
freeCompilerArgs += "-XXLanguage:+$featureName" freeCompilerArgs += "-XXLanguage:+$featureName"
} }
languageSettingsBuilder.experimentalAnnotationsInUse.forEach { annotationName ->
freeCompilerArgs += "-Xuse-experimental=$annotationName"
}
} }
private val apiVersionValues = ApiVersion.run { listOf(KOTLIN_1_0, KOTLIN_1_1, KOTLIN_1_2, KOTLIN_1_3) } private val apiVersionValues = ApiVersion.run { listOf(KOTLIN_1_0, KOTLIN_1_1, KOTLIN_1_2, KOTLIN_1_3) }
@@ -44,6 +44,15 @@ object SourceSetConsistencyChecks {
leftExtendsRightConsistently = { left, right -> left.containsAll(right) }, leftExtendsRightConsistently = { left, right -> left.containsAll(right) },
consistencyConditionHint = unstableFeaturesHint consistencyConditionHint = unstableFeaturesHint
) )
const val experimentalAnnotationsInUseHint = "The dependent source set must use all experimental annotations that its dependency uses."
internal val experimentalAnnotationsCheck = ConsistencyCheck<KotlinSourceSet, Set<String>>(
name = "set of experimental annotations in use",
getValue = { sourceSet -> sourceSet.languageSettings.experimentalAnnotationsInUse },
leftExtendsRightConsistently = { left, right -> left.containsAll(right) },
consistencyConditionHint = experimentalAnnotationsInUseHint
)
} }
internal class SourceSetConsistencyChecker( internal class SourceSetConsistencyChecker(
@@ -76,5 +85,5 @@ internal class SourceSetConsistencyChecker(
internal val defaultSourceSetLanguageSettingsChecker = with(SourceSetConsistencyChecks) { internal val defaultSourceSetLanguageSettingsChecker = with(SourceSetConsistencyChecks) {
// We don't check the progressive mode, since the features it enables are bugfixes // We don't check the progressive mode, since the features it enables are bugfixes
SourceSetConsistencyChecker(listOf(languageVersionCheck, unstableFeaturesCheck)) SourceSetConsistencyChecker(listOf(languageVersionCheck, experimentalAnnotationsCheck, unstableFeaturesCheck))
} }
@@ -5,7 +5,6 @@ import org.gradle.api.DefaultTask
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.file.FileCollection import org.gradle.api.file.FileCollection
import org.gradle.api.file.FileTree import org.gradle.api.file.FileTree
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider import org.gradle.api.provider.Provider
import org.gradle.api.tasks.* import org.gradle.api.tasks.*
import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.api.tasks.compile.AbstractCompile
@@ -21,10 +20,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.defaultSourceSetName import org.jetbrains.kotlin.gradle.plugin.mpp.defaultSourceSetName
import org.jetbrains.kotlin.gradle.plugin.mpp.isMainCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.isMainCompilation
import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.target.CompilerOutputKind.DYNAMIC import org.jetbrains.kotlin.konan.target.CompilerOutputKind.*
import org.jetbrains.kotlin.konan.target.CompilerOutputKind.FRAMEWORK
import org.jetbrains.kotlin.konan.target.CompilerOutputKind.PROGRAM
import org.jetbrains.kotlin.konan.target.CompilerOutputKind.STATIC
import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget
import java.io.File import java.io.File
@@ -154,6 +150,9 @@ open class KotlinNativeCompile : AbstractCompile() {
val enabledLanguageFeatures: Set<String> val enabledLanguageFeatures: Set<String>
@Input get() = languageSettings?.enabledLanguageFeatures ?: emptySet() @Input get() = languageSettings?.enabledLanguageFeatures ?: emptySet()
val experimentalAnnotationsInUse: Set<String>
@Input get() = languageSettings?.experimentalAnnotationsInUse.orEmpty()
// endregion. // endregion.
// region DSL for compiler options // region DSL for compiler options
@@ -227,6 +226,9 @@ open class KotlinNativeCompile : AbstractCompile() {
enabledLanguageFeatures.forEach { featureName -> enabledLanguageFeatures.forEach { featureName ->
add("-XXLanguage:+$featureName") add("-XXLanguage:+$featureName")
} }
experimentalAnnotationsInUse.forEach { annotationName ->
add("-Xuse-experimental=$annotationName")
}
// Compiler plugins. // Compiler plugins.
compilerPluginClasspath?.let { pluginClasspath -> compilerPluginClasspath?.let { pluginClasspath ->