Fix internals of an android-library not accessible in its androidTest

Issue #KT-19370 Fixed
This commit is contained in:
Sergey Igushkin
2017-08-04 17:22:22 +03:00
parent ae3497c6ce
commit 52f923c5ff
4 changed files with 47 additions and 1 deletions
@@ -0,0 +1,5 @@
import lib.internalLibFun
fun main(args: Array<String>) {
internalLibFun()
}
@@ -1,3 +1,5 @@
package lib
fun libUtil(): String = "libUtil"
fun libUtil(): String = "libUtil"
internal fun internalLibFun() = "internalLibFun"
@@ -4,6 +4,7 @@ import com.android.build.gradle.BaseExtension
import com.android.build.gradle.BasePlugin
import com.android.build.gradle.internal.variant.BaseVariantData
import com.android.build.gradle.internal.variant.BaseVariantOutputData
import com.android.build.gradle.internal.variant.LibraryVariantData
import com.android.build.gradle.internal.variant.TestVariantData
import com.android.builder.model.SourceProvider
import org.gradle.api.Project
@@ -14,6 +15,7 @@ import org.jetbrains.kotlin.gradle.internal.KaptVariantData
import org.jetbrains.kotlin.gradle.internal.registerGeneratedJavaSource
import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.utils.checkedReflection
import org.jetbrains.kotlin.incremental.configureMultiProjectIncrementalCompilation
import org.jetbrains.kotlin.incremental.multiproject.ArtifactDifferenceRegistryProviderAndroidWrapper
import java.io.File
@@ -57,8 +59,29 @@ internal class LegacyAndroidAndroidProjectHandler(kotlinConfigurationTools: Kotl
configureJavaTask(kotlinTask, javaTask, logger)
createSyncOutputTask(project, kotlinTask, javaTask, kotlinAfterJavaTask, getVariantName(variantData))
// In lib modules, the androidTest variants get the classes jar in their classpath instead of the Java
// destination dir. To use it as a friend path, set the jar as the javaOutputDir (see its usages):
if (variantData is LibraryVariantData) {
variantData.dependencyJarOrNull?.let { kotlinTask.javaOutputDir = it }
}
}
private val LibraryVariantData.dependencyJarOrNull: File?
get() =
checkedReflection(f@{
val output = variantConfiguration.javaClass.methods.firstOrNull { it.name == "getOutput" }
?.invoke(variantConfiguration)
?: return@f null
output.javaClass.methods?.firstOrNull { it.name == "getJarFile" }
?.invoke(output) as? File
}, { e: Exception ->
logger.kotlinDebug("dependencyJarOrNull for lib variant $name failed due to $e")
null
})
override fun getVariantName(variant: BaseVariantData<out BaseVariantOutputData>): String = variant.name
override fun checkVariantIsValid(variant: BaseVariantData<out BaseVariantOutputData>): Unit {
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.gradle.utils
import java.lang.reflect.Field
import java.lang.reflect.InvocationTargetException
internal fun Class<*>.getDeclaredFieldInHierarchy(name: String): Field? {
val inheritanceChain = generateSequence(this) { it.superclass }
@@ -28,3 +29,18 @@ internal fun Class<*>.getDeclaredFieldInHierarchy(name: String): Field? {
}
}.filterNotNull().first()
}
internal inline fun <T> checkedReflection(block: () -> T, onReflectionException: (Exception) -> T): T {
return try {
block()
}
catch (e: InvocationTargetException) {
throw e.targetException
}
catch (e: ReflectiveOperationException) {
onReflectionException(e)
}
catch (e: IllegalArgumentException) {
onReflectionException(e)
}
}