Android Extensions: Support Android variants and library dependencies (KT-14086, KT-16934)
This commit is contained in:
committed by
Yan Zhulanow
parent
8e9a62d553
commit
f4acf404ca
+1
@@ -33,6 +33,7 @@ class ExampleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
|
||||
kotlinCompile: AbstractCompile,
|
||||
javaCompile: AbstractCompile,
|
||||
variantData: Any?,
|
||||
androidProjectHandler: Any?,
|
||||
javaSourceSet: SourceSet?
|
||||
): List<SubpluginOption> {
|
||||
println("ExampleSubplugin loaded")
|
||||
|
||||
+1
@@ -79,6 +79,7 @@ class AllOpenKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
|
||||
kotlinCompile: AbstractCompile,
|
||||
javaCompile: AbstractCompile,
|
||||
variantData: Any?,
|
||||
androidProjectHandler: Any?,
|
||||
javaSourceSet: SourceSet?
|
||||
): List<SubpluginOption> {
|
||||
if (!AllOpenGradleSubplugin.isEnabled(project)) return emptyList()
|
||||
|
||||
+2
-1
@@ -22,7 +22,7 @@ import org.gradle.api.tasks.compile.AbstractCompile
|
||||
|
||||
class SubpluginOption(val key: String, val value: String)
|
||||
|
||||
interface KotlinGradleSubplugin<KotlinCompile : AbstractCompile> {
|
||||
interface KotlinGradleSubplugin<in KotlinCompile : AbstractCompile> {
|
||||
fun isApplicable(project: Project, task: KotlinCompile): Boolean
|
||||
|
||||
fun apply(
|
||||
@@ -30,6 +30,7 @@ interface KotlinGradleSubplugin<KotlinCompile : AbstractCompile> {
|
||||
kotlinCompile: KotlinCompile,
|
||||
javaCompile: AbstractCompile,
|
||||
variantData: Any?,
|
||||
androidProjectHandler: Any?,
|
||||
javaSourceSet: SourceSet?
|
||||
): List<SubpluginOption>
|
||||
|
||||
|
||||
+10
@@ -210,6 +210,16 @@ fun getSomething() = 10
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAndroidExtensionsManyVariants() {
|
||||
val project = Project("AndroidExtensionsManyVariants", gradleVersion)
|
||||
val options = defaultBuildOptions().copy(incremental = false)
|
||||
|
||||
project.build("assemble", options = options) {
|
||||
assertSuccessful()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAndroidKaptChangingDependencies() {
|
||||
val project = Project("AndroidKaptChangingDependencies", gradleVersion)
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion "25.0.2"
|
||||
defaultConfig {
|
||||
applicationId "org.example.manyvariants"
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 23
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
}
|
||||
}
|
||||
|
||||
flavorDimensions "color"
|
||||
|
||||
productFlavors {
|
||||
demo {
|
||||
dimension "color"
|
||||
applicationIdSuffix ".demo"
|
||||
versionNameSuffix "-demo"
|
||||
}
|
||||
full {
|
||||
dimension "color"
|
||||
applicationIdSuffix ".full"
|
||||
versionNameSuffix "-full"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package org.example.manyvariants
|
||||
|
||||
import android.app.Activity
|
||||
import kotlinx.android.synthetic.debug.activity_debug.*
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
|
||||
fun Activity.debug() {
|
||||
viewMain
|
||||
viewDebug
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/viewDebug"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</RelativeLayout>
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package org.example.manyvariants
|
||||
|
||||
import android.app.Activity
|
||||
import kotlinx.android.synthetic.demo.activity_demo.*
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
|
||||
fun Activity.demo() {
|
||||
viewMain
|
||||
viewDemo
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/viewDemo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</RelativeLayout>
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package org.example.manyvariants
|
||||
|
||||
import android.app.Activity
|
||||
import kotlinx.android.synthetic.debug.activity_debug.*
|
||||
import kotlinx.android.synthetic.demo.activity_demo.*
|
||||
import kotlinx.android.synthetic.demoDebug.activity_demo_debug.*
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
|
||||
fun Activity.demoDebug() {
|
||||
viewMain
|
||||
viewDemo
|
||||
viewDebug
|
||||
viewDemoDebug
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/viewDemoDebug"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</RelativeLayout>
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package org.example.manyvariants
|
||||
|
||||
import android.app.Activity
|
||||
import kotlinx.android.synthetic.full.activity_full.*
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
|
||||
fun Activity.full() {
|
||||
viewMain
|
||||
viewFull
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/viewFull"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</RelativeLayout>
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package org.example.manyvariants
|
||||
|
||||
import android.app.Activity
|
||||
import kotlinx.android.synthetic.full.activity_full.*
|
||||
import kotlinx.android.synthetic.fullRelease.activity_full_release.*
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import kotlinx.android.synthetic.release.activity_release.*
|
||||
|
||||
fun Activity.fullRelease() {
|
||||
viewMain
|
||||
viewFull
|
||||
viewRelease
|
||||
viewFullRelease
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/viewFullRelease"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</RelativeLayout>
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.example.manyvariants">
|
||||
|
||||
<application android:allowBackup="true" android:supportsRtl="true">
|
||||
<activity android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package org.example.manyvariants
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
|
||||
class MainActivity : Activity() {
|
||||
override fun onCreate(savedInstanceState: Bundle) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
viewMain
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/viewMain"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</RelativeLayout>
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package org.example.manyvariants
|
||||
|
||||
import android.app.Activity
|
||||
import kotlinx.android.synthetic.release.activity_release.*
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
|
||||
fun Activity.release() {
|
||||
viewMain
|
||||
viewRelease
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/viewRelease"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</RelativeLayout>
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven { url 'https://maven.google.com' }
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath "com.android.tools.build:gradle:$android_tools_version"
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven { url 'https://maven.google.com' }
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.gradle.jvmargs=-ea -XX:MaxPermSize=512m
|
||||
+1
@@ -0,0 +1 @@
|
||||
include ':app'
|
||||
+22
@@ -2,7 +2,9 @@ package org.jetbrains.kotlin.gradle.plugin
|
||||
|
||||
import com.android.build.gradle.*
|
||||
import com.android.build.gradle.api.*
|
||||
import com.android.build.gradle.tasks.MergeResources
|
||||
import com.android.builder.model.SourceProvider
|
||||
import com.android.ide.common.res2.ResourceSet
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.tasks.compile.AbstractCompile
|
||||
@@ -117,6 +119,10 @@ class Android25ProjectHandler(kotlinConfigurationTools: KotlinConfigurationTools
|
||||
// to some degree -- the dependent projects will rebuild non-incrementally when a library project changes
|
||||
}
|
||||
|
||||
override fun getResDirectories(variantData: BaseVariant): List<File> {
|
||||
return variantData.mergeResources?.computeResourceSetList0()?.flatMap { it.sourceFiles } ?: emptyList()
|
||||
}
|
||||
|
||||
private inner class KaptVariant(variantData: BaseVariant) : KaptVariantData<BaseVariant>(variantData) {
|
||||
override val name: String = getVariantName(variantData)
|
||||
override val sourceProviders: Iterable<SourceProvider> = getSourceProviders(variantData)
|
||||
@@ -137,6 +143,22 @@ class Android25ProjectHandler(kotlinConfigurationTools: KotlinConfigurationTools
|
||||
}
|
||||
}
|
||||
|
||||
//TODO once the Android plugin reaches its 3.0.0 release, consider compiling against it (remove the reflective call)
|
||||
//TODO this is a private API for now
|
||||
private fun MergeResources.computeResourceSetList0(): List<ResourceSet>? {
|
||||
val computeResourceSetListMethod = MergeResources::class.java.declaredMethods
|
||||
.firstOrNull { it.name == "computeResourceSetList" && it.parameterCount == 0 } ?: return null
|
||||
|
||||
val oldIsAccessible = computeResourceSetListMethod.isAccessible
|
||||
try {
|
||||
computeResourceSetListMethod.isAccessible = true
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return computeResourceSetListMethod.invoke(this) as? List<ResourceSet>
|
||||
} finally {
|
||||
computeResourceSetListMethod.isAccessible = oldIsAccessible
|
||||
}
|
||||
}
|
||||
|
||||
//TODO once the Android plugin reaches its 3.0.0 release, consider compiling against it (remove the reflective call)
|
||||
private val BaseVariant.dataBindingDependencyArtifactsIfSupported: FileCollection?
|
||||
get() = ReflectionUtil.findMethod(
|
||||
|
||||
+81
-20
@@ -18,6 +18,10 @@ package org.jetbrains.kotlin.gradle.internal
|
||||
|
||||
import com.android.build.gradle.BaseExtension
|
||||
import com.android.build.gradle.api.AndroidSourceSet
|
||||
import com.android.build.gradle.api.BaseVariant
|
||||
import com.android.build.gradle.api.TestVariant
|
||||
import com.android.build.gradle.internal.variant.BaseVariantData
|
||||
import com.android.build.gradle.internal.variant.TestVariantData
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.UnknownDomainObjectException
|
||||
@@ -25,7 +29,6 @@ import org.gradle.api.tasks.SourceSet
|
||||
import org.gradle.api.tasks.compile.AbstractCompile
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin
|
||||
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
|
||||
import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.w3c.dom.Document
|
||||
import java.io.File
|
||||
@@ -54,38 +57,96 @@ class AndroidSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
project: Project,
|
||||
kotlinCompile: KotlinCompile,
|
||||
javaCompile: AbstractCompile,
|
||||
variantData: Any?,
|
||||
variantData: Any?,
|
||||
androidProjectHandler: Any?,
|
||||
javaSourceSet: SourceSet?
|
||||
): List<SubpluginOption> {
|
||||
val androidExtension = project.extensions.getByName("android") as? BaseExtension ?: return emptyList()
|
||||
val sourceSets = androidExtension.sourceSets
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
androidProjectHandler as? AbstractAndroidProjectHandler<Any?> ?: return emptyList()
|
||||
|
||||
val androidExtension = project.extensions.getByName("android") as? BaseExtension ?: return emptyList()
|
||||
val pluginOptions = arrayListOf<SubpluginOption>()
|
||||
|
||||
val mainSourceSet = sourceSets.getByName("main")
|
||||
val manifestFile = mainSourceSet.manifest.srcFile
|
||||
val applicationPackage = getApplicationPackageFromManifest(manifestFile) ?: run {
|
||||
project.logger.warn(
|
||||
"Application package name is not present in the manifest file (${manifestFile.absolutePath})")
|
||||
""
|
||||
}
|
||||
pluginOptions += SubpluginOption("package", applicationPackage)
|
||||
val mainSourceSet = androidExtension.sourceSets.getByName("main")
|
||||
pluginOptions += SubpluginOption("package", getApplicationPackage(project, mainSourceSet))
|
||||
|
||||
fun addVariant(sourceSet: AndroidSourceSet) {
|
||||
pluginOptions += SubpluginOption("variant", sourceSet.name + ';' +
|
||||
sourceSet.res.srcDirs.joinToString(";") { it.absolutePath })
|
||||
fun addVariant(name: String, resDirectories: List<File>) {
|
||||
pluginOptions += SubpluginOption("variant", buildString {
|
||||
append(name)
|
||||
append(';')
|
||||
resDirectories.joinTo(this, separator = ";") { it.canonicalPath }
|
||||
})
|
||||
}
|
||||
|
||||
addVariant(mainSourceSet)
|
||||
fun addSourceSetAsVariant(name: String) {
|
||||
val sourceSet = androidExtension.sourceSets.findByName(name) ?: return
|
||||
val srcDirs = sourceSet.res.srcDirs.toList()
|
||||
if (srcDirs.isNotEmpty()) {
|
||||
addVariant(sourceSet.name, srcDirs)
|
||||
}
|
||||
}
|
||||
|
||||
val flavorSourceSets = AndroidGradleWrapper.getProductFlavorsSourceSets(androidExtension).filterNotNull()
|
||||
for (sourceSet in flavorSourceSets) {
|
||||
addVariant(sourceSet)
|
||||
val resDirectoriesForAllVariants = mutableListOf<List<File>>()
|
||||
|
||||
androidProjectHandler.forEachVariant(project) { variant ->
|
||||
if (androidProjectHandler.getTestedVariantData(variant) != null) return@forEachVariant
|
||||
resDirectoriesForAllVariants += androidProjectHandler.getResDirectories(variant)
|
||||
}
|
||||
|
||||
val commonResDirectories = getCommonResDirectories(resDirectoriesForAllVariants)
|
||||
|
||||
addVariant("main", commonResDirectories.toList())
|
||||
|
||||
getVariantComponentNames(variantData)?.let { (variantName, flavorName, buildTypeName) ->
|
||||
addSourceSetAsVariant(buildTypeName)
|
||||
|
||||
if (flavorName.isNotEmpty()) {
|
||||
addSourceSetAsVariant(flavorName)
|
||||
}
|
||||
|
||||
addSourceSetAsVariant(variantName)
|
||||
}
|
||||
|
||||
return pluginOptions
|
||||
}
|
||||
|
||||
// Android25ProjectHandler.KaptVariant actually contains BaseVariant, not BaseVariantData
|
||||
private fun getVariantComponentNames(flavorData: Any?): VariantComponentNames? = when(flavorData) {
|
||||
is KaptVariantData<*> -> getVariantComponentNames(flavorData.variantData)
|
||||
is TestVariantData -> getVariantComponentNames(flavorData.testedVariantData)
|
||||
is TestVariant -> getVariantComponentNames(flavorData.testedVariant)
|
||||
is BaseVariant -> VariantComponentNames(flavorData.name, flavorData.flavorName, flavorData.buildType.name)
|
||||
is BaseVariantData<*> -> VariantComponentNames(flavorData.name, flavorData.variantConfiguration.flavorName,
|
||||
flavorData.variantConfiguration.buildType.name)
|
||||
else -> null
|
||||
}
|
||||
|
||||
private data class VariantComponentNames(val variantName: String, val flavorName: String, val buildTypeName: String)
|
||||
|
||||
private fun getCommonResDirectories(resDirectories: List<List<File>>): Set<File> {
|
||||
var common = resDirectories.firstOrNull()?.toSet() ?: return emptySet()
|
||||
|
||||
for (resDirs in resDirectories.drop(1)) {
|
||||
common = common.intersect(resDirs)
|
||||
}
|
||||
|
||||
return common
|
||||
}
|
||||
|
||||
private fun getApplicationPackage(project: Project, mainSourceSet: AndroidSourceSet): String {
|
||||
val manifestFile = mainSourceSet.manifest.srcFile
|
||||
val applicationPackage = getApplicationPackageFromManifest(manifestFile)
|
||||
|
||||
if (applicationPackage == null) {
|
||||
project.logger.warn("Application package name is not present in the manifest file " +
|
||||
"(${manifestFile.absolutePath})")
|
||||
|
||||
return ""
|
||||
} else {
|
||||
return applicationPackage
|
||||
}
|
||||
}
|
||||
|
||||
private fun getApplicationPackageFromManifest(manifestFile: File): String? {
|
||||
try {
|
||||
return manifestFile.parseXml().documentElement.getAttribute("package")
|
||||
@@ -101,7 +162,7 @@ class AndroidSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
|
||||
override fun getArtifactName() = "kotlin-android-extensions"
|
||||
|
||||
fun File.parseXml(): Document {
|
||||
private fun File.parseXml(): Document {
|
||||
val factory = DocumentBuilderFactory.newInstance()
|
||||
val builder = factory.newDocumentBuilder()
|
||||
return builder.parse(this)
|
||||
|
||||
+3
-2
@@ -47,7 +47,8 @@ internal fun Project.initKapt(
|
||||
variantName: String,
|
||||
kotlinOptions: KotlinJvmOptionsImpl?,
|
||||
subpluginEnvironment: SubpluginEnvironment,
|
||||
tasksProvider: KotlinTasksProvider
|
||||
tasksProvider: KotlinTasksProvider,
|
||||
androidProjectHandler: AbstractAndroidProjectHandler<*>?
|
||||
): KotlinCompile? {
|
||||
val kaptExtension = extensions.getByType(KaptExtension::class.java)
|
||||
val kotlinAfterJavaTask: KotlinCompile?
|
||||
@@ -72,7 +73,7 @@ internal fun Project.initKapt(
|
||||
|
||||
kotlinAfterJavaTask.source(kaptManager.generatedKotlinSourceDir)
|
||||
kotlinAfterJavaTask.source(kaptManager.aptOutputDir)
|
||||
subpluginEnvironment.addSubpluginOptions(this, kotlinAfterJavaTask, javaTask, null, null)
|
||||
subpluginEnvironment.addSubpluginOptions(this, kotlinAfterJavaTask, javaTask, null, androidProjectHandler, null)
|
||||
|
||||
javaTask.doLast {
|
||||
moveGeneratedJavaFilesToCorrespondingDirectories(kaptManager.aptOutputDir)
|
||||
|
||||
+1
@@ -125,6 +125,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
kotlinCompile: KotlinCompile,
|
||||
javaCompile: AbstractCompile,
|
||||
variantData: Any?,
|
||||
androidProjectHandler: Any?,
|
||||
javaSourceSet: SourceSet?
|
||||
): List<SubpluginOption> {
|
||||
assert((variantData != null) xor (javaSourceSet != null))
|
||||
|
||||
+9
-8
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.com.intellij.util.ReflectionUtil
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
|
||||
import org.jetbrains.kotlin.gradle.internal.*
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin.Companion.getKaptClasssesDir
|
||||
import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.utils.ParsedGradleVersion
|
||||
import org.jetbrains.kotlin.incremental.configureMultiProjectIncrementalCompilation
|
||||
@@ -135,7 +134,7 @@ internal class Kotlin2JvmSourceSetProcessor(
|
||||
|
||||
val subpluginEnvironment = loadSubplugins(project)
|
||||
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
|
||||
project, kotlinTask, javaTask as JavaCompile, null, sourceSet)
|
||||
project, kotlinTask, javaTask as JavaCompile, null, null, sourceSet)
|
||||
|
||||
var kotlinAfterJavaTask: KotlinCompile? = null
|
||||
|
||||
@@ -148,7 +147,7 @@ internal class Kotlin2JvmSourceSetProcessor(
|
||||
aptConfiguration.resolve(), aptOutputDir, aptWorkingDir)
|
||||
|
||||
kotlinAfterJavaTask = project.initKapt(kotlinTask, javaTask, kaptManager,
|
||||
sourceSetName, null, subpluginEnvironment, tasksProvider)
|
||||
sourceSetName, null, subpluginEnvironment, tasksProvider, null)
|
||||
} else {
|
||||
removeAnnotationProcessingPluginClasspathEntry(kotlinTask)
|
||||
}
|
||||
@@ -409,12 +408,13 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
|
||||
|
||||
protected val logger = Logging.getLogger(this.javaClass)
|
||||
|
||||
protected abstract fun forEachVariant(project: Project, action: (V) -> Unit): Unit
|
||||
abstract fun forEachVariant(project: Project, action: (V) -> Unit): Unit
|
||||
abstract fun getTestedVariantData(variantData: V): V?
|
||||
abstract fun getResDirectories(variantData: V): List<File>
|
||||
|
||||
protected abstract fun getSourceProviders(variantData: V): Iterable<SourceProvider>
|
||||
protected abstract fun getAllJavaSources(variantData: V): Iterable<File>
|
||||
protected abstract fun getVariantName(variant: V): String
|
||||
protected abstract fun getTestedVariantData(variantData: V): V?
|
||||
protected abstract fun getJavaTask(variantData: V): AbstractCompile?
|
||||
protected abstract fun addJavaSourceDirectoryToVariantModel(variantData: V, javaSourceDirectory: File): Unit
|
||||
|
||||
@@ -541,7 +541,7 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
|
||||
aptFiles.toSet(), aptOutputDir, aptWorkingDir, variantData)
|
||||
|
||||
kotlinAfterJavaTask = project.initKapt(kotlinTask, javaTask, kaptManager,
|
||||
variantDataName, rootKotlinOptions, subpluginEnvironment, tasksProvider)
|
||||
variantDataName, rootKotlinOptions, subpluginEnvironment, tasksProvider, this)
|
||||
}
|
||||
|
||||
for (task in listOfNotNull(kotlinTask, kotlinAfterJavaTask)) {
|
||||
@@ -554,7 +554,7 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
|
||||
configureMultiProjectIc(project, variantData, javaTask, kotlinTask, kotlinAfterJavaTask)
|
||||
|
||||
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
|
||||
project, kotlinTask, javaTask, wrapVariantDataForKapt(variantData), null)
|
||||
project, kotlinTask, javaTask, wrapVariantDataForKapt(variantData), this, null)
|
||||
|
||||
appliedPlugins.flatMap { it.getSubpluginKotlinTasks(project, kotlinTask) }
|
||||
.forEach { configureSources(it, variantData) }
|
||||
@@ -700,6 +700,7 @@ internal class SubpluginEnvironment(
|
||||
kotlinTask: KotlinCompile,
|
||||
javaTask: AbstractCompile,
|
||||
variantData: Any?,
|
||||
androidProjectHandler: AbstractAndroidProjectHandler<out Any?>?,
|
||||
javaSourceSet: SourceSet?
|
||||
): List<KotlinGradleSubplugin<KotlinCompile>> {
|
||||
val pluginOptions = kotlinTask.pluginOptions
|
||||
@@ -715,7 +716,7 @@ internal class SubpluginEnvironment(
|
||||
val subpluginClasspath = subpluginClasspaths[subplugin] ?: continue
|
||||
subpluginClasspath.forEach { pluginOptions.addClasspathEntry(it) }
|
||||
|
||||
for (option in subplugin.apply(project, kotlinTask, javaTask, variantData, javaSourceSet)) {
|
||||
for (option in subplugin.apply(project, kotlinTask, javaTask, variantData, androidProjectHandler, javaSourceSet)) {
|
||||
pluginOptions.addPluginArgument(subplugin.getCompilerPluginId(), option.key, option.value)
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -91,6 +91,10 @@ internal class LegacyAndroidAndroidProjectHandler(kotlinConfigurationTools: Kotl
|
||||
override fun getTestedVariantData(variantData: BaseVariantData<*>): BaseVariantData<*>? =
|
||||
((variantData as? TestVariantData)?.testedVariantData as? BaseVariantData<*>)
|
||||
|
||||
override fun getResDirectories(variantData: BaseVariantData<out BaseVariantOutputData>): List<File> {
|
||||
return variantData.mergeResourcesTask?.rawInputFolders?.toList() ?: emptyList()
|
||||
}
|
||||
|
||||
private fun Project.tryGetSingleArtifact(variantData: BaseVariantData<*>): File? {
|
||||
val log = logger
|
||||
log.kotlinDebug { "Trying to determine single artifact for project $path" }
|
||||
|
||||
+1
@@ -81,6 +81,7 @@ class NoArgKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
|
||||
kotlinCompile: AbstractCompile,
|
||||
javaCompile: AbstractCompile,
|
||||
variantData: Any?,
|
||||
androidProjectHandler: Any?,
|
||||
javaSourceSet: SourceSet?
|
||||
): List<SubpluginOption> {
|
||||
if (!NoArgGradleSubplugin.isEnabled(project)) return emptyList()
|
||||
|
||||
+1
@@ -80,6 +80,7 @@ class SamWithReceiverKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompi
|
||||
kotlinCompile: AbstractCompile,
|
||||
javaCompile: AbstractCompile,
|
||||
variantData: Any?,
|
||||
androidProjectHandler: Any?,
|
||||
javaSourceSet: SourceSet?
|
||||
): List<SubpluginOption> {
|
||||
if (!SamWithReceiverGradleSubplugin.isEnabled(project)) return emptyList()
|
||||
|
||||
+23
-18
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.android.synthetic.idea.res
|
||||
import com.android.builder.model.SourceProvider
|
||||
import com.android.tools.idea.gradle.AndroidGradleModel
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.roots.ProjectRootModificationTracker
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.impl.PsiTreeChangePreprocessor
|
||||
@@ -47,7 +48,9 @@ class IDEAndroidLayoutXmlFileManager(val module: Module) : AndroidLayoutXmlFileM
|
||||
else {
|
||||
if (_moduleData == null) {
|
||||
_moduleData = cachedValue(project) {
|
||||
CachedValueProvider.Result.create(super.getModuleData(), getPsiTreeChangePreprocessor())
|
||||
CachedValueProvider.Result.create(
|
||||
super.getModuleData(),
|
||||
getPsiTreeChangePreprocessor(), ProjectRootModificationTracker.getInstance(project))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,31 +106,33 @@ class IDEAndroidLayoutXmlFileManager(val module: Module) : AndroidLayoutXmlFileM
|
||||
return listOf()
|
||||
}
|
||||
|
||||
private fun SourceProvider.toVariant() = AndroidVariant(name, resDirectories.map { it.canonicalPath })
|
||||
|
||||
private val Module.androidFacet: AndroidFacet?
|
||||
get() = AndroidFacet.getInstance(this)
|
||||
|
||||
private fun SourceProvider.toVariant() = AndroidVariant(name, resDirectories.map { it.absolutePath })
|
||||
|
||||
private fun AndroidFacet.toAndroidModuleInfo(): AndroidModule? {
|
||||
val applicationPackage = manifest?.`package`?.toString()
|
||||
val applicationPackage = manifest?.`package`?.toString() ?: return null
|
||||
|
||||
if (applicationPackage != null) {
|
||||
val mainVariant = mainSourceProvider.toVariant()
|
||||
val allResDirectories = getAppResources(true)?.resourceDirs.orEmpty().mapNotNull { it.canonicalPath }
|
||||
|
||||
val method = try { this::class.java.getMethod("getFlavorSourceProviders") } catch (e: NoSuchMethodException) { null }
|
||||
val variants: List<AndroidVariant>? = if (method != null) {
|
||||
val sourceProviders = method.invoke(this) as List<SourceProvider>?
|
||||
sourceProviders?.map { it.toVariant() } ?: listOf()
|
||||
}
|
||||
else {
|
||||
val model = AndroidGradleModel.get(module)
|
||||
model?.flavorSourceProviders?.map { it.toVariant() } ?: listOf(this.mainSourceProvider.toVariant())
|
||||
}
|
||||
val resDirectoriesForMainVariant = run {
|
||||
val resDirsFromSourceProviders = AndroidGradleModel.get(module)?.allSourceProviders.orEmpty()
|
||||
.filter { it.name != "main" }
|
||||
.flatMap { it.resDirectories }
|
||||
.map { it.canonicalPath }
|
||||
|
||||
if (variants != null) {
|
||||
return AndroidModule(applicationPackage, listOf(mainVariant) + variants)
|
||||
allResDirectories - resDirsFromSourceProviders
|
||||
}
|
||||
|
||||
val variants = mutableListOf(AndroidVariant("main", resDirectoriesForMainVariant))
|
||||
|
||||
AndroidGradleModel.get(module)?.let { androidGradleModel ->
|
||||
androidGradleModel.activeSourceProviders.filter { it.name != "main" }.forEach { sourceProvider ->
|
||||
variants += sourceProvider.toVariant()
|
||||
}
|
||||
}
|
||||
return null
|
||||
|
||||
return AndroidModule(applicationPackage, variants)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user