diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt index e89944f64f4..a38ad7b2e0f 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt @@ -21,6 +21,8 @@ class KotlinAndroid32GradleIT : KotlinAndroid3GradleIT(androidGradlePluginVersio build("assemble", "compileDebugUnitTestJavaWithJavac", "printCompilerPluginOptions") { assertSuccessful() + assertContains("KT-29964 OK") // Output from lib/build.gradle + assertTasksExecuted( ":lib:compileDebugKotlinAndroidLib", ":lib:compileReleaseKotlinAndroidLib", diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-android/lib/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-android/lib/build.gradle index 70703d9f6f8..64d315c00a4 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-android/lib/build.gradle +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-android/lib/build.gradle @@ -36,6 +36,21 @@ dependencies { androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' } +kotlin.targets.all { + compilations.all { + // KT-29964: check that Android compilations can be configured with an `all { ... }` handler: + kotlinOptions { + verbose = true + } + compileKotlinTask.doFirst { + if (!compileKotlinTask.kotlinOptions.verbose) { + throw new AssertionError("kotlinOptions were not configured properly") + } + println "KT-29964 OK" + } + } +} + kotlin { sourceSets { jvmLibMain { 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 930d03d64b1..0f494fd5f09 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 @@ -727,44 +727,48 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationT kotlinOptions.noJdk = true ext.addExtension(KOTLIN_OPTIONS_DSL_NAME, kotlinOptions) - project.afterEvaluate { project -> - forEachVariant(project) { variant -> - val variantName = getVariantName(variant) - val compilation = kotlinAndroidTarget.compilations.create(variantName) - setUpDependencyResolution(variant, compilation) - } + val androidPluginIds = listOf( + "android", "com.android.application", "android-library", "com.android.library", + "com.android.test", "com.android.feature", "com.android.dynamic-feature", "com.android.instantapp" + ) - val androidPluginIds = listOf( - "android", "com.android.application", "android-library", "com.android.library", - "com.android.test", "com.android.feature", "com.android.dynamic-feature", "com.android.instantapp" - ) - val plugin = androidPluginIds.asSequence() + val plugin by lazy { + androidPluginIds.asSequence() .mapNotNull { project.plugins.findPlugin(it) as? BasePlugin } .firstOrNull() ?: throw InvalidPluginException("'kotlin-android' expects one of the Android Gradle " + "plugins to be applied to the project:\n\t" + androidPluginIds.joinToString("\n\t") { "* $it" }) + } - checkAndroidAnnotationProcessorDependencyUsage(project) + forEachVariant(project) { variant -> + val variantName = getVariantName(variant) - forEachVariant(project) { - processVariant( - it, kotlinAndroidTarget, project, ext, plugin, kotlinOptions, kotlinConfigurationTools.kotlinTasksProvider - ) + // Create the compilation and configure it first, then add to the compilations container. As this code is executed + // in afterEvaluate, a user's build script might have already attached item handlers to the compilations container, and those + // handlers might break when fired on a compilation that is not yet properly configured (e.g. KT-29964): + kotlinAndroidTarget.compilationFactory.create(variantName).let { compilation -> + setUpDependencyResolution(variant, compilation) + + processVariant(variant, compilation, project, ext, plugin, kotlinOptions, kotlinConfigurationTools.kotlinTasksProvider) + + @Suppress("UNCHECKED_CAST") + (kotlinAndroidTarget.compilations as NamedDomainObjectCollection).add(compilation) } val subpluginEnvironment = SubpluginEnvironment.loadSubplugins(project, kotlinConfigurationTools.kotlinPluginVersion) + val compilation = kotlinAndroidTarget.compilations.getByName(getVariantName(variant)) + applySubplugins(project, compilation, variant, subpluginEnvironment) + } - forEachVariant(project) { variant -> - val compilation = kotlinAndroidTarget.compilations.getByName(getVariantName(variant)) - applySubplugins(project, compilation, variant, subpluginEnvironment) - } + project.whenEvaluated { + checkAndroidAnnotationProcessorDependencyUsage(project) } } private fun processVariant( variantData: V, - target: KotlinAndroidTarget, + compilation: KotlinJvmAndroidCompilation, project: Project, androidExt: BaseExtension, androidPlugin: BasePlugin, @@ -782,7 +786,6 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationT return } - val compilation = target.compilations.getByName(variantDataName) val defaultSourceSet = project.kotlinExtension.sourceSets.maybeCreate(compilation.defaultSourceSetName) val kotlinTaskName = compilation.compileKotlinTaskName diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTarget.kt index a8f8d7b8706..830de45e83e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTarget.kt @@ -26,7 +26,7 @@ open class KotlinAndroidTarget( override val platformType: KotlinPlatformType get() = KotlinPlatformType.androidJvm - private val compilationFactory = KotlinJvmAndroidCompilationFactory(project, this) + internal val compilationFactory = KotlinJvmAndroidCompilationFactory(project, this) override val compilations: NamedDomainObjectContainer = project.container(compilationFactory.itemClass, compilationFactory)