diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt index cd73510ba93..75227aebd3f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2020 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.dsl @@ -57,6 +46,12 @@ open class KotlinProjectExtension : KotlinSourceSetContainer { val experimental: ExperimentalExtension get() = DslObject(this).extensions.getByType(ExperimentalExtension::class.java) + var explicitApi: ExplicitApiMode? = null + + fun explicitApi() { + explicitApi = ExplicitApiMode.Strict + } + override var sourceSets: NamedDomainObjectContainer @Suppress("UNCHECKED_CAST") get() = DslObject(this).extensions.getByName("sourceSets") as NamedDomainObjectContainer @@ -228,4 +223,12 @@ enum class NativeCacheKind(val produce: String?, val outputKind: CompilerOutputK fun byCompilerArgument(argument: String): NativeCacheKind? = NativeCacheKind.values().firstOrNull { it.name.equals(argument, ignoreCase = true) } } +} + +enum class ExplicitApiMode(private val cliOption: String) { + Strict("strict"), + Warning("warning"), + Disabled("disabled"); + + fun toCompilerArg() = "-Xexplicit-api=$cliOption" } \ 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 39224f612ea..e30e4b94dc8 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 @@ -1,3 +1,8 @@ +/* + * Copyright 2010-2020 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 import com.android.build.gradle.* @@ -498,6 +503,7 @@ internal abstract class AbstractKotlinPlugin( fun configureProjectGlobalSettings(project: Project, kotlinPluginVersion: String) { configureDefaultVersionsResolutionStrategy(project, kotlinPluginVersion) configureClassInspectionForIC(project) + project.setupGeneralKotlinExtensionParameters() } fun configureTarget( diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt index 93c08b87673..42c12941839 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 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. */ @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.gradle.dsl.configureOrCreate import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin.Companion.sourceSetFreeCompilerArgsPropertyName import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope import org.jetbrains.kotlin.gradle.plugin.sources.checkSourceSetVisibilityRequirements @@ -97,6 +98,7 @@ class KotlinMultiplatformPlugin( // propagate compiler plugin options to the source set language settings setupAdditionalCompilerArguments(project) + project.setupGeneralKotlinExtensionParameters() project.pluginManager.apply(ScriptingGradleSubplugin::class.java) } @@ -134,22 +136,6 @@ class KotlinMultiplatformPlugin( val associatedCompilation = primaryCompilationsBySourceSet[sourceSet] ?: metadataCompilation project.tasks.getByName(associatedCompilation.compileKotlinTaskName) as AbstractCompile } - - // Also set ad-hoc free compiler args from the internal project property - freeCompilerArgsProvider = project.provider { - val propertyValue = with(project.extensions.extraProperties) { - val sourceSetFreeCompilerArgsPropertyName = sourceSetFreeCompilerArgsPropertyName(sourceSet.name) - if (has(sourceSetFreeCompilerArgsPropertyName)) { - get(sourceSetFreeCompilerArgsPropertyName) - } else null - } - mutableListOf().apply { - when (propertyValue) { - is String -> add(propertyValue) - is Iterable<*> -> addAll(propertyValue.map { it.toString() }) - } - } - } } } } @@ -314,7 +300,7 @@ class KotlinMultiplatformPlugin( companion object { const val METADATA_TARGET_NAME = "metadata" - private fun sourceSetFreeCompilerArgsPropertyName(sourceSetName: String) = + internal fun sourceSetFreeCompilerArgsPropertyName(sourceSetName: String) = "kotlin.mpp.freeCompilerArgsForSourceSet.$sourceSetName" internal const val GRADLE_NO_METADATA_WARNING = "This build consumes Gradle module metadata but does not produce " + @@ -403,4 +389,44 @@ internal fun sourcesJarTask( } return result -} \ No newline at end of file +} + +internal fun Project.setupGeneralKotlinExtensionParameters() { + val sourceSetsInMainCompilation by lazy { + CompilationSourceSetUtil.compilationsBySourceSets(project).filterValues { compilations -> + compilations.any { + // kotlin main compilation + it.name == KotlinCompilation.MAIN_COMPILATION_NAME + // android compilation which is NOT in tested variant + || (it as? KotlinJvmAndroidCompilation)?.let { getTestedVariantData(it.androidVariant) == null } == true + } + }.keys + } + + kotlinExtension.sourceSets.all { sourceSet -> + (sourceSet.languageSettings as? DefaultLanguageSettingsBuilder)?.run { + + // Set ad-hoc free compiler args from the internal project property + freeCompilerArgsProvider = project.provider { + val propertyValue = with(project.extensions.extraProperties) { + val sourceSetFreeCompilerArgsPropertyName = sourceSetFreeCompilerArgsPropertyName(sourceSet.name) + if (has(sourceSetFreeCompilerArgsPropertyName)) { + get(sourceSetFreeCompilerArgsPropertyName) + } else null + } + + mutableListOf().apply { + when (propertyValue) { + is String -> add(propertyValue) + is Iterable<*> -> addAll(propertyValue.map { it.toString() }) + } + + val explicitApiState = project.kotlinExtension.explicitApi?.toCompilerArg() + // do not look into lazy set if explicitApiMode was not enabled + if (explicitApiState != null && sourceSet in sourceSetsInMainCompilation) + add(explicitApiState) + } + } + } + } +}