(partial implementation)
diff --git a/libraries/tools/kotlin-gradle-plugin-api/build.gradle b/libraries/tools/kotlin-gradle-plugin-api/build.gradle
index e30d085..0f4077e 100644
--- a/libraries/tools/kotlin-gradle-plugin-api/build.gradle
+++ b/libraries/tools/kotlin-gradle-plugin-api/build.gradle
@@ -15,7 +15,10 @@
dependencies {
compile project(':kotlin-stdlib')
-
+
+ // Granular compile dependency; At runtime, it is covered by the compiler distribution the kotlin-gradle-plugin depends on.
+ compileOnly(project(':compiler:util')) { transitive = false }
+
compileOnly gradleApi()
compileOnly 'com.android.tools.build:gradle:0.4.2'
}
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 0000000..290cc2b
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/LanguageSettingsBuilder.kt
@@ -0,0 +1,16 @@
+/*
+ * 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)
+}
\ 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 c496581..b16e61b 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,12 +9,15 @@
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
val resources: SourceDirectorySet
+ val languageSettings: LanguageSettingsBuilder
fun kotlin(configureClosure: Closure<Any?>): SourceDirectorySet
+ fun languageSettings(configureClosure: Closure<Any?>): LanguageSettingsBuilder
companion object {
const val COMMON_MAIN_SOURCE_SET_NAME = "commonMain"
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 107c395..b85736c 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.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 @@
filter.include("**/*.java", "**/*.kt", "**/*.kts")
}
+ override val languageSettings: LanguageSettingsBuilder = DefaultLanguageSettingsBuilder()
+
override val resources: SourceDirectorySet = createDefaultSourceDirectorySet(displayName + " resources", fileResolver)
override fun kotlin(configureClosure: Closure<Any?>): SourceDirectorySet = kotlin.apply { ConfigureUtil.configure(configureClosure, this) }
+ override fun languageSettings(configureClosure: Closure<Any?>): LanguageSettingsBuilder = languageSettings.apply {
+ ConfigureUtil.configure(configureClosure, this)
+ }
+
override fun getName(): String = displayName
override fun dependencies(configure: KotlinDependencyHandler.() -> Unit): Unit =
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 0000000..9219b15
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultLanguageSettingsBuilder.kt
@@ -0,0 +1,57 @@
+/*
+ * 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 enabledLanguageFeatures = mutableSetOf<LanguageFeature>()
+
+ override fun enableLanguageFeature(name: String) {
+ val languageFeature = LanguageFeature.values().find { it.name == name } ?: throw InvalidUserDataException(
+ "Unknown language feature '${name}'"
+ )
+ enabledLanguageFeatures += languageFeature
+ }
+
+ companion object {
+ }
+}
+
+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 }
\ 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 0000000..3b220ea
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/SourceSetConsistencyChecker.kt
@@ -0,0 +1,64 @@
+/*
+ * 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.LanguageVersion
+import org.jetbrains.kotlin.gradle.plugin.source.KotlinSourceSet
+
+internal class ConsistencyCheck<T, S>(
+ val name: String,
+ val getValue: (T) -> S,
+ val leftExtendsRightConsistently: (S, S) -> Boolean,
+ val consistencyConditionHint: String
+)
+
+private val languageVersionCheck = ConsistencyCheck<KotlinSourceSet, LanguageVersion>(
+ name = "language version",
+ getValue = { sourceSet ->
+ sourceSet.languageSettings.languageVersion?.let { parseLanguageVersionSetting(it) } ?: LanguageVersion.LATEST_STABLE
+ },
+ leftExtendsRightConsistently = { left, right -> left >= right },
+ consistencyConditionHint = "The language version of the dependent source set must be greater than or equal to that of its dependency."
+)
+
+private val apiVersionCheck = ConsistencyCheck<KotlinSourceSet, ApiVersion>(
+ name = "language version",
+ getValue = { sourceSet ->
+ sourceSet.languageSettings.apiVersion?.let { parseApiVersionSettings(it) } ?: ApiVersion.LATEST_STABLE
+ },
+ leftExtendsRightConsistently = { left, right -> left >= right },
+ consistencyConditionHint = "The language version of the dependent source set must be greater than or equal to that of its dependency."
+)
+
+internal class SourceSetConsistencyChecker(
+ val checks: Set<ConsistencyCheck<KotlinSourceSet, *>>
+) {
+ fun <S> runSingleCheck(
+ left: KotlinSourceSet,
+ right: KotlinSourceSet,
+ check: ConsistencyCheck<KotlinSourceSet, S>
+ ) {
+ val leftValue = check.getValue(left)
+ val rightValue = check.getValue(right)
+
+ if (!check.leftExtendsRightConsistently(leftValue, rightValue)) {
+ throw InvalidUserDataException(
+ "Inconsistent language settings for Kotlin source sets: '${left.name}' depends on '${right.name}'\n" +
+ "'${left.name}': ${check.name} is ${leftValue}\n" +
+ "'${right.name}': ${check.name} is ${rightValue}\n" +
+ check.consistencyConditionHint
+ )
+ }
+ }
+
+ fun runAllChecks(left: KotlinSourceSet, right: KotlinSourceSet) {
+ for (check in checks) {
+ runSingleCheck(left, right, check)
+ }
+ }
+}
\ No newline at end of file