summaryrefslogtreecommitdiff
path: root/compiler/src/main/kotlin/android/databinding
diff options
context:
space:
mode:
authorYigit Boyar <yboyar@google.com>2017-12-21 10:00:25 -0800
committerYigit Boyar <yboyar@google.com>2018-05-18 22:25:47 +0000
commit744db5c5a111d68c30302deae8b4ba1ea9355603 (patch)
treed77df39f15fa9cfffb37ccdf8f1b3fc1471db120 /compiler/src/main/kotlin/android/databinding
parent24c7c961ba1eb09dccab240bcd18fd71df09a7dc (diff)
downloaddata-binding-744db5c5a111d68c30302deae8b4ba1ea9355603.tar.gz
Fix kotlin.Unit method references in binding layouts.
When there is a binding adapter that receives a kotlin function which does not return, Kotlin converts it to Function0<kotlin.Unit>. But if there is a kotlin class with a method that does not return value, kotlin converts it to void. This becomes a problem for data binding because it cannot match the two when using function references. We cannot simply convert kotlin.Unit to void because we still generate code in java so we have to return a value in the implementation. Instead, this CL changes function matcher to accept the two as equals and also changes the code generators to handle the case manually. Also added a kotlin test app (finally). Bug: 70915745 Bug: 78662035 Test: KotlinTestApp Change-Id: I019ee7eb1dd635b12efd7725ccc22f0c63dc2d72
Diffstat (limited to 'compiler/src/main/kotlin/android/databinding')
-rw-r--r--compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt41
1 files changed, 24 insertions, 17 deletions
diff --git a/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt b/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt
index 18317af9..3581aaf6 100644
--- a/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt
+++ b/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt
@@ -607,7 +607,9 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder, val libTypes: LibTypes
callbacks.groupBy { it.callbackWrapper }.forEach {
val wrapper = it.key
val lambdas = it.value
- val shouldReturn = !wrapper.method.returnType.isVoid
+ // special case kotlin unit. b/78662035
+ val returnKotlinUnit = wrapper.method.returnType.isKotlinUnit
+ val shouldReturn = !wrapper.method.returnType.isVoid && !returnKotlinUnit
if (shouldReturn) {
lambdas.forEach {
it.callbackExprModel.ext.forceLocalize.add(it.expr)
@@ -621,6 +623,8 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder, val libTypes: LibTypes
nl(lambda.executionPath.toCode())
if (shouldReturn) {
nl("return ${lambda.expr.scopedName()};")
+ } else if (returnKotlinUnit) {
+ nl("return null;")
}
} else {
block("switch(${CallbackWrapper.SOURCE_ID})") {
@@ -628,10 +632,10 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder, val libTypes: LibTypes
block("case ${lambda.callbackId}:") {
nl(lambda.callbackExprModel.localizeGlobalVariables(lambda))
nl(lambda.executionPath.toCode())
- if (shouldReturn) {
- nl("return ${lambda.expr.scopedName()};")
- } else {
- nl("break;")
+ when {
+ shouldReturn -> nl("return ${lambda.expr.scopedName()};")
+ returnKotlinUnit -> nl("return null;")
+ else -> nl("break;")
}
}
}
@@ -1191,7 +1195,7 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder, val libTypes: LibTypes
} else {
extendsImplements = "extends"
}
- nl("public static class ${expr.listenerClassName} $extendsImplements ${listenerType.canonicalName}{") {
+ nl("public static class ${expr.listenerClassName} $extendsImplements $listenerType{") {
if (expr.target.isDynamic) {
tab("private ${expr.target.resolvedType.toJavaCode()} value;")
tab("public ${expr.listenerClassName} setValue(${expr.target.resolvedType.toJavaCode()} value) {") {
@@ -1209,22 +1213,25 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder, val libTypes: LibTypes
"${it.value.toJavaCode()} arg${it.index}"
}.joinToString(", ")
}) {") {
- val obj: String
- if (expr.target.isDynamic) {
- obj = "this.value"
+ val obj = if (expr.target.isDynamic) {
+ "this.value"
} else {
- obj = expr.target.toCode().generate();
+ expr.target.toCode().generate()
}
- val returnStr: String
- if (!returnType.isVoid) {
- returnStr = "return "
+ val returnSuffix = if(returnType.isKotlinUnit) {
+ "return null;"
} else {
- returnStr = ""
+ ""
}
- val args = parameterTypes.withIndex().map {
+ val returnPrefix = if (!returnType.isVoid && !returnType.isKotlinUnit) {
+ "return "
+ } else {
+ ""
+ }
+ val args = parameterTypes.withIndex().joinToString(", ") {
"arg${it.index}"
- }.joinToString(", ")
- tab("$returnStr$obj.${expr.name}($args);")
+ }
+ tab("$returnPrefix$obj.${expr.name}($args); $returnSuffix")
}
tab("}")
}