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 df91fda1fd6..1e2bad0fc27 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 @@ -3,8 +3,11 @@ package org.jetbrains.kotlin.gradle.plugin import com.android.build.gradle.BaseExtension import com.android.build.gradle.BasePlugin import com.android.build.gradle.api.AndroidSourceSet +import com.android.build.gradle.internal.TaskContainerAdaptor +import com.android.build.gradle.internal.TaskManager import com.android.build.gradle.internal.variant.BaseVariantData import com.android.build.gradle.internal.variant.BaseVariantOutputData +import com.android.build.gradle.internal.variant.TestVariantData import com.android.builder.model.SourceProvider import groovy.lang.Closure import org.gradle.api.InvalidUserDataException @@ -31,6 +34,7 @@ import org.jetbrains.kotlin.gradle.internal.initKapt import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper import org.jetbrains.kotlin.gradle.plugin.android.KotlinJillTask import org.jetbrains.kotlin.gradle.tasks.* +import org.jetbrains.kotlin.gradle.utils.getDeclaredFieldInHierarchy import org.jetbrains.kotlin.incremental.configureMultiProjectIncrementalCompilation import org.jetbrains.kotlin.incremental.multiproject.ArtifactDifferenceRegistryProviderAndroidWrapper import java.io.File @@ -369,6 +373,22 @@ internal open class KotlinAndroidPlugin( } } + private fun forceCreateJavacTask(project: Project, + androidPlugin: BasePlugin, + variantData: BaseVariantData<*>): JavaCompile? { + val taskManager = androidPlugin::class.java.getDeclaredFieldInHierarchy("taskManager") + ?.let { it.isAccessible = true; it[androidPlugin] as TaskManager } + if (taskManager == null) { + log.kotlinDebug("TaskManager was not found, possibly, an incompatible Android Gradle plugin version is used.") + return null + } + val taskContainerAdaptor = TaskContainerAdaptor(project.tasks) + return taskManager.createJavacTask(taskContainerAdaptor, variantData.scope)?.get(taskContainerAdaptor) + } + + private fun getTestedVariantData(variantData: BaseVariantData<*>): BaseVariantData<*>? = + ((variantData as? TestVariantData)?.testedVariantData as? BaseVariantData<*>) + private fun processVariantData( variantDataList: List>, project: Project, @@ -384,7 +404,12 @@ internal open class KotlinAndroidPlugin( val variantDataName = variantData.name logger.kotlinDebug("Process variant [$variantDataName]") - val javaTask = AndroidGradleWrapper.getJavaTask(variantData) + val testedVariantData = getTestedVariantData(variantData) + val isAndroidTestVariant = variantDataName.endsWith("androidTest", ignoreCase = true) && + testedVariantData != null + + val javaTask = AndroidGradleWrapper.getJavaTask(variantData) ?: + (if (isAndroidTestVariant) forceCreateJavacTask(project, androidPlugin, variantData) else null) if (javaTask == null) { logger.info("KOTLIN: javaTask is missing for $variantDataName, so Kotlin files won't be compiled for it") @@ -446,6 +471,10 @@ internal open class KotlinAndroidPlugin( } configureSources(kotlinTask, variantData) + if (isAndroidTestVariant) { + configureSources(kotlinTask, testedVariantData!!) + } + if (kotlinAfterJavaTask != null) { configureSources(kotlinAfterJavaTask, variantData) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/reflectionUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/reflectionUtils.kt new file mode 100644 index 00000000000..8fd08834a19 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/reflectionUtils.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2010-2016 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. + */ + +package org.jetbrains.kotlin.gradle.utils + +import java.lang.reflect.Field + +internal fun Class<*>.getDeclaredFieldInHierarchy(name: String): Field? { + val inheritanceChain = generateSequence(this) { it.superclass } + return inheritanceChain.map { + try { + it.getDeclaredField(name) + } catch (_: NoSuchFieldException) { + null + } + }.filterNotNull().first() +}