1d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar/* 2d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Copyright (C) 2015 The Android Open Source Project 3d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 4d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * you may not use this file except in compliance with the License. 5d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * You may obtain a copy of the License at 6d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 7d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Unless required by applicable law or agreed to in writing, software 8d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 9d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * See the License for the specific language governing permissions and 11d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * limitations under the License. 12d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar */ 13d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 14fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.tool.writer 15d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 166047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarimport android.databinding.tool.Binding 17e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarimport android.databinding.tool.BindingTarget 186047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarimport android.databinding.tool.CallbackWrapper 19d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mountimport android.databinding.tool.InverseBinding 20716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport android.databinding.tool.LayoutBinder 21fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.Expr 22fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ExprModel 23fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.FieldAccessExpr 24716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport android.databinding.tool.expr.IdentifierExpr 256047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarimport android.databinding.tool.expr.LambdaExpr 26793e979f25e190162eacf46d6a4efc3efc1d2f91George Mountimport android.databinding.tool.expr.ListenerExpr 2709aeb26073fc8a98263806f53e44819ebe5046c6Yigit Boyarimport android.databinding.tool.expr.ResourceExpr 28d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mountimport android.databinding.tool.expr.TernaryExpr 296047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarimport android.databinding.tool.expr.localizeGlobalVariables 306047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarimport android.databinding.tool.expr.shouldLocalizeInCallbacks 316047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarimport android.databinding.tool.expr.toCode 327b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarimport android.databinding.tool.ext.androidId 33d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mountimport android.databinding.tool.ext.br 347b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarimport android.databinding.tool.ext.joinToCamelCaseAsVar 3559229481aec5a284d322a2ca80dff836485feb0cYigit Boyarimport android.databinding.tool.ext.lazyProp 36716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport android.databinding.tool.ext.versionedLazy 3792a428505b9102bc0560d2d5be1768da097909c2George Mountimport android.databinding.tool.processing.ErrorMessages 38fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelAnalyzer 396047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarimport android.databinding.tool.reflection.ModelClass 407b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarimport android.databinding.tool.util.L 416047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarimport android.databinding.tool.util.Preconditions 4296e1c821dd446d1ed78f8ae61131550588f60a24George Mountimport java.util.ArrayList 43716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport java.util.Arrays 44716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport java.util.BitSet 4534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport java.util.HashMap 4643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 47fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyarfun String.stripNonJava() = this.split("[^a-zA-Z0-9]".toRegex()).map{ it.trim() }.joinToCamelCaseAsVar() 48d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 49019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarenum class Scope { 506047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar GLOBAL, 51fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar FIELD, 52fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar METHOD, 53fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar FLAG, 54fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar EXECUTE_PENDING_METHOD, 556047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar CONSTRUCTOR_PARAM, 566047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar CALLBACK; 576047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar companion object { 586047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar var currentScope = GLOBAL; 596047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar private val scopeStack = arrayListOf<Scope>() 606047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar fun enter(scope : Scope) { 616047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar scopeStack.add(currentScope) 626047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar currentScope = scope 636047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 646047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 656047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar fun exit() { 666047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar currentScope = scopeStack.removeAt(scopeStack.size - 1) 676047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 686047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 696047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar fun reset() { 706047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar scopeStack.clear() 716047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar currentScope = GLOBAL 726047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 736047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 74019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar} 75019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar 76d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarclass ExprModelExt { 77019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val usedFieldNames = hashMapOf<Scope, MutableSet<String>>(); 78fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar init { 7939113ca579a3d4e1c24e204f102e6dc9b26125afTor Norbye Scope.values().forEach { usedFieldNames[it] = hashSetOf<String>() } 80019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar } 816047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 826047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar internal val forceLocalize = hashSetOf<Expr>() 836047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 84d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val localizedFlags = arrayListOf<FlagSet>() 85d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 86d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun localizeFlag(set : FlagSet, name:String) : FlagSet { 87d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar localizedFlags.add(set) 88793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount val result = getUniqueName(name, Scope.FLAG, false) 8959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar set.localName = result 90d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return set 91d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 92d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 93793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount fun getUniqueName(base : String, scope : Scope, isPublic : kotlin.Boolean) : String { 94793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount var candidateBase = base 9559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (!isPublic && candidateBase.length > 20) { 96793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount candidateBase = candidateBase.substring(0, 20); 97793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } 98793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount var candidate = candidateBase 996047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar if (scope == Scope.CALLBACK || scope == Scope.EXECUTE_PENDING_METHOD) { 1006047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar candidate = candidate.decapitalize() 1016047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 102d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var i = 0 1035d454e5f2397a3b160f081ce123b4ca7ff0fc356Yigit Boyar while (usedFieldNames[scope]!!.contains(candidate)) { 104d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar i ++ 105793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount candidate = candidateBase + i 106d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 1075d454e5f2397a3b160f081ce123b4ca7ff0fc356Yigit Boyar usedFieldNames[scope]!!.add(candidate) 108d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return candidate 109d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 110d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 111d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 1126047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarfun ModelClass.defaultValue() = ModelAnalyzer.getInstance().getDefaultValue(toJavaCode()) 113793e979f25e190162eacf46d6a4efc3efc1d2f91George Mountfun ExprModel.getUniqueFieldName(base : String, isPublic : kotlin.Boolean) : String = ext.getUniqueName(base, Scope.FIELD, isPublic) 114793e979f25e190162eacf46d6a4efc3efc1d2f91George Mountfun ExprModel.getUniqueMethodName(base : String, isPublic : kotlin.Boolean) : String = ext.getUniqueName(base, Scope.METHOD, isPublic) 115793e979f25e190162eacf46d6a4efc3efc1d2f91George Mountfun ExprModel.getConstructorParamName(base : String) : String = ext.getUniqueName(base, Scope.CONSTRUCTOR_PARAM, false) 116d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun ExprModel.localizeFlag(set : FlagSet, base : String) : FlagSet = ext.localizeFlag(set, base) 117d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 11859229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.needsLocalField by lazyProp { expr : Expr -> 11959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar expr.canBeEvaluatedToAVariable() && !(expr.isVariable() && !expr.isUsed) && (expr.isDynamic || expr is ResourceExpr) 12009aeb26073fc8a98263806f53e44819ebe5046c6Yigit Boyar} 12109aeb26073fc8a98263806f53e44819ebe5046c6Yigit Boyar 1226047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarfun Expr.isForcedToLocalize() = model.ext.forceLocalize.contains(this) 12309aeb26073fc8a98263806f53e44819ebe5046c6Yigit Boyar 124019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar// not necessarily unique. Uniqueness is solved per scope 12559229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval BindingTarget.readableName by lazyProp { target: BindingTarget -> 12659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (target.id == null) { 12759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar "boundView" + indexFromTag(target.tag) 12800da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 12959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar target.id.androidId().stripNonJava() 13000da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 131d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 1327551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 133de38dd3ef0577d25b2d59863603abe5750d0c231George Mountfun BindingTarget.superConversion(variable : String) : String { 13459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (resolvedType != null && resolvedType.extendsViewStub()) { 13559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar return "new android.databinding.ViewStubProxy((android.view.ViewStub) $variable)" 136de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } else { 13759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar return "($interfaceClass) $variable" 138de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 139de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 140de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 14159229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval BindingTarget.fieldName : String by lazyProp { target : BindingTarget -> 142019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val name : String 143793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount val isPublic : kotlin.Boolean 14459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (target.id == null) { 145019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar name = "m${target.readableName}" 146793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount isPublic = false 147019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar } else { 148019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar name = target.readableName 149793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount isPublic = true 15034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 15159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar target.model.getUniqueFieldName(name, isPublic) 152d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 153d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 15459229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval BindingTarget.androidId by lazyProp { target : BindingTarget -> 15559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (target.id.startsWith("@android:id/")) { 15659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar "android.R.id.${target.id.androidId()}" 157fdfbbcd5ecf37d77a4b9ab1cefdebd68de71ca2bGeorge Mount } else { 15859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar "R.id.${target.id.androidId()}" 159fdfbbcd5ecf37d77a4b9ab1cefdebd68de71ca2bGeorge Mount } 160d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 161d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 16259229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval BindingTarget.interfaceClass by lazyProp { target : BindingTarget -> 16359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (target.resolvedType != null && target.resolvedType.extendsViewStub()) { 164de38dd3ef0577d25b2d59863603abe5750d0c231George Mount "android.databinding.ViewStubProxy" 165de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } else { 16659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar target.interfaceType 167de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 168de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 169de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 17059229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval BindingTarget.constructorParamName by lazyProp { target : BindingTarget -> 17159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar target.model.getConstructorParamName(target.readableName) 172d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 173d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 174019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar// not necessarily unique. Uniqueness is decided per scope 17559229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.readableName by lazyProp { expr : Expr -> 1766047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar val stripped = expr.uniqueKey.stripNonJava() 17759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar L.d("readableUniqueName for [%s] %s is %s", System.identityHashCode(expr), expr.uniqueKey, stripped) 178019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar stripped 179de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 180de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 18159229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.fieldName by lazyProp { expr : Expr -> 18259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar expr.model.getUniqueFieldName("m${expr.readableName.capitalize()}", false) 183d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 184d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 185d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mountval InverseBinding.fieldName by lazyProp { inverseBinding : InverseBinding -> 186af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar val targetName = inverseBinding.target.fieldName; 187af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar val eventName = inverseBinding.eventAttribute.stripNonJava() 188af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar inverseBinding.model.getUniqueFieldName("$targetName$eventName", false) 189d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount} 190d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 19159229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.listenerClassName by lazyProp { expr : Expr -> 19259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar expr.model.getUniqueFieldName("${expr.resolvedType.simpleName}Impl", false) 193716ba89e7f459f49ea85070d4710c1d79d715298George Mount} 194716ba89e7f459f49ea85070d4710c1d79d715298George Mount 19559229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.oldValueName by lazyProp { expr : Expr -> 19659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar expr.model.getUniqueFieldName("mOld${expr.readableName.capitalize()}", false) 19720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount} 19820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 1996047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarfun Expr.scopedName() : String = when(Scope.currentScope) { 2006047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar Scope.CALLBACK -> callbackLocalName 2016047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar else -> executePendingLocalName 2026047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar} 2036047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 2046047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarval Expr.callbackLocalName by lazyProp { expr : Expr -> 2056047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar if(expr.shouldLocalizeInCallbacks()) "${expr.model.ext.getUniqueName(expr.readableName, Scope.CALLBACK, false)}" 2066047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar else expr.toCode().generate() 2076047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar} 2086047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 20959229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.executePendingLocalName by lazyProp { expr : Expr -> 210f58c3bd412f9bdc5ec589fdcfed470889abb6ea6Yigit Boyar if(expr.isDynamic || expr.needsLocalField) "${expr.model.ext.getUniqueName(expr.readableName, Scope.EXECUTE_PENDING_METHOD, false)}" 21109aeb26073fc8a98263806f53e44819ebe5046c6Yigit Boyar else expr.toCode().generate() 212d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 213d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 21459229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.setterName by lazyProp { expr : Expr -> 21559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar expr.model.getUniqueMethodName("set${expr.readableName.capitalize()}", true) 216d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 217d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 21859229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.onChangeName by lazyProp { expr : Expr -> 21959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar expr.model.getUniqueMethodName("onChange${expr.readableName.capitalize()}", false) 220d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 221d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 22259229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.getterName by lazyProp { expr : Expr -> 22359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar expr.model.getUniqueMethodName("get${expr.readableName.capitalize()}", true) 224d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 225d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 22659229481aec5a284d322a2ca80dff836485feb0cYigit Boyarfun Expr.isVariable() = this is IdentifierExpr && this.isDynamic 227d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 22859229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.dirtyFlagSet by lazyProp { expr : Expr -> 22959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar FlagSet(expr.invalidFlags, expr.model.flagBucketCount) 230d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 231d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 23259229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.invalidateFlagSet by lazyProp { expr : Expr -> 23359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar FlagSet(expr.id) 234d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 235d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 23659229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.shouldReadFlagSet by versionedLazy { expr : Expr -> 23759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar FlagSet(expr.shouldReadFlags, expr.model.flagBucketCount) 238d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 239d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 24059229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.shouldReadWithConditionalsFlagSet by versionedLazy { expr : Expr -> 24159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar FlagSet(expr.shouldReadFlagsWithConditionals, expr.model.flagBucketCount) 242eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar} 243eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar 24459229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.conditionalFlags by lazyProp { expr : Expr -> 245d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar arrayListOf(FlagSet(expr.getRequirementFlagIndex(false)), 246d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getRequirementFlagIndex(true))) 247d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 248d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 2496047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarfun Binding.toAssignmentCode() : String { 2506047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar val fieldName: String 2516047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar if (this.target.viewClass. 2526047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar equals(this.target.interfaceType)) { 2536047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar fieldName = "this.${this.target.fieldName}" 2546047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } else { 2556047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar fieldName = "((${this.target.viewClass}) this.${this.target.fieldName})" 2566047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 2576047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar return this.toJavaCode(fieldName, "this.mBindingComponent") 2586047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar} 2596047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 26059229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval LayoutBinder.requiredComponent by lazyProp { layoutBinder: LayoutBinder -> 261d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount val requiredFromBindings = layoutBinder. 26259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar bindingTargets. 26359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar flatMap { it.bindings }. 264d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount firstOrNull { it.bindingAdapterInstanceClass != null }?.bindingAdapterInstanceClass 265d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount val requiredFromInverse = layoutBinder. 266d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount bindingTargets. 267d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount flatMap { it.inverseBindings }. 268d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount firstOrNull { it.bindingAdapterInstanceClass != null }?.bindingAdapterInstanceClass 269d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount requiredFromBindings ?: requiredFromInverse 270e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount} 271e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 272d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.getRequirementFlagSet(expected : Boolean) : FlagSet = conditionalFlags[if(expected) 1 else 0] 273d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 274d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.notEmpty(cb : (suffix : String, value : Long) -> Unit) { 275d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar buckets.withIndex().forEach { 276d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (it.value != 0L) { 277d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar cb(getWordSuffix(it.index), buckets[it.index]) 278d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 279d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 280d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 281d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 28259229481aec5a284d322a2ca80dff836485feb0cYigit Boyarfun getWordSuffix(wordIndex : Int) : String { 28359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar return if(wordIndex == 0) "" else "_$wordIndex" 284d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 285d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 286d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.localValue(bucketIndex : Int) = 28759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (localName == null) binaryCode(bucketIndex) 28859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar else "$localName${getWordSuffix(bucketIndex)}" 289d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 290d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyarfun FlagSet.binaryCode(bucketIndex : Int) = longToBinary(buckets[bucketIndex]) 291d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 292d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 29359229481aec5a284d322a2ca80dff836485feb0cYigit Boyarfun longToBinary(l : Long) = "0x${java.lang.Long.toHexString(l)}L" 294d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 295d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun <T> FlagSet.mapOr(other : FlagSet, cb : (suffix : String, index : Int) -> T) : List<T> { 29659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val min = Math.min(buckets.size, other.buckets.size) 297d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val result = arrayListOf<T>() 298d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in 0..(min - 1)) { 299d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // if these two can match by any chance, call the callback 300d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (intersect(other, i)) { 301d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar result.add(cb(getWordSuffix(i), i)) 302d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 303d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 304d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return result 305d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 306d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 30796e1c821dd446d1ed78f8ae61131550588f60a24George Mountfun indexFromTag(tag : String) : kotlin.Int { 30896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val startIndex : kotlin.Int 3097ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount if (tag.startsWith("binding_")) { 31059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar startIndex = "binding_".length; 31196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 31296e1c821dd446d1ed78f8ae61131550588f60a24George Mount startIndex = tag.lastIndexOf('_') + 1 31396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 31496e1c821dd446d1ed78f8ae61131550588f60a24George Mount return Integer.parseInt(tag.substring(startIndex)) 31596e1c821dd446d1ed78f8ae61131550588f60a24George Mount} 31696e1c821dd446d1ed78f8ae61131550588f60a24George Mount 31743596c2b2997e40b709627419732100d78a62ff0Yigit Boyarclass LayoutBinderWriter(val layoutBinder : LayoutBinder) { 31859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val model = layoutBinder.model 31934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val indices = HashMap<BindingTarget, kotlin.Int>() 32059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val mDirtyFlags by lazy { 32159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val fs = FlagSet(BitSet(), model.flagBucketCount); 32243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Arrays.fill(fs.buckets, -1) 32359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar fs.isDynamic = true 32443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.localizeFlag(fs, "mDirtyFlags") 32543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs 326d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 327d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 32859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val className = layoutBinder.implementationName 329d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 33059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val baseClassName = "${layoutBinder.className}" 331d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 33259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val includedBinders by lazy { 33359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.bindingTargets.filter { it.isBinder } 3347551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 3357551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 33659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val variables by lazy { 33759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar model.exprMap.values.filterIsInstance(IdentifierExpr::class.java).filter { it.isVariable() } 33843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 339d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 34059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val usedVariables by lazy { 3416047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar variables.filter {it.isUsed || it.isIsUsedInCallback } 3426047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 3436047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 3446047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar val callbacks by lazy { 3456047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar model.exprMap.values.filterIsInstance(LambdaExpr::class.java) 3465bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 347d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 34896e1c821dd446d1ed78f8ae61131550588f60a24George Mount public fun write(minSdk : kotlin.Int) : String { 3496047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar Scope.reset() 3505bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar layoutBinder.resolveWhichExpressionsAreUsed() 35134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount calculateIndices(); 35259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar return kcode("package ${layoutBinder.`package`};") { 35359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("import ${layoutBinder.modulePackage}.R;") 35459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("import ${layoutBinder.modulePackage}.BR;") 3555bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("import android.view.View;") 356dea555cf42dc3583604699c8c018d22681f56166George Mount val classDeclaration : String 357dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 35859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar classDeclaration = "$className extends $baseClassName" 359dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 36059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar classDeclaration = "$className extends android.databinding.ViewDataBinding" 361dea555cf42dc3583604699c8c018d22681f56166George Mount } 3626047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("public class $classDeclaration ${buildImplements()}") { 3636047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(declareIncludeViews()) 3646047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(declareViews()) 3656047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(declareVariables()) 3666047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(declareBoundValues()) 3676047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(declareListeners()) 368bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount try { 369bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount Scope.enter(Scope.GLOBAL) 370bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount nl(declareInverseBindingImpls()); 371bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount } finally { 372bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount Scope.exit() 373bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount } 3746047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(declareConstructor(minSdk)) 3756047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(declareInvalidateAll()) 3766047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(declareHasPendingBindings()) 3776047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(declareSetVariable()) 3786047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(variableSettersAndGetters()) 3796047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(onFieldChange()) 3806047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar try { 3816047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar Scope.enter(Scope.GLOBAL) 3826047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(executePendingBindings()) 3836047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } finally { 3846047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar Scope.exit() 3856047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 3866047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 3876047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(declareListenerImpls()) 3886047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar try { 3896047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar Scope.enter(Scope.CALLBACK) 3906047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(declareCallbackImplementations()) 3916047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } finally { 3926047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar Scope.exit() 3936047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 3946047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 3956047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(declareDirtyFlags()) 396dea555cf42dc3583604699c8c018d22681f56166George Mount if (!layoutBinder.hasVariations()) { 3976047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(declareFactories()) 398dea555cf42dc3583604699c8c018d22681f56166George Mount } 3996047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(flagMapping()) 4006047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("//end") 4015bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 4025bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar }.generate() 4035bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 4046047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar fun buildImplements() : String { 4056047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar return if (callbacks.isEmpty()) { 4066047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar "" 4076047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } else { 4086047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar "implements " + callbacks.map { it.callbackWrapper.cannonicalListenerName }.distinct().joinToString(", ") 4096047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 4106047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 4116047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 41234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fun calculateIndices() : Unit { 41359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val taggedViews = layoutBinder.bindingTargets.filter{ 41459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.isUsed && it.tag != null && !it.isBinder 41534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 41696e1c821dd446d1ed78f8ae61131550588f60a24George Mount taggedViews.forEach { 41759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar indices.put(it, indexFromTag(it.tag)) 41896e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 41996e1c821dd446d1ed78f8ae61131550588f60a24George Mount val indexStart = maxIndex() + 1 42059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.bindingTargets.filter{ 42159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.isUsed && !taggedViews.contains(it) 42296e1c821dd446d1ed78f8ae61131550588f60a24George Mount }.withIndex().forEach { 42396e1c821dd446d1ed78f8ae61131550588f60a24George Mount indices.put(it.value, it.index + indexStart) 42434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 42534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 4264c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun declareIncludeViews() = kcode("") { 427239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount nl("private static final android.databinding.ViewDataBinding.IncludedLayouts sIncludes;") 4284c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("private static final android.util.SparseIntArray sViewsWithIds;") 4294c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("static {") { 43059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val hasBinders = layoutBinder.bindingTargets.firstOrNull{ it.isUsed && it.isBinder } != null 4314c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount if (!hasBinders) { 4324c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sIncludes = null;") 43300da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 43459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val numBindings = layoutBinder.bindingTargets.filter{ it.isUsed }.count() 43559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("sIncludes = new android.databinding.ViewDataBinding.IncludedLayouts($numBindings);") 43696e1c821dd446d1ed78f8ae61131550588f60a24George Mount val includeMap = HashMap<BindingTarget, ArrayList<BindingTarget>>() 43759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.bindingTargets.filter{ it.isUsed && it.isBinder }.forEach { 43859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val includeTag = it.tag; 43959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val parent = layoutBinder.bindingTargets.firstOrNull { 44059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.isUsed && !it.isBinder && includeTag.equals(it.tag) 44159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar } ?: throw IllegalStateException("Could not find parent of include file") 44259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar var list = includeMap[parent] 44396e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (list == null) { 44496e1c821dd446d1ed78f8ae61131550588f60a24George Mount list = ArrayList<BindingTarget>() 44596e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.put(parent, list) 44696e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 44796e1c821dd446d1ed78f8ae61131550588f60a24George Mount list.add(it) 4484c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 44996e1c821dd446d1ed78f8ae61131550588f60a24George Mount 45059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar includeMap.keys.forEach { 45159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val index = indices[it] 45259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("sIncludes.setIncludes($index, ") { 453239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount tab ("new String[] {${ 45459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar includeMap[it]!!.map { 45559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar "\"${it.includedLayout}\"" 456239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount }.joinToString(", ") 457239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount }},") 458239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount tab("new int[] {${ 45959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar includeMap[it]!!.map { 46059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar "${indices[it]}" 461239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount }.joinToString(", ") 462239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount }},") 463239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount tab("new int[] {${ 46459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar includeMap[it]!!.map { 46559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar "R.layout.${it.includedLayout}" 466239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount }.joinToString(", ") 467239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount }});") 46896e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 46996e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 47096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 47159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val viewsWithIds = layoutBinder.bindingTargets.filter { 47259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.isUsed && !it.isBinder && (!it.supportsTag() || (it.id != null && it.tag == null)) 47300da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 47496e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (viewsWithIds.isEmpty()) { 4754c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = null;") 47600da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 4774c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = new android.util.SparseIntArray();") 47896e1c821dd446d1ed78f8ae61131550588f60a24George Mount viewsWithIds.forEach { 47959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("sViewsWithIds.put(${it.androidId}, ${indices[it]});") 4804c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 48100da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 4824c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 4834c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("}") 4844c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 48596e1c821dd446d1ed78f8ae61131550588f60a24George Mount 48696e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun maxIndex() : kotlin.Int { 48759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val maxIndex = indices.values.max() 48896e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (maxIndex == null) { 48996e1c821dd446d1ed78f8ae61131550588f60a24George Mount return -1 49096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 49196e1c821dd446d1ed78f8ae61131550588f60a24George Mount return maxIndex 49296e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 49396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 49496e1c821dd446d1ed78f8ae61131550588f60a24George Mount 49596e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun declareConstructor(minSdk : kotlin.Int) = kcode("") { 49696e1c821dd446d1ed78f8ae61131550588f60a24George Mount val bindingCount = maxIndex() + 1 49796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val parameterType : String 49896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val superParam : String 49959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (layoutBinder.isMerge) { 50096e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View[]" 50196e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root[0]" 50296e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 50396e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View" 50496e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root" 50596e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 50696e1c821dd446d1ed78f8ae61131550588f60a24George Mount val rootTagsSupported = minSdk >= 14 507dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 508dea555cf42dc3583604699c8c018d22681f56166George Mount nl("") 50959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public $className(android.databinding.DataBindingComponent bindingComponent, $parameterType root) {") { 51059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("this(bindingComponent, $superParam, mapBindings(bindingComponent, root, $bindingCount, sIncludes, sViewsWithIds));") 511dea555cf42dc3583604699c8c018d22681f56166George Mount } 512dea555cf42dc3583604699c8c018d22681f56166George Mount nl("}") 51359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("private $className(android.databinding.DataBindingComponent bindingComponent, $parameterType root, Object[] bindings) {") { 51459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("super(bindingComponent, $superParam, ${model.observables.size}") { 51559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.sortedTargets.filter { it.id != null }.forEach { 516dea555cf42dc3583604699c8c018d22681f56166George Mount tab(", ${fieldConversion(it)}") 51734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 518dea555cf42dc3583604699c8c018d22681f56166George Mount tab(");") 51934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 52034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 521dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 52259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public $baseClassName(android.databinding.DataBindingComponent bindingComponent, $parameterType root) {") { 52359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("super(bindingComponent, $superParam, ${model.observables.size});") 52459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("final Object[] bindings = mapBindings(bindingComponent, root, $bindingCount, sIncludes, sViewsWithIds);") 525dea555cf42dc3583604699c8c018d22681f56166George Mount } 526dea555cf42dc3583604699c8c018d22681f56166George Mount } 527e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount if (layoutBinder.requiredComponent != null) { 528e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("ensureBindingComponentIsNotNull(${layoutBinder.requiredComponent}.class);") 529e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 53059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val taggedViews = layoutBinder.sortedTargets.filter{it.isUsed } 531dea555cf42dc3583604699c8c018d22681f56166George Mount taggedViews.forEach { 53259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (!layoutBinder.hasVariations() || it.id == null) { 533dea555cf42dc3583604699c8c018d22681f56166George Mount tab("this.${it.fieldName} = ${fieldConversion(it)};") 534dea555cf42dc3583604699c8c018d22681f56166George Mount } 53559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (!it.isBinder) { 53659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (it.resolvedType != null && it.resolvedType.extendsViewStub()) { 537de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("this.${it.fieldName}.setContainingBinding(this);") 538de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 53959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (it.supportsTag() && it.tag != null && 54059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar (rootTagsSupported || it.tag.startsWith("binding_"))) { 54159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val originalTag = it.originalTag; 542dea555cf42dc3583604699c8c018d22681f56166George Mount var tagValue = "null" 54392a428505b9102bc0560d2d5be1768da097909c2George Mount if (originalTag != null && !originalTag.startsWith("@{")) { 54459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tagValue = "\"$originalTag\"" 545dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@")) { 54659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar var packageName = layoutBinder.modulePackage 547dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@android:")) { 548dea555cf42dc3583604699c8c018d22681f56166George Mount packageName = "android" 54900da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 550dea555cf42dc3583604699c8c018d22681f56166George Mount val slashIndex = originalTag.indexOf('/') 551dea555cf42dc3583604699c8c018d22681f56166George Mount val resourceId = originalTag.substring(slashIndex + 1) 55259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tagValue = "root.getResources().getString($packageName.R.string.$resourceId)" 55300da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 55400da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 55559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("this.${it.fieldName}.setTag($tagValue);") 55659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar } else if (it.tag != null && !it.tag.startsWith("binding_") && 55759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.originalTag != null) { 55859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar L.e(ErrorMessages.ROOT_TAG_NOT_SUPPORTED, it.originalTag) 5597551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 560d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 561d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 5624d4979490e1fa374c0d7f3599fed0a9e83a579d0George Mount tab("setRootTag(root);") 5636047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar tab(declareCallbackInstances()) 564dea555cf42dc3583604699c8c018d22681f56166George Mount tab("invalidateAll();"); 5650fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 566d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 567d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 5686047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar fun declareCallbackInstances() = kcode("// listeners") { 5696047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar callbacks.groupBy { it.callbackWrapper.minApi } 5706047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar .forEach { 5716047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar if (it.key > 1) { 5726047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("if(getBuildSdkInt() < ${it.key})") { 5736047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar it.value.forEach { lambda -> 5746047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("${lambda.fieldName} = null;") 5756047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 5766047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 5776047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("else") { 5786047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar it.value.forEach { lambda -> 5796047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("${lambda.fieldName} = ${lambda.generateConstructor()};") 5806047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 5816047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 5826047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } else { 5836047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar it.value.forEach { lambda -> 5846047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("${lambda.fieldName} = ${lambda.generateConstructor()};") 5856047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 5866047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 5876047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 5886047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 5896047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 5906047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar fun declareCallbackImplementations() = kcode("// callback impls") { 5916047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar callbacks.groupBy { it.callbackWrapper }.forEach { 5926047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar val wrapper = it.key 5936047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar val lambdas = it.value 5946047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar val shouldReturn = !wrapper.method.returnType.isVoid 5956047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar if (shouldReturn) { 5966047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar lambdas.forEach { 5976047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar it.callbackExprModel.ext.forceLocalize.add(it.expr) 5986047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 5996047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 6006047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("public final ${wrapper.method.returnType.canonicalName} ${wrapper.listenerMethodName}(${wrapper.allArgsWithTypes()})") { 6016047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar Preconditions.check(lambdas.size > 0, "bindings list should not be empty") 6026047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar if (lambdas.size == 1) { 6036047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar val lambda = lambdas[0] 6046047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(lambda.callbackExprModel.localizeGlobalVariables(lambda)) 6056047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(lambda.executionPath.toCode()) 6066047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar if (shouldReturn) { 6076047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("return ${lambda.expr.scopedName()};") 6086047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 6096047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } else { 6106047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("switch(${CallbackWrapper.SOURCE_ID})") { 6116047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar lambdas.forEach { lambda -> 6126047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("case ${lambda.callbackId}:") { 6136047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(lambda.callbackExprModel.localizeGlobalVariables(lambda)) 6146047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(lambda.executionPath.toCode()) 6156047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar if (shouldReturn) { 6166047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("return ${lambda.expr.scopedName()};") 6176047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } else { 6186047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("break;") 6196047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 6206047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 6216047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 6226047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar if (shouldReturn) { 6236047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("default:") { 6246047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("return ${wrapper.method.returnType.defaultValue()};") 6256047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 6266047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 6276047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 6286047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 6296047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 6306047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 6316047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 6326047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 633dea555cf42dc3583604699c8c018d22681f56166George Mount fun fieldConversion(target : BindingTarget) : String { 63459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (!target.isUsed) { 635dea555cf42dc3583604699c8c018d22681f56166George Mount return "null" 636dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 63759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val index = indices[target] ?: throw IllegalStateException("Unknown binding target") 63859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val variableName = "bindings[$index]" 639dea555cf42dc3583604699c8c018d22681f56166George Mount return target.superConversion(variableName) 640dea555cf42dc3583604699c8c018d22681f56166George Mount } 641dea555cf42dc3583604699c8c018d22681f56166George Mount } 642dea555cf42dc3583604699c8c018d22681f56166George Mount 643d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareInvalidateAll() = kcode("") { 6447551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("@Override") 6456047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("public void invalidateAll()") { 64659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val fs = FlagSet(layoutBinder.model.invalidateAnyBitSet, 64759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.model.flagBucketCount); 6486047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("synchronized(this)") { 64959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar for (i in (0..(mDirtyFlags.buckets.size - 1))) { 6501c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.localValue(i)} = ${fs.localValue(i)};") 6511c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 6526047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 65359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar includedBinders.filter{it.isUsed }.forEach { binder -> 6546047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("${binder.fieldName}.invalidateAll();") 6557551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 6566047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("requestRebind();"); 657d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 658d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 659d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 660447971abca811b11b8c1d8e7bfaa294856d03c16George Mount fun declareHasPendingBindings() = kcode("") { 661447971abca811b11b8c1d8e7bfaa294856d03c16George Mount nl("@Override") 662447971abca811b11b8c1d8e7bfaa294856d03c16George Mount nl("public boolean hasPendingBindings() {") { 66359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (mDirtyFlags.buckets.size > 0) { 664447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("synchronized(this) {") { 66559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val flagCheck = 0.rangeTo(mDirtyFlags.buckets.size - 1).map { 666447971abca811b11b8c1d8e7bfaa294856d03c16George Mount "${mDirtyFlags.localValue(it)} != 0" 667447971abca811b11b8c1d8e7bfaa294856d03c16George Mount }.joinToString(" || ") 66859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("if ($flagCheck) {") { 669447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("return true;") 670447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 671447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("}") 672447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 673447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("}") 674447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 67559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar includedBinders.filter{it.isUsed }.forEach { binder -> 676447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("if (${binder.fieldName}.hasPendingBindings()) {") { 677447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("return true;") 678447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 679447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("}") 680447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 681447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("return false;") 682447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 683447971abca811b11b8c1d8e7bfaa294856d03c16George Mount nl("}") 684447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 685447971abca811b11b8c1d8e7bfaa294856d03c16George Mount 686d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareSetVariable() = kcode("") { 6870fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("public boolean setVariable(int variableId, Object variable) {") { 688d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch(variableId) {") { 6895bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 69059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab ("case ${it.name.br()} :") { 69159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("${it.setterName}((${it.resolvedType.toJavaCode()}) variable);") 692d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 693d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 694d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 6956047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar val declaredOnly = variables.filter { !it.isUsed && !it.isIsUsedInCallback && it.isDeclared }; 69623910cf498c35704a03ba4f3889de2ab97ccbe21George Mount declaredOnly.forEachIndexed { i, identifierExpr -> 69759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab ("case ${identifierExpr.name.br()} :") { 69859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (i == declaredOnly.size - 1) { 69923910cf498c35704a03ba4f3889de2ab97ccbe21George Mount tab("return true;") 70023910cf498c35704a03ba4f3889de2ab97ccbe21George Mount } 70123910cf498c35704a03ba4f3889de2ab97ccbe21George Mount } 70223910cf498c35704a03ba4f3889de2ab97ccbe21George Mount } 703d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 704d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 705d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 706d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7070fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 708d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 709d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 710d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun variableSettersAndGetters() = kcode("") { 7116047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar variables.filterNot{ usedVariables.contains(it) }.forEach { 71259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public void ${it.setterName}(${it.resolvedType.toJavaCode()} ${it.readableName}) {") { 7135bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("// not used, ignore") 7145bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 7155bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 7165bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("") 71759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public ${it.resolvedType.toJavaCode()} ${it.getterName}() {") { 71859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("return ${it.defaultValue};") 7195bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 7205bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 7215bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 7225bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 72359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (it.userDefinedType != null) { 7246047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("public void ${it.setterName}(${it.resolvedType.toJavaCode()} ${it.readableName})") { 72559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (it.isObservable) { 7266047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("updateRegistration(${it.id}, ${it.readableName});"); 72718243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 7286047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("this.${it.fieldName} = ${it.readableName};") 72918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount // set dirty flags! 73018243f6f1b7527272ef4feccdf4327d80d9f2241George Mount val flagSet = it.invalidateFlagSet 7316047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("synchronized(this)") { 7321c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 7336047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("${mDirtyFlags.localName}$suffix |= ${flagSet.localValue(index)};") 7341c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 7356047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 736d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount // TODO: Remove this condition after releasing version 1.1 of SDK 737d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (ModelAnalyzer.getInstance().findClass("android.databinding.ViewDataBinding", null).isObservable) { 7386047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("notifyPropertyChanged(${it.name.br()});") 739d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 7406047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("super.requestRebind();") 741d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 74218243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("") 7436047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("public ${it.resolvedType.toJavaCode()} ${it.getterName}()") { 7446047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("return ${it.fieldName};") 745d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 746d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 747d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 748d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 749d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 750d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun onFieldChange() = kcode("") { 75134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("@Override") 75234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {") { 7534c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("switch (localFieldId) {") { 75459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar model.observables.forEach { 75559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("case ${it.id} :") { 75659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("return ${it.onChangeName}((${it.resolvedType.toJavaCode()}) object, fieldId);") 757d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 758d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 759d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 760d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 761d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 762d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 76334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 76434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 765d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 76659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar model.observables.forEach { 7676047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("private boolean ${it.onChangeName}(${it.resolvedType.toJavaCode()} ${it.readableName}, int fieldId)") { 7686047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("switch (fieldId)", { 76959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val accessedFields: List<FieldAccessExpr> = it.parents.filterIsInstance(FieldAccessExpr::class.java) 7706047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar accessedFields.filter { it.isUsed && it.hasBindableAnnotations() } 77188ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar .groupBy { it.brName } 772d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 77388ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar // If two expressions look different but resolve to the same method, 77488ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar // we are not yet able to merge them. This is why we merge their 77588ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar // flags below. 7766047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("case ${it.key}:") { 7776047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("synchronized(this)") { 77888ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar val flagSet = it.value.foldRight(FlagSet()) { l, r -> l.invalidateFlagSet.or(r) } 77988ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar 78088ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 78188ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar tab("${mDirtyFlags.localValue(index)} |= ${flagSet.localValue(index)};") 7821c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 7836047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 7846047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("return true;") 785d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 786d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 787d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7886047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("case ${"".br()}:") { 789d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.invalidateFlagSet 7906047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("synchronized(this)") { 7911c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 79259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("${mDirtyFlags.localName}$suffix |= ${flagSet.localValue(index)};") 7931c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 7946047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 7956047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("return true;") 796d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 797d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) 7986047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("return false;") 799d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 80034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 801d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 802d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 803d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 804d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareViews() = kcode("// views") { 805dea555cf42dc3583604699c8c018d22681f56166George Mount val oneLayout = !layoutBinder.hasVariations(); 80659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.sortedTargets.filter {it.isUsed && (oneLayout || it.id == null)}.forEach { 807dea555cf42dc3583604699c8c018d22681f56166George Mount val access : String 80859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (oneLayout && it.id != null) { 809dea555cf42dc3583604699c8c018d22681f56166George Mount access = "public" 810dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 811dea555cf42dc3583604699c8c018d22681f56166George Mount access = "private" 812dea555cf42dc3583604699c8c018d22681f56166George Mount } 81359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("$access final ${it.interfaceClass} ${it.fieldName};") 814d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 815d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 816d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 817d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareVariables() = kcode("// variables") { 8185bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 81959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("private ${it.resolvedType.toJavaCode()} ${it.fieldName};") 820d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8216047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar callbacks.forEach { 8226047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar val wrapper = it.callbackWrapper 8236047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("private final ${wrapper.klass.canonicalName} ${it.fieldName}").app(";") 8246047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 825d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 826d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 82720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount fun declareBoundValues() = kcode("// values") { 82859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.sortedTargets.filter { it.isUsed } 82959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar .flatMap { it.bindings } 83020c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .filter { it.requiresOldValue() } 8316047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar .flatMap{ it.componentExpressions.toList() } 83220c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .groupBy { it } 83320c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .forEach { 83459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val expr = it.key 83559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("private ${expr.resolvedType.toJavaCode()} ${expr.oldValueName};") 83620c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 83720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 83820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 839716ba89e7f459f49ea85070d4710c1d79d715298George Mount fun declareListeners() = kcode("// listeners") { 84059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar model.exprMap.values.filter { 841793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount it is ListenerExpr 842716ba89e7f459f49ea85070d4710c1d79d715298George Mount }.groupBy { it }.forEach { 843793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount val expr = it.key as ListenerExpr 844716ba89e7f459f49ea85070d4710c1d79d715298George Mount nl("private ${expr.listenerClassName} ${expr.fieldName};") 845716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 846716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 847716ba89e7f459f49ea85070d4710c1d79d715298George Mount 848d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount fun declareInverseBindingImpls() = kcode("// Inverse Binding Event Handlers") { 849af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar layoutBinder.sortedTargets.filter { it.isUsed }.forEach { target -> 850af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar target.inverseBindings.forEach { inverseBinding -> 851d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount val className : String 852d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount val param : String 853af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar if (inverseBinding.isOnBinder) { 854d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount className = "android.databinding.ViewDataBinding.PropertyChangedInverseListener" 855d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount param = "BR.${inverseBinding.eventAttribute}" 856d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } else { 857d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount className = "android.databinding.InverseBindingListener" 858d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount param = "" 859d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 860bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount block("private $className ${inverseBinding.fieldName} = new $className($param)") { 861bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount nl("@Override") 862bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount block("public void onChange()") { 863bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount if (inverseBinding.inverseExpr != null) { 864bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount val valueExpr = inverseBinding.variableExpr 865bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount val getterCall = inverseBinding.getterCall 866bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount nl("// Inverse of ${inverseBinding.expr}") 867bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount nl("// is ${inverseBinding.inverseExpr}") 868bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount nl("${valueExpr.resolvedType.toJavaCode()} ${valueExpr.name} = ${getterCall.toJava("mBindingComponent", target.fieldName)};") 869bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount nl(inverseBinding.callbackExprModel.localizeGlobalVariables(valueExpr)) 870bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount nl(inverseBinding.executionPath.toCode()) 871bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount } else { 872bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount block("synchronized(this)") { 873bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount val flagSet = inverseBinding.chainedExpressions.fold(FlagSet(), { initial, expr -> 874bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount initial.or(FlagSet(expr.id)) 875bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount }) 876bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount mDirtyFlags.mapOr(flagSet) { suffix, index -> 877bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount tab("${mDirtyFlags.localValue(index)} |= ${flagSet.binaryCode(index)};") 878bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount } 879bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount } 880bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount nl("requestRebind();") 881bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount } 882d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 883bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount }.app(";") 884d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 885d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 886d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 887d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareDirtyFlags() = kcode("// dirty flag") { 888d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.ext.localizedFlags.forEach { flag -> 889de38dd3ef0577d25b2d59863603abe5750d0c231George Mount flag.notEmpty { suffix, value -> 8900fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private") 89159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar app(" ", if(flag.isDynamic) null else "static final"); 89259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar app(" ", " ${flag.type} ${flag.localName}$suffix = ${longToBinary(value)};") 893d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 894d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 895d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 896d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 897d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun flagMapping() = kcode("/* flag mapping") { 89859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (model.flagMapping != null) { 89959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val mapping = model.flagMapping 900d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in mapping.indices) { 901f58c3bd412f9bdc5ec589fdcfed470889abb6ea6Yigit Boyar tab("flag $i (${longToBinary(1L + i)}): ${model.findFlagExpression(i)}") 902d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 903d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 904d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nl("flag mapping end*/") 905d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 906d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 9074c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun executePendingBindings() = kcode("") { 9080fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("@Override") 9096047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("protected void executeBindings()") { 910d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val tmpDirtyFlags = FlagSet(mDirtyFlags.buckets) 91159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tmpDirtyFlags.localName = "dirtyFlags"; 91259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar for (i in (0..mDirtyFlags.buckets.size - 1)) { 9136047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("${tmpDirtyFlags.type} ${tmpDirtyFlags.localValue(i)} = 0;") 914d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 9156047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("synchronized(this)") { 91659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar for (i in (0..mDirtyFlags.buckets.size - 1)) { 9176047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("${tmpDirtyFlags.localValue(i)} = ${mDirtyFlags.localValue(i)};") 9186047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("${mDirtyFlags.localValue(i)} = 0;") 9191c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 9206047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 92159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar model.pendingExpressions.filter { it.needsLocalField }.forEach { 9226047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("${it.resolvedType.toJavaCode()} ${it.executePendingLocalName} = ${if (it.isVariable()) it.fieldName else it.defaultValue};") 923d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 924b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("writing executePendingBindings for %s", className) 925d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar do { 9266047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar val batch = ExprModel.filterShouldRead(model.pendingExpressions) 927a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val justRead = arrayListOf<Expr>() 928b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("batch: %s", batch) 929d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar while (!batch.none()) { 930a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val readNow = batch.filter { it.shouldReadNow(justRead) } 931d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (readNow.isEmpty()) { 932d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar throw IllegalStateException("do not know what I can read. bailing out ${batch.joinToString("\n")}") 933d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 93459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar L.d("new read now. batch size: %d, readNow size: %d", batch.size, readNow.size) 935a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount nl(readWithDependants(readNow, justRead, batch, tmpDirtyFlags)) 936a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount batch.removeAll(justRead) 937d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 9386047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("// batch finished") 939a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } while (model.markBitsRead()) 9407b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar // verify everything is read. 9416047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar val batch = ExprModel.filterShouldRead(model.pendingExpressions) 9427b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar if (batch.isNotEmpty()) { 9437b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar L.e("could not generate code for %s. This might be caused by circular dependencies." 94459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar + "Please report on b.android.com. %d %s %s", layoutBinder.layoutname, 94559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar batch.size, batch[0], batch[0].toCode().generate()) 9467b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar } 947d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // 94859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.sortedTargets.filter { it.isUsed } 94959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar .flatMap { it.bindings } 950a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount .groupBy { 95159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar "${tmpDirtyFlags.mapOr(it.expr.dirtyFlagSet) { suffix, index -> 95259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${it.expr.dirtyFlagSet.localValue(index)}) != 0" 953a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount }.joinToString(" || ") }" 954a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount }.forEach { 9556047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("if (${it.key})") { 95659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.value.groupBy { Math.max(1, it.minApi) }.forEach { 957a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val setterValues = kcode("") { 958d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.value.forEach { binding -> 9596047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(binding.toAssignmentCode()).app(";") 960a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 961a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 9626047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("// api target ${it.key}") 963a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount if (it.key > 1) { 9646047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("if(getBuildSdkInt() >= ${it.key})") { 9656047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(setterValues) 966d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 967a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } else { 9686047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(setterValues) 96920c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 97020c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 971a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 972a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 973a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount 97420c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 97559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.sortedTargets.filter { it.isUsed } 97659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar .flatMap { it.bindings } 97720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .filter { it.requiresOldValue() } 97859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar .groupBy {"${tmpDirtyFlags.mapOr(it.expr.dirtyFlagSet) { suffix, index -> 97959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${it.expr.dirtyFlagSet.localValue(index)}) != 0" 980a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount }.joinToString(" || ") 981a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount }"}.forEach { 9826047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("if (${it.key})") { 98359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.value.groupBy { it.expr }.map { it.value.first() }.forEach { 98459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.componentExpressions.forEach { expr -> 9856047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("this.${expr.oldValueName} = ${expr.toCode().generate()};") 986d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 987d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 988a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 989a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 99059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar includedBinders.filter{it.isUsed }.forEach { binder -> 9916047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("${binder.fieldName}.executePendingBindings();") 9927551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 99359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.sortedTargets.filter{ 99459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.isUsed && it.resolvedType != null && it.resolvedType.extendsViewStub() 995de38dd3ef0577d25b2d59863603abe5750d0c231George Mount }.forEach { 9966047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("if (${it.fieldName}.getBinding() != null)") { 9976047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("${it.fieldName}.getBinding().executePendingBindings();") 998de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 999de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 1000d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 1001d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 1002d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 1003a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount fun readWithDependants(expressionList: List<Expr>, justRead: MutableList<Expr>, 1004a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount batch: MutableList<Expr>, tmpDirtyFlags: FlagSet, 1005a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount inheritedFlags: FlagSet? = null) : KCode = kcode("") { 1006a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount expressionList.groupBy { it.shouldReadFlagSet }.forEach { 1007a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val flagSet = it.key 1008a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val needsIfWrapper = inheritedFlags == null || !flagSet.bitsEqual(inheritedFlags) 1009a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val expressions = it.value 1010a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val ifClause = "if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 1011a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 1012a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount }.joinToString(" || ") 1013a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount })" 1014a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val readCode = kcode("") { 1015a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val dependants = ArrayList<Expr>() 1016a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount expressions.groupBy { condition(it) }.forEach { 1017a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val condition = it.key 10180b6d118e6eeb3bc100fc6a6e66016ab812cb2783Yigit Boyar val assignedValues = it.value.filter { it.needsLocalField && !it.isVariable() } 1019a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount if (!assignedValues.isEmpty()) { 1020a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val assignment = kcode("") { 1021a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount assignedValues.forEach { expr: Expr -> 1022bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount tab("// read ${expr}") 1023a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount tab("${expr.executePendingLocalName}").app(" = ", expr.toFullCode()).app(";") 1024a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 1025a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 1026a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount if (condition != null) { 102759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("if ($condition) {") { 1028a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount app("", assignment) 1029a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 1030a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount tab ("}") 1031a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } else { 1032a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount app("", assignment) 1033d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 103459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.value.filter { it.isObservable }.forEach { expr: Expr -> 103559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("updateRegistration(${expr.id}, ${expr.executePendingLocalName});") 10369e7a4ce47ae5f4428f7630fe03a7ad66d06177fbGeorge Mount } 1037a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 1038a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount 1039a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount it.value.forEach { expr: Expr -> 1040a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount justRead.add(expr) 1041bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount L.d("%s / readWithDependants %s", className, expr); 1042a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount L.d("flag set:%s . inherited flags: %s. need another if: %s", flagSet, inheritedFlags, needsIfWrapper); 1043a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount 1044a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount // if I am the condition for an expression, set its flag 104559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar expr.dependants.filter { 104659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar !it.isConditional && it.dependant is TernaryExpr && 104759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar (it.dependant as TernaryExpr).pred == expr 104859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar }.map { it.dependant }.groupBy { 1049eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar // group by when those ternaries will be evaluated (e.g. don't set conditional flags for no reason) 105059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val ternaryBitSet = it.shouldReadFlagsWithConditionals 105159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val isBehindTernary = ternaryBitSet.nextSetBit(model.invalidateAnyFlagIndex) == -1 1052eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar if (!isBehindTernary) { 1053eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar val ternaryFlags = it.shouldReadWithConditionalsFlagSet 1054eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar "if(${tmpDirtyFlags.mapOr(ternaryFlags){ suffix, index -> 1055eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${ternaryFlags.localValue(index)}) != 0" 1056eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar }.joinToString(" || ")}) {" 1057eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } else { 1058eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar // TODO if it is behind a ternary, we should set it when its predicate is elevated 1059eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar // Normally, this would mean that there is another code path to re-read our current expression. 1060eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar // Unfortunately, this may not be true due to the coverage detection in `expr#markAsReadIfDone`, this may never happen. 1061eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar // for v1.0, we'll go with always setting it and suffering an unnecessary calculation for this edge case. 1062eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar // we can solve this by listening to elevation events from the model. 1063eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar "" 1064a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 1065eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar }.forEach { 1066eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar val hasAnotherIf = it.key != "" 1067eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar if (hasAnotherIf) { 1068eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar tab(it.key) { 1069eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar tab("if (${expr.executePendingLocalName}) {") { 1070eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar it.value.forEach { 1071eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar val set = it.getRequirementFlagSet(true) 1072eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar mDirtyFlags.mapOr(set) { suffix, index -> 1073eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 1074eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } 1075eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } 1076eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } 1077eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar tab("} else {") { 1078eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar it.value.forEach { 1079eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar val set = it.getRequirementFlagSet(false) 1080eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar mDirtyFlags.mapOr(set) { suffix, index -> 1081eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 1082eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } 1083eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } 1084eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar }.tab("}") 1085eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar }.app("}") 1086eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } else { 1087eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar tab("if (${expr.executePendingLocalName}) {") { 1088eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar it.value.forEach { 1089eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar val set = it.getRequirementFlagSet(true) 1090eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar mDirtyFlags.mapOr(set) { suffix, index -> 1091eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 1092eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } 1093a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 1094a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 1095eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar tab("} else {") { 1096eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar it.value.forEach { 1097eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar val set = it.getRequirementFlagSet(false) 1098eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar mDirtyFlags.mapOr(set) { suffix, index -> 1099eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 1100eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } 1101eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } 1102eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } app("}") 1103a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 1104a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 110559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val chosen = expr.dependants.filter { 110659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val dependant = it.dependant 1107a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount batch.contains(dependant) && 110859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar dependant.shouldReadFlagSet.andNot(flagSet).isEmpty && 1109a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount dependant.shouldReadNow(justRead) 1110a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 1111a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount if (chosen.isNotEmpty()) { 111259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar dependants.addAll(chosen.map { it.dependant }) 11130fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 11140fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 1115a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 1116a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount if (dependants.isNotEmpty()) { 1117a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val nextInheritedFlags = if (needsIfWrapper) flagSet else inheritedFlags 1118a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount nl(readWithDependants(dependants, justRead, batch, tmpDirtyFlags, nextInheritedFlags)) 1119a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 1120d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 11210fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar 1122a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount if (needsIfWrapper) { 11236047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block(ifClause) { 11246047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(readCode) 1125d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 1126a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } else { 11276047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl(readCode) 1128d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 1129d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 1130a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 1131a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount 1132a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount fun condition(expr : Expr) : String? { 1133a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount if (expr.canBeEvaluatedToAVariable() && !expr.isVariable()) { 1134a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount // create an if case for all dependencies that might be null 113559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val nullables = expr.dependencies.filter { 113659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.isMandatory && it.other.resolvedType.isNullable 113759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar }.map { it.other } 113859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (!expr.isEqualityCheck && nullables.isNotEmpty()) { 1139a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount return "${nullables.map { "${it.executePendingLocalName} != null" }.joinToString(" && ")}" 1140a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } else { 1141a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount return null 1142d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 1143d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } else { 1144a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount return null 1145d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 1146d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 1147716ba89e7f459f49ea85070d4710c1d79d715298George Mount 1148716ba89e7f459f49ea85070d4710c1d79d715298George Mount fun declareListenerImpls() = kcode("// Listener Stub Implementations") { 114959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar model.exprMap.values.filter { 115059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.isUsed && it is ListenerExpr 1151716ba89e7f459f49ea85070d4710c1d79d715298George Mount }.groupBy { it }.forEach { 1152793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount val expr = it.key as ListenerExpr 115359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val listenerType = expr.resolvedType; 1154793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount val extendsImplements : String 115559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (listenerType.isInterface) { 1156793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount extendsImplements = "implements" 1157793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } else { 1158793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount extendsImplements = "extends" 1159793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } 116059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public static class ${expr.listenerClassName} $extendsImplements ${listenerType.canonicalName}{") { 1161c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount if (expr.target.isDynamic) { 1162c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount tab("private ${expr.target.resolvedType.toJavaCode()} value;") 1163c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount tab("public ${expr.listenerClassName} setValue(${expr.target.resolvedType.toJavaCode()} value) {") { 1164716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab("this.value = value;") 1165716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab("return value == null ? null : this;") 1166716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 1167716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab("}") 1168716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 116959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val listenerMethod = expr.method 117059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val parameterTypes = listenerMethod.parameterTypes 11716047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar val returnType = listenerMethod.getReturnType(parameterTypes.toList()) 1172793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount tab("@Override") 117359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public $returnType ${listenerMethod.name}(${ 1174716ba89e7f459f49ea85070d4710c1d79d715298George Mount parameterTypes.withIndex().map { 1175716ba89e7f459f49ea85070d4710c1d79d715298George Mount "${it.value.toJavaCode()} arg${it.index}" 1176716ba89e7f459f49ea85070d4710c1d79d715298George Mount }.joinToString(", ") 1177793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount }) {") { 1178793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount val obj : String 1179c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount if (expr.target.isDynamic) { 1180793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount obj = "this.value" 1181793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } else { 1182c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount obj = expr.target.toCode().generate(); 1183793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } 1184793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount val returnStr : String 118559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (!returnType.isVoid) { 1186793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount returnStr = "return " 1187793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } else { 1188793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount returnStr = "" 1189716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 1190793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount val args = parameterTypes.withIndex().map { 1191793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount "arg${it.index}" 1192793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount }.joinToString(", ") 119359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("$returnStr$obj.${expr.name}($args);") 1194716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 1195793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount tab("}") 1196716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 1197716ba89e7f459f49ea85070d4710c1d79d715298George Mount nl("}") 1198716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 1199716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 120043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 1201dea555cf42dc3583604699c8c018d22681f56166George Mount fun declareFactories() = kcode("") { 12026047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot)") { 12036047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("return inflate(inflater, root, attachToRoot, android.databinding.DataBindingUtil.getDefaultComponent());") 1204e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 12056047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot, android.databinding.DataBindingComponent bindingComponent)") { 12066047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("return android.databinding.DataBindingUtil.<$baseClassName>inflate(inflater, ${layoutBinder.modulePackage}.R.layout.${layoutBinder.layoutname}, root, attachToRoot, bindingComponent);") 1207081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount } 120859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (!layoutBinder.isMerge) { 12096047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("public static $baseClassName inflate(android.view.LayoutInflater inflater)") { 12106047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("return inflate(inflater, android.databinding.DataBindingUtil.getDefaultComponent());") 1211e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 12126047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.databinding.DataBindingComponent bindingComponent)") { 12136047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("return bind(inflater.inflate(${layoutBinder.modulePackage}.R.layout.${layoutBinder.layoutname}, null, false), bindingComponent);") 121496e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 12156047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("public static $baseClassName bind(android.view.View view)") { 12166047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("return bind(view, android.databinding.DataBindingUtil.getDefaultComponent());") 1217e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 12186047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("public static $baseClassName bind(android.view.View view, android.databinding.DataBindingComponent bindingComponent)") { 12196047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar block("if (!\"${layoutBinder.tag}_0\".equals(view.getTag()))") { 12206047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("throw new RuntimeException(\"view tag isn't correct on view:\" + view.getTag());") 122196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 12226047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar nl("return new $baseClassName(bindingComponent, view);") 122396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 1224dea555cf42dc3583604699c8c018d22681f56166George Mount } 1225dea555cf42dc3583604699c8c018d22681f56166George Mount } 1226dea555cf42dc3583604699c8c018d22681f56166George Mount 12278b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar /** 12288b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar * When called for a library compilation, we do not generate real implementations 12298b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar */ 12308b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar public fun writeBaseClass(forLibrary : Boolean) : String = 123159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar kcode("package ${layoutBinder.`package`};") { 12326047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar Scope.reset() 1233fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.Bindable;") 1234fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.DataBindingUtil;") 1235fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.ViewDataBinding;") 123659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public abstract class $baseClassName extends ViewDataBinding {") 123759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.sortedTargets.filter{it.id != null}.forEach { 123859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public final ${it.interfaceClass} ${it.fieldName};") 123934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 124034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 124159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("protected $baseClassName(android.databinding.DataBindingComponent bindingComponent, android.view.View root_, int localFieldCount") { 124259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.sortedTargets.filter{it.id != null}.forEach { 124359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab(", ${it.interfaceClass} ${it.constructorParamName}") 124434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 124534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 124634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab(") {") { 1247e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("super(bindingComponent, root_, localFieldCount);") 124859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.sortedTargets.filter{it.id != null}.forEach { 1249019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("this.${it.fieldName} = ${it.constructorParamName};") 125034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 12514c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 12524c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 12534c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("") 125443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar variables.forEach { 125559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (it.userDefinedType != null) { 125659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val type = ModelAnalyzer.getInstance().applyImports(it.userDefinedType, model.imports) 125759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public abstract void ${it.setterName}($type ${it.readableName});") 125818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 125943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 126059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot) {") { 1261e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return inflate(inflater, root, attachToRoot, android.databinding.DataBindingUtil.getDefaultComponent());") 1262e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1263e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("}") 126459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public static $baseClassName inflate(android.view.LayoutInflater inflater) {") { 1265e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return inflate(inflater, android.databinding.DataBindingUtil.getDefaultComponent());") 1266e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1267e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("}") 126859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public static $baseClassName bind(android.view.View view) {") { 12698b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar if (forLibrary) { 12708b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar tab("return null;") 12718b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar } else { 1272e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return bind(view, android.databinding.DataBindingUtil.getDefaultComponent());") 12738b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar } 127443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 12754c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 127659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot, android.databinding.DataBindingComponent bindingComponent) {") { 12778b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar if (forLibrary) { 12788b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar tab("return null;") 12798b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar } else { 128059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("return DataBindingUtil.<$baseClassName>inflate(inflater, ${layoutBinder.modulePackage}.R.layout.${layoutBinder.layoutname}, root, attachToRoot, bindingComponent);") 12818b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar } 12824c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 12834c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 128459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.databinding.DataBindingComponent bindingComponent) {") { 1285e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount if (forLibrary) { 1286e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return null;") 1287e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } else { 128859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("return DataBindingUtil.<$baseClassName>inflate(inflater, ${layoutBinder.modulePackage}.R.layout.${layoutBinder.layoutname}, null, false, bindingComponent);") 1289e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1290e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1291e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("}") 129259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public static $baseClassName bind(android.view.View view, android.databinding.DataBindingComponent bindingComponent) {") { 12938b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar if (forLibrary) { 12948b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar tab("return null;") 12958b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar } else { 129659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("return ($baseClassName)bind(bindingComponent, view, ${layoutBinder.modulePackage}.R.layout.${layoutBinder.layoutname});") 12978b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar } 12984c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 12994c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 130043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar nl("}") 130143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.generate() 1302dea555cf42dc3583604699c8c018d22681f56166George Mount} 1303