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 2d769af2580..33ec3a67096 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
@@ -8,13 +8,39 @@ import java.io.File
class KotlinAndroidGradleIT : AbstractKotlinAndroidGradleTests(gradleVersion = "3.3", androidGradlePluginVersion = "2.3.0")
-class KotlinAndroid30GradleIT : AbstractKotlinAndroidGradleTests(gradleVersion = "4.0-rc-1", androidGradlePluginVersion = "3.0.0-alpha2")
class KotlinAndroidWithJackGradleIT : AbstractKotlinAndroidWithJackGradleTests(gradleVersion = "3.3", androidGradlePluginVersion = "2.3.+")
+class KotlinAndroid30GradleIT : AbstractKotlinAndroidGradleTests(gradleVersion = "4.0-rc-1", androidGradlePluginVersion = "3.0.0-alpha2") {
+
+ @Test
+ fun testApplyWithFeaturePlugin() {
+ val project = Project("AndroidProject", gradleVersion)
+
+ project.setupWorkingDir()
+ File(project.projectDir, "Lib/build.gradle").modify { text ->
+ // Change the applied plugin to com.android.feature
+ text.replace("com.android.library", "com.android.feature").apply { assert(!equals(text)) }
+ }
+
+ // Check that Kotlin tasks were created for both lib and feature variants:
+ val kotlinTaskNames =
+ listOf("Debug", "Release").flatMap { buildType ->
+ listOf("Flavor1", "Flavor2").flatMap { flavor ->
+ listOf("", "Feature").map { isFeature -> ":Lib:compile$flavor$buildType${isFeature}Kotlin" }
+ }
+ }
+
+ project.build(":Lib:assemble") {
+ assertSuccessful()
+ assertContains(*kotlinTaskNames.toTypedArray())
+ }
+ }
+}
+
const val ANDROID_HOME_PATH = "../../../dependencies/androidSDK"
abstract class AbstractKotlinAndroidGradleTests(
- private val gradleVersion: String,
+ protected val gradleVersion: String,
private val androidGradlePluginVersion: String
) : BaseGradleIT() {
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3AndroidIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3AndroidIT.kt
index b92913a1aea..77b6201f17d 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3AndroidIT.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3AndroidIT.kt
@@ -6,7 +6,7 @@ import java.io.File
class Kapt3Android30IT : Kapt3AndroidIT() {
override val androidGradlePluginVersion: String
- get() = "3.0.0-alpha1"
+ get() = "3.0.0-alpha3"
}
open class Kapt3AndroidIT : Kapt3BaseIT() {
@@ -106,4 +106,17 @@ open class Kapt3AndroidIT : Kapt3BaseIT() {
assertFileExists("build/generated/source/kapt/release/io/realm/DefaultRealmModuleMediator.java")
}
}
+
+ @Test
+ open fun testDatabinding() {
+ val project = Project("android-databinding", GRADLE_VERSION, directoryPrefix = "kapt2")
+ val options = androidBuildOptions()
+
+ project.build("compileReleaseSources", options = options) {
+ assertSuccessful()
+ assertKaptSuccessful()
+ assertFileExists("app/build/generated/source/kapt/release/com/example/databinding/BR.java")
+ assertFileExists("app/build/generated/source/kapt/release/com/example/databinding/databinding/ActivityTestBinding.java")
+ }
+ }
}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/build.gradle
new file mode 100644
index 00000000000..38b16facd3c
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/build.gradle
@@ -0,0 +1,36 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-kapt'
+
+android {
+ compileSdkVersion 24
+ buildToolsVersion "25.0.2"
+ defaultConfig {
+ applicationId "com.example.databinding"
+ minSdkVersion 21
+ targetSdkVersion 24
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+ dataBinding {
+ enabled = true
+ }
+}
+
+repositories {
+ maven { url 'https://maven.google.com' }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+ kapt "com.android.databinding:compiler:$android_tools_version"
+ compile 'com.android.support.constraint:constraint-layout:1.0.2'
+ testCompile 'junit:junit:4.12'
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/AndroidManifest.xml b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000000..ec0a4f4c02c
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/AndroidManifest.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/java/com/example/databinding/EnumAdapter.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/java/com/example/databinding/EnumAdapter.kt
new file mode 100644
index 00000000000..be774cdd369
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/java/com/example/databinding/EnumAdapter.kt
@@ -0,0 +1,99 @@
+package com.example.databinding
+
+import android.content.Context
+import android.content.res.Resources
+import android.databinding.*
+import android.databinding.adapters.AdapterViewBindingAdapter
+import android.support.annotation.IntegerRes
+import android.util.Log
+import android.view.*
+import android.widget.*
+
+
+interface Displayable {
+ fun displayString(res: Resources): String
+}
+
+
+@InverseBindingMethods(
+ InverseBindingMethod(type = Spinner::class, attribute = "selectionEnum", method = "getSelectedItem", event = "app:selectionAttrChanged")
+)
+open class EnumAdapter(val context: Context,
+ enumClass: Class,
+ @IntegerRes var resource: Int = android.R.layout.simple_spinner_item,
+ @IntegerRes var dropDownResource: Int = android.R.layout.simple_spinner_dropdown_item,
+ val isOptional: Boolean = false) :
+ BaseAdapter() where DispEnum : Displayable, DispEnum : Enum
+{
+ val inflater: LayoutInflater = LayoutInflater.from(context)
+ val konstants: Array = enumClass.enumConstants
+
+ override fun getItem(position: Int): DispEnum? {
+ if (isOptional) {
+ return if (position == 0) null else konstants[position - 1]
+ }
+ return konstants[position]
+ }
+
+ override fun getItemId(position: Int): Long = position + 0L
+
+ override fun getCount(): Int = konstants.size + if (isOptional) 1 else 0
+
+ override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
+ return createViewFromResource(position, convertView, parent, resource)
+ }
+
+ override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
+ return createViewFromResource(position, convertView, parent, dropDownResource)
+ }
+
+ private fun createViewFromResource(position: Int, convertView: View?, parent: ViewGroup, resource: Int): View {
+ val view = convertView ?: inflater.inflate(resource, parent, false)
+ val textView: TextView
+ try {
+ textView = view as TextView
+ } catch (e: ClassCastException) {
+ Log.e("EnumAdapter", "You must supply a resource ID for a TextView")
+ return view
+ }
+
+ val enum = getItem(position)
+ textView.text = enum?.displayString(context.resources) ?: "-----"
+ return view
+ }
+
+ companion object {
+ @JvmStatic fun optionalPosition(e: Enum<*>?): Int {
+ e?.let { return it.ordinal + 1}
+ return 0
+ }
+ }
+}
+
+@BindingAdapter("app:selectionEnum", "app:selectionChanged", "app:selectionAttrChanged", requireAll = false)
+fun bindSpinnerEnum(spinner: Spinner, newValue: Enum<*>?,
+ itemSelectedListener: AdapterViewBindingAdapter.OnItemSelected?,
+ changeListener: InverseBindingListener?) {
+ val spinnerAdapter = spinner.adapter
+ if (spinnerAdapter !is EnumAdapter<*>) {
+ throw UnsupportedOperationException("app:selectionEnum attribute on Spinner requires EnumAdapter")
+ }
+ if (changeListener == null && itemSelectedListener == null)
+ spinner.onItemSelectedListener = null
+ else
+ spinner.onItemSelectedListener = AdapterViewBindingAdapter.OnItemSelectedComponentListener(itemSelectedListener, nothingingSelectedListener, changeListener)
+
+ val isOptional = spinnerAdapter.isOptional
+ if (!isOptional && newValue == null) {
+ throw IllegalStateException("Can't set a null value for app:selectionEnum, adapter.isOptional is false")
+ }
+ if (spinner.selectedItem != newValue) {
+ val sel = if (isOptional) EnumAdapter.optionalPosition(newValue) else newValue!!.ordinal
+ spinner.setSelection(sel)
+ }
+}
+
+val nothingingSelectedListener = object : AdapterViewBindingAdapter.OnNothingSelected {
+ override fun onNothingSelected(parent: AdapterView<*>?) {
+ }
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/java/com/example/databinding/MainActivity.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/java/com/example/databinding/MainActivity.kt
new file mode 100644
index 00000000000..97752b34139
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/java/com/example/databinding/MainActivity.kt
@@ -0,0 +1,38 @@
+package com.example.databinding
+
+import android.app.Activity
+import android.databinding.DataBindingUtil
+import android.os.Bundle
+import android.view.MotionEvent
+import android.widget.Toast
+import com.example.databinding.databinding.ActivityTestBinding
+
+class MainActivity : Activity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val binding: ActivityTestBinding = DataBindingUtil.setContentView(this, R.layout.activity_test)
+ val uprof = UserProfile()
+ binding.userProfile = uprof
+ binding.context = this
+ binding.genderPicker.adapter = EnumAdapter(this, Gender::class.java)
+ binding.genderPicker.setOnTouchListener { v, event ->
+ if (event.actionMasked == MotionEvent.ACTION_DOWN)
+ spinnerClicked = true
+ false
+ }
+ }
+
+ var spinnerClicked = false
+ fun spinnerClicked() {
+ spinnerClicked = true
+ }
+ fun selectionChanged() {
+ if (spinnerClicked)
+ Toast.makeText(this, "sdds", Toast.LENGTH_LONG).show()
+ spinnerClicked = false
+ }
+
+ fun clickHandler(uprof: UserProfile): Boolean = true
+
+ fun longClickHandler(uprof: UserProfile): Boolean = true
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/java/com/example/databinding/UserProfile.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/java/com/example/databinding/UserProfile.kt
new file mode 100644
index 00000000000..f229d4269f7
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/java/com/example/databinding/UserProfile.kt
@@ -0,0 +1,13 @@
+package com.example.databinding
+
+import android.content.res.Resources
+import android.databinding.BaseObservable
+
+class UserProfile : BaseObservable() {
+ open var gender: Gender = Gender.Female
+}
+
+enum class Gender(val display: String): Displayable {
+ Male("male"), Female("female");
+ override fun displayString(res: Resources): String = display
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/res/layout/activity_test.xml b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/res/layout/activity_test.xml
new file mode 100644
index 00000000000..9557021ba4d
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/res/layout/activity_test.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/res/values/strings.xml b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/res/values/strings.xml
new file mode 100644
index 00000000000..500e320cbba
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ ActivityRideUpTest
+
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/res/values/styles.xml b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/res/values/styles.xml
new file mode 100644
index 00000000000..32d75edf43f
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/app/src/main/res/values/styles.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/build.gradle
new file mode 100644
index 00000000000..748483695ef
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/build.gradle
@@ -0,0 +1,24 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ mavenLocal()
+ maven { url 'https://maven.google.com' }
+ }
+ dependencies {
+ classpath "com.android.tools.build:gradle:$android_tools_version"
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ mavenLocal()
+ maven { url 'https://maven.google.com' }
+ }
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/settings.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/settings.gradle
new file mode 100644
index 00000000000..e7b4def49cb
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/android-databinding/settings.gradle
@@ -0,0 +1 @@
+include ':app'