LayoutBinderWriter.kt revision e4cd38824a6627b9fef229c549c636e35ad63b5f
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 16e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarimport android.databinding.tool.BindingTarget 17716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport android.databinding.tool.LayoutBinder 18fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.Expr 19fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ExprModel 20fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.FieldAccessExpr 21716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport android.databinding.tool.expr.IdentifierExpr 22716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport android.databinding.tool.expr.TernaryExpr 237b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarimport android.databinding.tool.ext.androidId 247b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarimport android.databinding.tool.ext.br 257b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarimport android.databinding.tool.ext.joinToCamelCaseAsVar 26716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport android.databinding.tool.ext.lazy 27716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport android.databinding.tool.ext.versionedLazy 28fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelAnalyzer 297b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarimport android.databinding.tool.util.L 3096e1c821dd446d1ed78f8ae61131550588f60a24George Mountimport java.util.ArrayList 31716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport java.util.Arrays 32716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport java.util.BitSet 3334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport java.util.HashMap 34716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport java.util.HashSet 35716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport kotlin.properties.Delegates 3643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 37fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyarfun String.stripNonJava() = this.split("[^a-zA-Z0-9]".toRegex()).map{ it.trim() }.joinToCamelCaseAsVar() 38d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 39019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarenum class Scope { 40fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar FIELD, 41fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar METHOD, 42fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar FLAG, 43fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar EXECUTE_PENDING_METHOD, 44019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar CONSTRUCTOR_PARAM 45019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar} 46019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar 47d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarclass ExprModelExt { 48019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val usedFieldNames = hashMapOf<Scope, MutableSet<String>>(); 49fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar init { 50019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Scope.values().forEach { usedFieldNames[it] = hashSetOf<String>() } 51019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar } 52d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val localizedFlags = arrayListOf<FlagSet>() 53d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 54d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun localizeFlag(set : FlagSet, name:String) : FlagSet { 55d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar localizedFlags.add(set) 56019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val result = getUniqueName(name, Scope.FLAG) 57d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar set.setLocalName(result) 58d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return set 59d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 60d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 61019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar fun getUniqueName(base : String, scope : Scope) : String { 62d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var candidate = base 63d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var i = 0 64019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar while (usedFieldNames[scope].contains(candidate)) { 65d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar i ++ 66d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar candidate = base + i 67d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 68019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar usedFieldNames[scope].add(candidate) 69d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return candidate 70d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 71d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 72d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 73de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval ExprModel.ext by Delegates.lazy { target : ExprModel -> 74d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar ExprModelExt() 75d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 76d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 77019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getUniqueFieldName(base : String) : String = ext.getUniqueName(base, Scope.FIELD) 78019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getUniqueMethodName(base : String) : String = ext.getUniqueName(base, Scope.METHOD) 79019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getUniqueFlagName(base : String) : String = ext.getUniqueName(base, Scope.FLAG) 80019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getConstructorParamName(base : String) : String = ext.getUniqueName(base, Scope.CONSTRUCTOR_PARAM) 81d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 82d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun ExprModel.localizeFlag(set : FlagSet, base : String) : FlagSet = ext.localizeFlag(set, base) 83d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 84019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar// not necessarily unique. Uniqueness is solved per scope 85019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval BindingTarget.readableName by Delegates.lazy { target: BindingTarget -> 8600da715547ee7d5d38a3b8576090ca427a94daa5George Mount if (target.getId() == null) { 87019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar "boundView" + indexFromTag(target.getTag()) 8800da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 89019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar target.getId().androidId().stripNonJava() 9000da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 91d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 927551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 93de38dd3ef0577d25b2d59863603abe5750d0c231George Mountfun BindingTarget.superConversion(variable : String) : String { 9496e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (getResolvedType() != null && getResolvedType().extendsViewStub()) { 95de38dd3ef0577d25b2d59863603abe5750d0c231George Mount return "new android.databinding.ViewStubProxy((android.view.ViewStub) ${variable})" 96de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } else { 97de38dd3ef0577d25b2d59863603abe5750d0c231George Mount return "(${interfaceType}) ${variable}" 98de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 99de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 100de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 101019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval BindingTarget.fieldName : String by Delegates.lazy { target : BindingTarget -> 102019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val name : String 103019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar if (target.getId() == null) { 104019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar name = "m${target.readableName}" 105019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar } else { 106019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar name = target.readableName 10734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 108019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar target.getModel().getUniqueFieldName(name) 109d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 110d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 111de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.androidId by Delegates.lazy { target : BindingTarget -> 112fdfbbcd5ecf37d77a4b9ab1cefdebd68de71ca2bGeorge Mount if (target.getId().startsWith("@android:id/")) { 113fdfbbcd5ecf37d77a4b9ab1cefdebd68de71ca2bGeorge Mount "android.R.id.${target.getId().androidId()}" 114fdfbbcd5ecf37d77a4b9ab1cefdebd68de71ca2bGeorge Mount } else { 115fdfbbcd5ecf37d77a4b9ab1cefdebd68de71ca2bGeorge Mount "R.id.${target.getId().androidId()}" 116fdfbbcd5ecf37d77a4b9ab1cefdebd68de71ca2bGeorge Mount } 117d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 118d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 119de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.interfaceType by Delegates.lazy { target : BindingTarget -> 120de38dd3ef0577d25b2d59863603abe5750d0c231George Mount if (target.getResolvedType() != null && target.getResolvedType().extendsViewStub()) { 121de38dd3ef0577d25b2d59863603abe5750d0c231George Mount "android.databinding.ViewStubProxy" 122de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } else { 123de38dd3ef0577d25b2d59863603abe5750d0c231George Mount target.getInterfaceType() 124de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 125de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 126de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 127019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval BindingTarget.constructorParamName by Delegates.lazy { target : BindingTarget -> 128019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar target.getModel().getConstructorParamName(target.readableName) 129d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 130d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 131019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar// not necessarily unique. Uniqueness is decided per scope 132de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.readableName by Delegates.lazy { expr : Expr -> 133019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val stripped = "${expr.getUniqueKey().stripNonJava()}" 134b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("readableUniqueName for [%s] %s is %s", System.identityHashCode(expr), expr.getUniqueKey(), stripped) 135019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar stripped 136de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 137de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 138de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.fieldName by Delegates.lazy { expr : Expr -> 139019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueFieldName("m${expr.readableName.capitalize()}") 140d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 141d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 142716ba89e7f459f49ea85070d4710c1d79d715298George Mountval Expr.listenerClassName by Delegates.lazy { expr : Expr -> 143716ba89e7f459f49ea85070d4710c1d79d715298George Mount expr.getModel().getUniqueFieldName("${expr.readableName.capitalize()}Impl") 144716ba89e7f459f49ea85070d4710c1d79d715298George Mount} 145716ba89e7f459f49ea85070d4710c1d79d715298George Mount 14620c7182163d99575d382e065f5a5fe45ed6b87e2George Mountval Expr.oldValueName by Delegates.lazy { expr : Expr -> 14720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount expr.getModel().getUniqueFieldName("mOld${expr.readableName.capitalize()}") 14820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount} 14920c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 150019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval Expr.executePendingLocalName by Delegates.lazy { expr : Expr -> 1514a81aabc49f6c881d960cd541adda7de9625277aYigit Boyar "${expr.getModel().ext.getUniqueName(expr.readableName, Scope.EXECUTE_PENDING_METHOD)}" 152d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 153d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 154de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.setterName by Delegates.lazy { expr : Expr -> 155019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueMethodName("set${expr.readableName.capitalize()}") 156d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 157d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 158de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.onChangeName by Delegates.lazy { expr : Expr -> 159019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueMethodName("onChange${expr.readableName.capitalize()}") 160d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 161d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 162de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.getterName by Delegates.lazy { expr : Expr -> 163019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueMethodName("get${expr.readableName.capitalize()}") 164d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 165d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 166de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.dirtyFlagName by Delegates.lazy { expr : Expr -> 167019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueFlagName("sFlag${expr.readableName.capitalize()}") 168d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 169d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 170d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 171e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarfun Expr.toCode(full : Boolean = false) : KCode = CodeGenUtil.toCode(this, full) 172d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 173d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.isVariable() = this is IdentifierExpr && this.isDynamic() 174d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 175d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.conditionalFlagName(output : Boolean, suffix : String) = "${dirtyFlagName}_${output}$suffix" 176d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 177de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.dirtyFlagSet by Delegates.lazy { expr : Expr -> 178d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getInvalidFlags(), expr.getModel().getFlagBucketCount()) 179d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 180d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 181de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.invalidateFlagSet by Delegates.lazy { expr : Expr -> 182d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getId()) 183d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 184d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 1857b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarval Expr.shouldReadFlagSet by Delegates.versionedLazy { expr : Expr -> 186d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getShouldReadFlags(), expr.getModel().getFlagBucketCount()) 187d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 188d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 189de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.conditionalFlags by Delegates.lazy { expr : Expr -> 190d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar arrayListOf(FlagSet(expr.getRequirementFlagIndex(false)), 191d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getRequirementFlagIndex(true))) 192d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 193d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 194e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mountval LayoutBinder.requiredComponent by Delegates.lazy { layoutBinder: LayoutBinder -> 195e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount val required = layoutBinder. 196e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount getBindingTargets(). 197e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount flatMap { it.getBindings() }. 198e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount firstOrNull { it.getBindingAdapterInstanceClass() != null } 199e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount required?.getBindingAdapterInstanceClass() 200e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount} 201e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 202d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.getRequirementFlagSet(expected : Boolean) : FlagSet = conditionalFlags[if(expected) 1 else 0] 203d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 204d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.notEmpty(cb : (suffix : String, value : Long) -> Unit) { 205d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar buckets.withIndex().forEach { 206d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (it.value != 0L) { 207d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar cb(getWordSuffix(it.index), buckets[it.index]) 208d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 209d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 210d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 211d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 212d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.getWordSuffix(wordIndex : Int) : String { 213d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return if(wordIndex == 0) "" else "_${wordIndex}" 214d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 215d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 216d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.localValue(bucketIndex : Int) = 217d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar if (getLocalName() == null) binaryCode(bucketIndex) 218d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar else "${getLocalName()}${getWordSuffix(bucketIndex)}" 219d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 220d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyarfun FlagSet.binaryCode(bucketIndex : Int) = longToBinary(buckets[bucketIndex]) 221d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 222d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 223d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyarfun longToBinary(l : Long) = 224d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar "0b${java.lang.Long.toBinaryString(l)}L" 225d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 226d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun <T> FlagSet.mapOr(other : FlagSet, cb : (suffix : String, index : Int) -> T) : List<T> { 227d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val min = Math.min(buckets.size(), other.buckets.size()) 228d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val result = arrayListOf<T>() 229d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in 0..(min - 1)) { 230d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // if these two can match by any chance, call the callback 231d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (intersect(other, i)) { 232d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar result.add(cb(getWordSuffix(i), i)) 233d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 234d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 235d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return result 236d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 237d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 23896e1c821dd446d1ed78f8ae61131550588f60a24George Mountfun indexFromTag(tag : String) : kotlin.Int { 23996e1c821dd446d1ed78f8ae61131550588f60a24George Mount val startIndex : kotlin.Int 2407ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount if (tag.startsWith("binding_")) { 2417ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount startIndex = "binding_".length(); 24296e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 24396e1c821dd446d1ed78f8ae61131550588f60a24George Mount startIndex = tag.lastIndexOf('_') + 1 24496e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 24596e1c821dd446d1ed78f8ae61131550588f60a24George Mount return Integer.parseInt(tag.substring(startIndex)) 24696e1c821dd446d1ed78f8ae61131550588f60a24George Mount} 24796e1c821dd446d1ed78f8ae61131550588f60a24George Mount 24843596c2b2997e40b709627419732100d78a62ff0Yigit Boyarclass LayoutBinderWriter(val layoutBinder : LayoutBinder) { 249d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val model = layoutBinder.getModel() 25034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val indices = HashMap<BindingTarget, kotlin.Int>() 25143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val mDirtyFlags by Delegates.lazy { 25243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val fs = FlagSet(BitSet(), model.getFlagBucketCount()); 25343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Arrays.fill(fs.buckets, -1) 25443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs.setDynamic(true) 25543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.localizeFlag(fs, "mDirtyFlags") 25643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs 257d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 258d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 25943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val dynamics by Delegates.lazy { model.getExprMap().values().filter { it.isDynamic() } } 260dea555cf42dc3583604699c8c018d22681f56166George Mount val className = layoutBinder.getImplementationName() 261d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 262dea555cf42dc3583604699c8c018d22681f56166George Mount val baseClassName = "${layoutBinder.getClassName()}" 263d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 2647551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar val includedBinders by Delegates.lazy { 2657551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar layoutBinder.getBindingTargets().filter { it.isBinder() } 2667551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 2677551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 26843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val variables by Delegates.lazy { 26943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.getExprMap().values().filterIsInstance(javaClass<IdentifierExpr>()).filter { it.isVariable() } 27043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 271d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 2725bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar val usedVariables by Delegates.lazy { 2735bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar variables.filter {it.isUsed()} 2745bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 275d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 27696e1c821dd446d1ed78f8ae61131550588f60a24George Mount public fun write(minSdk : kotlin.Int) : String { 2775bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar layoutBinder.resolveWhichExpressionsAreUsed() 27834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount calculateIndices(); 2795bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar return kcode("package ${layoutBinder.getPackage()};") { 280a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar nl("import ${layoutBinder.getModulePackage()}.R;") 281a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar nl("import ${layoutBinder.getModulePackage()}.BR;") 2825bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("import android.view.View;") 283dea555cf42dc3583604699c8c018d22681f56166George Mount val classDeclaration : String 284dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 285dea555cf42dc3583604699c8c018d22681f56166George Mount classDeclaration = "${className} extends ${baseClassName}" 286dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 287dea555cf42dc3583604699c8c018d22681f56166George Mount classDeclaration = "${className} extends android.databinding.ViewDataBinding" 288dea555cf42dc3583604699c8c018d22681f56166George Mount } 289dea555cf42dc3583604699c8c018d22681f56166George Mount nl("public class ${classDeclaration} {") { 2904c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(declareIncludeViews()) 2915bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareViews()) 2925bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareVariables()) 29320c7182163d99575d382e065f5a5fe45ed6b87e2George Mount tab(declareBoundValues()) 294716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab(declareListeners()) 29596e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab(declareConstructor(minSdk)) 2965bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareInvalidateAll()) 297447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab(declareHasPendingBindings()) 2985bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareLog()) 2995bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareSetVariable()) 3005bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(variableSettersAndGetters()) 3015bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(onFieldChange()) 3025bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 3034c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(executePendingBindings()) 3045bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 305716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab(declareListenerImpls()) 3065bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareDirtyFlags()) 307dea555cf42dc3583604699c8c018d22681f56166George Mount if (!layoutBinder.hasVariations()) { 308dea555cf42dc3583604699c8c018d22681f56166George Mount tab(declareFactories()) 309dea555cf42dc3583604699c8c018d22681f56166George Mount } 3105bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 3115bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 3125bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(flagMapping()) 3135bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("//end") 3145bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar }.generate() 3155bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 31634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fun calculateIndices() : Unit { 31796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val taggedViews = layoutBinder.getBindingTargets().filter{ 318d6527ee28cc3aa05818799af8def9593346f91bcGeorge Mount it.isUsed() && it.getTag() != null && !it.isBinder() 31934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 32096e1c821dd446d1ed78f8ae61131550588f60a24George Mount taggedViews.forEach { 32196e1c821dd446d1ed78f8ae61131550588f60a24George Mount indices.put(it, indexFromTag(it.getTag())) 32296e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 32396e1c821dd446d1ed78f8ae61131550588f60a24George Mount val indexStart = maxIndex() + 1 32496e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getBindingTargets().filter{ 32596e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !taggedViews.contains(it) 32696e1c821dd446d1ed78f8ae61131550588f60a24George Mount }.withIndex().forEach { 32796e1c821dd446d1ed78f8ae61131550588f60a24George Mount indices.put(it.value, it.index + indexStart) 32834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 32934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 3304c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun declareIncludeViews() = kcode("") { 331239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount nl("private static final android.databinding.ViewDataBinding.IncludedLayouts sIncludes;") 3324c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("private static final android.util.SparseIntArray sViewsWithIds;") 3334c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("static {") { 3344c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount val hasBinders = layoutBinder.getBindingTargets().firstOrNull{ it.isUsed() && it.isBinder()} != null 3354c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount if (!hasBinders) { 3364c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sIncludes = null;") 33700da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 33896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val numBindings = layoutBinder.getBindingTargets().filter{ it.isUsed() }.count() 339239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount tab("sIncludes = new android.databinding.ViewDataBinding.IncludedLayouts(${numBindings});") 34096e1c821dd446d1ed78f8ae61131550588f60a24George Mount val includeMap = HashMap<BindingTarget, ArrayList<BindingTarget>>() 34196e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getBindingTargets().filter{ it.isUsed() && it.isBinder() }.forEach { 34296e1c821dd446d1ed78f8ae61131550588f60a24George Mount val includeTag = it.getTag(); 34396e1c821dd446d1ed78f8ae61131550588f60a24George Mount val parent = layoutBinder.getBindingTargets().firstOrNull { 34496e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !it.isBinder() && includeTag.equals(it.getTag()) 34596e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 34696e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (parent == null) { 34796e1c821dd446d1ed78f8ae61131550588f60a24George Mount throw IllegalStateException("Could not find parent of include file") 34896e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 34996e1c821dd446d1ed78f8ae61131550588f60a24George Mount var list = includeMap.get(parent) 35096e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (list == null) { 35196e1c821dd446d1ed78f8ae61131550588f60a24George Mount list = ArrayList<BindingTarget>() 35296e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.put(parent, list) 35396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 35496e1c821dd446d1ed78f8ae61131550588f60a24George Mount list.add(it) 3554c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 35696e1c821dd446d1ed78f8ae61131550588f60a24George Mount 35796e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.keySet().forEach { 35896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val index = indices.get(it) 359239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount tab("sIncludes.setIncludes(${index}, ") { 360239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount tab ("new String[] {${ 361239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount includeMap.get(it).map { 362239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount "\"${it.getIncludedLayout()}\"" 363239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount }.joinToString(", ") 364239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount }},") 365239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount tab("new int[] {${ 366239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount includeMap.get(it).map { 367239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount "${indices.get(it)}" 368239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount }.joinToString(", ") 369239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount }},") 370239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount tab("new int[] {${ 371239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount includeMap.get(it).map { 372239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount "R.layout.${it.getIncludedLayout()}" 373239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount }.joinToString(", ") 374239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount }});") 37596e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 37696e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 37796e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 37896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val viewsWithIds = layoutBinder.getBindingTargets().filter { 379d6527ee28cc3aa05818799af8def9593346f91bcGeorge Mount it.isUsed() && !it.isBinder() && (!it.supportsTag() || (it.getId() != null && it.getTag() == null)) 38000da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 38196e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (viewsWithIds.isEmpty()) { 3824c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = null;") 38300da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 3844c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = new android.util.SparseIntArray();") 38596e1c821dd446d1ed78f8ae61131550588f60a24George Mount viewsWithIds.forEach { 38634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("sViewsWithIds.put(${it.androidId}, ${indices.get(it)});") 3874c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 38800da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 3894c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 3904c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("}") 3914c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 39296e1c821dd446d1ed78f8ae61131550588f60a24George Mount 39396e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun maxIndex() : kotlin.Int { 39496e1c821dd446d1ed78f8ae61131550588f60a24George Mount val maxIndex = indices.values().max() 39596e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (maxIndex == null) { 39696e1c821dd446d1ed78f8ae61131550588f60a24George Mount return -1 39796e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 39896e1c821dd446d1ed78f8ae61131550588f60a24George Mount return maxIndex 39996e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 40096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 40196e1c821dd446d1ed78f8ae61131550588f60a24George Mount 40296e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun declareConstructor(minSdk : kotlin.Int) = kcode("") { 40396e1c821dd446d1ed78f8ae61131550588f60a24George Mount val bindingCount = maxIndex() + 1 40496e1c821dd446d1ed78f8ae61131550588f60a24George Mount val parameterType : String 40596e1c821dd446d1ed78f8ae61131550588f60a24George Mount val superParam : String 40696e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (layoutBinder.isMerge()) { 40796e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View[]" 40896e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root[0]" 40996e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 41096e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View" 41196e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root" 41296e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 41396e1c821dd446d1ed78f8ae61131550588f60a24George Mount val rootTagsSupported = minSdk >= 14 414dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 415dea555cf42dc3583604699c8c018d22681f56166George Mount nl("") 416e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount nl("public ${className}(android.databinding.DataBindingComponent bindingComponent, ${parameterType} root) {") { 417e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("this(bindingComponent, ${superParam}, mapBindings(bindingComponent, root, ${bindingCount}, sIncludes, sViewsWithIds));") 418dea555cf42dc3583604699c8c018d22681f56166George Mount } 419dea555cf42dc3583604699c8c018d22681f56166George Mount nl("}") 420e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount nl("private ${className}(android.databinding.DataBindingComponent bindingComponent, ${parameterType} root, Object[] bindings) {") { 421e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("super(bindingComponent, ${superParam}, ${model.getObservables().size()}") { 42296e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter { it.getId() != null }.forEach { 423dea555cf42dc3583604699c8c018d22681f56166George Mount tab(", ${fieldConversion(it)}") 42434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 425dea555cf42dc3583604699c8c018d22681f56166George Mount tab(");") 42634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 42734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 428dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 429e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount nl("public ${baseClassName}(android.databinding.DataBindingComponent bindingComponent, ${parameterType} root) {") { 430e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("super(bindingComponent, ${superParam}, ${model.getObservables().size()});") 431e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("final Object[] bindings = mapBindings(bindingComponent, root, ${bindingCount}, sIncludes, sViewsWithIds);") 432dea555cf42dc3583604699c8c018d22681f56166George Mount } 433dea555cf42dc3583604699c8c018d22681f56166George Mount } 434e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount if (layoutBinder.requiredComponent != null) { 435e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("ensureBindingComponentIsNotNull(${layoutBinder.requiredComponent}.class);") 436e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 43796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val taggedViews = layoutBinder.getSortedTargets().filter{it.isUsed()} 438dea555cf42dc3583604699c8c018d22681f56166George Mount taggedViews.forEach { 439dea555cf42dc3583604699c8c018d22681f56166George Mount if (!layoutBinder.hasVariations() || it.getId() == null) { 440dea555cf42dc3583604699c8c018d22681f56166George Mount tab("this.${it.fieldName} = ${fieldConversion(it)};") 441dea555cf42dc3583604699c8c018d22681f56166George Mount } 442d6527ee28cc3aa05818799af8def9593346f91bcGeorge Mount if (!it.isBinder()) { 443de38dd3ef0577d25b2d59863603abe5750d0c231George Mount if (it.getResolvedType() != null && it.getResolvedType().extendsViewStub()) { 444de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("this.${it.fieldName}.setContainingBinding(this);") 445de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 44696e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (it.supportsTag() && it.getTag() != null && 4477ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount (rootTagsSupported || it.getTag().startsWith("binding_"))) { 448dea555cf42dc3583604699c8c018d22681f56166George Mount val originalTag = it.getOriginalTag(); 449dea555cf42dc3583604699c8c018d22681f56166George Mount var tagValue = "null" 450dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag != null) { 451dea555cf42dc3583604699c8c018d22681f56166George Mount tagValue = "\"${originalTag}\"" 452dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@")) { 453dea555cf42dc3583604699c8c018d22681f56166George Mount var packageName = layoutBinder.getModulePackage() 454dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@android:")) { 455dea555cf42dc3583604699c8c018d22681f56166George Mount packageName = "android" 45600da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 457dea555cf42dc3583604699c8c018d22681f56166George Mount val slashIndex = originalTag.indexOf('/') 458dea555cf42dc3583604699c8c018d22681f56166George Mount val resourceId = originalTag.substring(slashIndex + 1) 459dea555cf42dc3583604699c8c018d22681f56166George Mount tagValue = "root.getResources().getString(${packageName}.R.string.${resourceId})" 46000da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 46100da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 462dea555cf42dc3583604699c8c018d22681f56166George Mount tab("this.${it.fieldName}.setTag(${tagValue});") 4637551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 464d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 465d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 4664d4979490e1fa374c0d7f3599fed0a9e83a579d0George Mount tab("setRootTag(root);") 467dea555cf42dc3583604699c8c018d22681f56166George Mount tab("invalidateAll();"); 4680fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 469d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 470d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 471dea555cf42dc3583604699c8c018d22681f56166George Mount fun fieldConversion(target : BindingTarget) : String { 472dea555cf42dc3583604699c8c018d22681f56166George Mount if (!target.isUsed()) { 473dea555cf42dc3583604699c8c018d22681f56166George Mount return "null" 474dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 47596e1c821dd446d1ed78f8ae61131550588f60a24George Mount val index = indices.get(target) 476dea555cf42dc3583604699c8c018d22681f56166George Mount if (index == null) { 47796e1c821dd446d1ed78f8ae61131550588f60a24George Mount throw IllegalStateException("Unknown binding target") 478dea555cf42dc3583604699c8c018d22681f56166George Mount } 47996e1c821dd446d1ed78f8ae61131550588f60a24George Mount val variableName = "bindings[${index}]" 480dea555cf42dc3583604699c8c018d22681f56166George Mount return target.superConversion(variableName) 481dea555cf42dc3583604699c8c018d22681f56166George Mount } 482dea555cf42dc3583604699c8c018d22681f56166George Mount } 483dea555cf42dc3583604699c8c018d22681f56166George Mount 484d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareInvalidateAll() = kcode("") { 4857551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("@Override") 4867551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("public void invalidateAll() {") { 487019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val fs = FlagSet(layoutBinder.getModel().getInvalidateAnyBitSet(), 488019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar layoutBinder.getModel().getFlagBucketCount()); 4891c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 4901c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar for (i in (0..(mDirtyFlags.buckets.size() - 1))) { 4911c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.localValue(i)} = ${fs.localValue(i)};") 4921c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 4931c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 4945bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar includedBinders.filter{it.isUsed()}.forEach { binder -> 4957551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar tab("${binder.fieldName}.invalidateAll();") 4967551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 4972f64c44e4fa296cf658ca986c095eab62f82a31dYigit Boyar tab("requestRebind();"); 498d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 4990fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 500d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 501d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 502447971abca811b11b8c1d8e7bfaa294856d03c16George Mount fun declareHasPendingBindings() = kcode("") { 503447971abca811b11b8c1d8e7bfaa294856d03c16George Mount nl("@Override") 504447971abca811b11b8c1d8e7bfaa294856d03c16George Mount nl("public boolean hasPendingBindings() {") { 505447971abca811b11b8c1d8e7bfaa294856d03c16George Mount if (mDirtyFlags.buckets.size() > 0) { 506447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("synchronized(this) {") { 507447971abca811b11b8c1d8e7bfaa294856d03c16George Mount val flagCheck = 0.rangeTo(mDirtyFlags.buckets.size() - 1).map { 508447971abca811b11b8c1d8e7bfaa294856d03c16George Mount "${mDirtyFlags.localValue(it)} != 0" 509447971abca811b11b8c1d8e7bfaa294856d03c16George Mount }.joinToString(" || ") 510447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("if (${flagCheck}) {") { 511447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("return true;") 512447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 513447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("}") 514447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 515447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("}") 516447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 517447971abca811b11b8c1d8e7bfaa294856d03c16George Mount includedBinders.filter{it.isUsed()}.forEach { binder -> 518447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("if (${binder.fieldName}.hasPendingBindings()) {") { 519447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("return true;") 520447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 521447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("}") 522447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 523447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("return false;") 524447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 525447971abca811b11b8c1d8e7bfaa294856d03c16George Mount nl("}") 526447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 527447971abca811b11b8c1d8e7bfaa294856d03c16George Mount 528d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareSetVariable() = kcode("") { 5290fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("public boolean setVariable(int variableId, Object variable) {") { 530d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch(variableId) {") { 5315bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 53243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab ("case ${it.getName().br()} :") { 533d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${it.setterName}((${it.getResolvedType().toJavaCode()}) variable);") 534d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 535d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 536d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 537d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 538d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 539d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 540d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 5410fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 542d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 543d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 544d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareLog() = kcode("") { 5450fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private void log(String msg, long i) {") { 546d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("""android.util.Log.d("BINDER", msg + ":" + Long.toHexString(i));""") 5470fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 5480fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 549d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 550d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 551d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun variableSettersAndGetters() = kcode("") { 5525bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar variables.filterNot{it.isUsed()}.forEach { 553019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar nl("public void ${it.setterName}(${it.getResolvedType().toJavaCode()} ${it.readableName}) {") { 5545bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("// not used, ignore") 5555bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5565bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 5575bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("") 5585bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("public ${it.getResolvedType().toJavaCode()} ${it.getterName}() {") { 5595bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("return ${it.getDefaultValue()};") 5605bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5615bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 5625bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5635bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 56418243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.getUserDefinedType() != null) { 565019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar nl("public void ${it.setterName}(${it.getResolvedType().toJavaCode()} ${it.readableName}) {") { 56618243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.isObservable()) { 567019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("updateRegistration(${it.getId()}, ${it.readableName});"); 56818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 569019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("this.${it.fieldName} = ${it.readableName};") 57018243f6f1b7527272ef4feccdf4327d80d9f2241George Mount // set dirty flags! 57118243f6f1b7527272ef4feccdf4327d80d9f2241George Mount val flagSet = it.invalidateFlagSet 5721c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 5731c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 5741c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.getLocalName()}$suffix |= ${flagSet.localValue(index)};") 5751c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 5761c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab ("}") 57718243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("super.requestRebind();") 578d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 57918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 58018243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("") 58118243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("public ${it.getResolvedType().toJavaCode()} ${it.getterName}() {") { 58218243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("return ${it.fieldName};") 583d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 58418243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 585d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 586d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 587d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 588d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 589d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun onFieldChange() = kcode("") { 59034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("@Override") 59134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {") { 5924c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("switch (localFieldId) {") { 593d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getObservables().forEach { 594d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("case ${it.getId()} :") { 595d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return ${it.onChangeName}((${it.getResolvedType().toJavaCode()}) object, fieldId);") 596d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 597d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 598d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 599d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 600d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 601d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 60234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 60334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 604d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 605d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getObservables().forEach { 606019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar nl("private boolean ${it.onChangeName}(${it.getResolvedType().toJavaCode()} ${it.readableName}, int fieldId) {") { 607d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch (fieldId) {", { 608d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val accessedFields: List<FieldAccessExpr> = it.getParents().filterIsInstance(javaClass<FieldAccessExpr>()) 609c4a07bddb4dd5c3bfbecf4d87909c5b447ae56dcGeorge Mount accessedFields.filter { it.hasBindableAnnotations() } 610d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .groupBy { it.getName() } 611d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 61243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${it.key.br()}:") { 613d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val field = it.value.first() 6141c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 6151c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(field.invalidateFlagSet) { suffix, index -> 6161c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.localValue(index)} |= ${field.invalidateFlagSet.localValue(index)};") 6171c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 6181c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 619d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 620d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 621d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 622d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 62343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${"".br()}:") { 624d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.invalidateFlagSet 6251c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 6261c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 6271c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.getLocalName()}$suffix |= ${flagSet.localValue(index)};") 6281c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 6291c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 630d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 631d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 632d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 633d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) 634d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 635d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 636d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 63734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 63834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 639d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 640d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 641d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 642d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareViews() = kcode("// views") { 643dea555cf42dc3583604699c8c018d22681f56166George Mount val oneLayout = !layoutBinder.hasVariations(); 64496e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter {it.isUsed() && (oneLayout || it.getId() == null)}.forEach { 645dea555cf42dc3583604699c8c018d22681f56166George Mount val access : String 646dea555cf42dc3583604699c8c018d22681f56166George Mount if (oneLayout && it.getId() != null) { 647dea555cf42dc3583604699c8c018d22681f56166George Mount access = "public" 648dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 649dea555cf42dc3583604699c8c018d22681f56166George Mount access = "private" 650dea555cf42dc3583604699c8c018d22681f56166George Mount } 651dea555cf42dc3583604699c8c018d22681f56166George Mount nl("${access} final ${it.interfaceType} ${it.fieldName};") 652d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 653d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 654d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 655d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareVariables() = kcode("// variables") { 6565bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 6570fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private ${it.getResolvedType().toJavaCode()} ${it.fieldName};") 658d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 659d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 660d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 66120c7182163d99575d382e065f5a5fe45ed6b87e2George Mount fun declareBoundValues() = kcode("// values") { 66220c7182163d99575d382e065f5a5fe45ed6b87e2George Mount layoutBinder.getSortedTargets().filter { it.isUsed() } 66320c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .flatMap { it.getBindings() } 66420c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .filter { it.requiresOldValue() } 66520c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .flatMap{ it.getComponentExpressions().toArrayList() } 66620c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .groupBy { it } 66720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .forEach { 66820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount val expr = it.getKey() 66920c7182163d99575d382e065f5a5fe45ed6b87e2George Mount nl("private ${expr.getResolvedType().toJavaCode()} ${expr.oldValueName};") 67020c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 67120c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 67220c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 673716ba89e7f459f49ea85070d4710c1d79d715298George Mount fun declareListeners() = kcode("// listeners") { 674716ba89e7f459f49ea85070d4710c1d79d715298George Mount model.getExprMap().values().filter { 675716ba89e7f459f49ea85070d4710c1d79d715298George Mount it is FieldAccessExpr && it.isListener() 676716ba89e7f459f49ea85070d4710c1d79d715298George Mount }.groupBy { it }.forEach { 677716ba89e7f459f49ea85070d4710c1d79d715298George Mount val expr = it.key as FieldAccessExpr 678716ba89e7f459f49ea85070d4710c1d79d715298George Mount nl("private ${expr.listenerClassName} ${expr.fieldName};") 679716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 680716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 681716ba89e7f459f49ea85070d4710c1d79d715298George Mount 682d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareDirtyFlags() = kcode("// dirty flag") { 683d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.ext.localizedFlags.forEach { flag -> 684de38dd3ef0577d25b2d59863603abe5750d0c231George Mount flag.notEmpty { suffix, value -> 6850fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private") 686d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(" ", if(flag.isDynamic()) null else "static final"); 687d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar app(" ", " ${flag.type} ${flag.getLocalName()}$suffix = ${longToBinary(value)};") 688d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 689d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 690d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 691d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 692d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun flagMapping() = kcode("/* flag mapping") { 693d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (model.getFlagMapping() != null) { 694d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val mapping = model.getFlagMapping() 695d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in mapping.indices) { 696d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("flag $i: ${mapping[i]}") 697d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 698d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 699d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nl("flag mapping end*/") 700d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 701d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 7024c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun executePendingBindings() = kcode("") { 7030fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("@Override") 704e725f0d81e1b07e88f819be9a82181eeeb680dbfGeorge Mount nl("protected void executeBindings() {") { 705d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val tmpDirtyFlags = FlagSet(mDirtyFlags.buckets) 706d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tmpDirtyFlags.setLocalName("dirtyFlags"); 707d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in (0..mDirtyFlags.buckets.size() - 1)) { 7081c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${tmpDirtyFlags.type} ${tmpDirtyFlags.localValue(i)} = 0;") 709d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7101c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 7111c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar for (i in (0..mDirtyFlags.buckets.size() - 1)) { 7121c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${tmpDirtyFlags.localValue(i)} = ${mDirtyFlags.localValue(i)};") 7131c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.localValue(i)} = 0;") 7141c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 7151c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 7164a81aabc49f6c881d960cd541adda7de9625277aYigit Boyar model.getPendingExpressions().filterNot {!it.canBeEvaluatedToAVariable() || (it.isVariable() && !it.isUsed())}.forEach { 7174a81aabc49f6c881d960cd541adda7de9625277aYigit Boyar tab("${it.getResolvedType().toJavaCode()} ${it.executePendingLocalName} = ${if(it.isVariable()) it.fieldName else it.getDefaultValue()};") 718d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 719b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("writing executePendingBindings for %s", className) 720d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar do { 72174f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyar val batch = ExprModel.filterShouldRead(model.getPendingExpressions()).toArrayList() 722b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("batch: %s", batch) 723d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val mJustRead = arrayListOf<Expr>() 724d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar while (!batch.none()) { 7250fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val readNow = batch.filter { it.shouldReadNow(mJustRead) } 726d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (readNow.isEmpty()) { 727d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar throw IllegalStateException("do not know what I can read. bailing out ${batch.joinToString("\n")}") 728d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 729b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("new read now. batch size: %d, readNow size: %d", batch.size(), readNow.size()) 730d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 731d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar readNow.forEach { 7320fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl(readWithDependants(it, mJustRead, batch, tmpDirtyFlags)) 733d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 734d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar batch.removeAll(mJustRead) 735d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7360fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// batch finished") 737d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } while(model.markBitsRead()) 7387b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar // verify everything is read. 7397b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar val batch = ExprModel.filterShouldRead(model.getPendingExpressions()).toArrayList() 7407b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar if (batch.isNotEmpty()) { 7417b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar L.e("could not generate code for %s. This might be caused by circular dependencies." 7427b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar + "Please report on b.android.com", layoutBinder.getLayoutname()) 7437b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar } 744d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // 74596e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter { it.isUsed() } 746d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .flatMap { it.getBindings() } 747d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .groupBy { it.getExpr() } 748d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 749d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.key.dirtyFlagSet 750d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 751d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 752d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }.joinToString(" || ") 753d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) {") { 754d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.value.forEach { binding -> 75597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("// api target ${binding.getMinApi()}") 75634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val fieldName : String 757d6527ee28cc3aa05818799af8def9593346f91bcGeorge Mount if (binding.getTarget().getViewClass(). 75834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount equals(binding.getTarget().getInterfaceType())) { 75934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fieldName = "this.${binding.getTarget().fieldName}" 76034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } else { 76134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fieldName = "((${binding.getTarget().getViewClass()}) this.${binding.getTarget().fieldName})" 76234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 763e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount val bindingCode = binding.toJavaCode(fieldName, "this.mBindingComponent") 76497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar if (binding.getMinApi() > 1) { 7654c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("if(getBuildSdkInt() >= ${binding.getMinApi()}) {") { 76697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("$bindingCode;") 76797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 76897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("}") 76997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } else { 77097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("$bindingCode;") 77197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 772d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 77320c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 77420c7182163d99575d382e065f5a5fe45ed6b87e2George Mount tab("}") 77520c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 77620c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 77720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount layoutBinder.getSortedTargets().filter { it.isUsed() } 77820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .flatMap { it.getBindings() } 77920c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .filter { it.requiresOldValue() } 78020c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .groupBy { it.getExpr() } 78120c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .forEach { 78220c7182163d99575d382e065f5a5fe45ed6b87e2George Mount val flagSet = it.key.dirtyFlagSet 78320c7182163d99575d382e065f5a5fe45ed6b87e2George Mount tab("if (${tmpDirtyFlags.mapOr(flagSet) { suffix, index -> 78420c7182163d99575d382e065f5a5fe45ed6b87e2George Mount "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 78520c7182163d99575d382e065f5a5fe45ed6b87e2George Mount }.joinToString(" || ") 78620c7182163d99575d382e065f5a5fe45ed6b87e2George Mount }) {") { 78720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount it.value.first().getComponentExpressions().forEach { expr -> 78820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount tab("this.${expr.oldValueName} = ${expr.toCode(false).generate()};") 78920c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 790d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 791d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 792d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7935bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar includedBinders.filter{it.isUsed()}.forEach { binder -> 7944c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("${binder.fieldName}.executePendingBindings();") 7957551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 79696e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{ 797de38dd3ef0577d25b2d59863603abe5750d0c231George Mount it.isUsed() && it.getResolvedType() != null && it.getResolvedType().extendsViewStub() 798de38dd3ef0577d25b2d59863603abe5750d0c231George Mount }.forEach { 799de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("if (${it.fieldName}.getBinding() != null) {") { 800de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("${it.fieldName}.getBinding().executePendingBindings();") 801de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 802de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("}") 803de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 804d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8050fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 806d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 807d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 808d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar fun readWithDependants(expr : Expr, mJustRead : MutableList<Expr>, batch : MutableList<Expr>, 809d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tmpDirtyFlags : FlagSet, inheritedFlags : FlagSet? = null) : KCode = kcode("") { 810d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mJustRead.add(expr) 811b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("%s / readWithDependants %s", className, expr.getUniqueKey()); 812d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = expr.shouldReadFlagSet 813d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val needsIfWrapper = inheritedFlags == null || !flagSet.bitsEqual(inheritedFlags) 814b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("flag set:%s . inherited flags: %s. need another if: %s", flagSet, inheritedFlags, needsIfWrapper); 815d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val ifClause = "if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 81643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 81743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.joinToString(" || ") 818d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar })" 819d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 820d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val readCode = kcode("") { 821e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar if (expr.canBeEvaluatedToAVariable() && !expr.isVariable()) { 822d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // it is not a variable read it. 823d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("// read ${expr.getUniqueKey()}") 824d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // create an if case for all dependencies that might be null 825d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val nullables = expr.getDependencies().filter { 826e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount it.isMandatory() && it.getOther().getResolvedType().isNullable() 82774f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyar }.map { it.getOther() } 828d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (!expr.isEqualityCheck() && nullables.isNotEmpty()) { 829019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab ("if ( ${nullables.map { "${it.executePendingLocalName} != null" }.joinToString(" && ")}) {") { 830019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("${expr.executePendingLocalName}").app(" = ", expr.toCode(true)).app(";") 831d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 832d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 833d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } else { 834019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("${expr.executePendingLocalName}").app(" = ", expr.toCode(true)).app(";") 835d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8367920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount if (expr.isObservable()) { 837019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("updateRegistration(${expr.getId()}, ${expr.executePendingLocalName});") 838d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8390fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 840d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 8410fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar // if I am the condition for an expression, set its flag 8420fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val conditionals = expr.getDependants().filter { !it.isConditional() 8430fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar && it.getDependant() is TernaryExpr && (it.getDependant() as TernaryExpr).getPred() == expr } 8440fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar .map { it.getDependant() } 8450fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar if (conditionals.isNotEmpty()) { 8460fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// setting conditional flags") 847019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("if (${expr.executePendingLocalName}) {") { 8480fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar conditionals.forEach { 8490fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val set = it.getRequirementFlagSet(true) 8500fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar mDirtyFlags.mapOr(set) { suffix , index -> 8510fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 852d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 853d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 854d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8550fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("} else {") { 8560fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar conditionals.forEach { 8570fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val set = it.getRequirementFlagSet(false) 8580fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar mDirtyFlags.mapOr(set) { suffix , index -> 8590fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 8600fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 8610fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 8620fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } tab("}") 863d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8640fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar 865d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val chosen = expr.getDependants().filter { 866d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val dependant = it.getDependant() 867d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar batch.contains(dependant) && 868d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar dependant.shouldReadFlagSet.andNot(flagSet).isEmpty() && 869d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar dependant.shouldReadNow(mJustRead) 870d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 871d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (chosen.isNotEmpty()) { 872d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val nextInheritedFlags = if (needsIfWrapper) flagSet else inheritedFlags 873d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar chosen.forEach { 874d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readWithDependants(it.getDependant(), mJustRead, batch, tmpDirtyFlags, nextInheritedFlags)) 875d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 876d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 877d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 878d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar if (needsIfWrapper) { 879d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tab(ifClause) { 880d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar app(" {") 881d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readCode) 882d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 883d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tab("}") 884d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } else { 885d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readCode) 886d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 887d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 888716ba89e7f459f49ea85070d4710c1d79d715298George Mount 889716ba89e7f459f49ea85070d4710c1d79d715298George Mount fun declareListenerImpls() = kcode("// Listener Stub Implementations") { 890716ba89e7f459f49ea85070d4710c1d79d715298George Mount model.getExprMap().values().filter { 891716ba89e7f459f49ea85070d4710c1d79d715298George Mount it.isUsed() && it is FieldAccessExpr && it.isListener() 892716ba89e7f459f49ea85070d4710c1d79d715298George Mount }.groupBy { it }.forEach { 893716ba89e7f459f49ea85070d4710c1d79d715298George Mount val expr = it.key as FieldAccessExpr 894716ba89e7f459f49ea85070d4710c1d79d715298George Mount val listeners = expr.getListenerTypes() 895716ba89e7f459f49ea85070d4710c1d79d715298George Mount val extends = listeners.firstOrNull{ !it.isInterface() } 896716ba89e7f459f49ea85070d4710c1d79d715298George Mount val extendsImplements = StringBuilder() 897716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (extends != null) { 898716ba89e7f459f49ea85070d4710c1d79d715298George Mount extendsImplements.append("extends ${extends.toJavaCode()} "); 899716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 900716ba89e7f459f49ea85070d4710c1d79d715298George Mount val implements = expr.getListenerTypes().filter{ it.isInterface() }.map { 901716ba89e7f459f49ea85070d4710c1d79d715298George Mount it.toJavaCode() 902716ba89e7f459f49ea85070d4710c1d79d715298George Mount }.joinToString(", ") 903716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (!implements.isEmpty()) { 904716ba89e7f459f49ea85070d4710c1d79d715298George Mount extendsImplements.append("implements ${implements}") 905716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 906716ba89e7f459f49ea85070d4710c1d79d715298George Mount nl("public static class ${expr.listenerClassName} ${extendsImplements} {") { 907716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab("public ${expr.listenerClassName}() {}") 908716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (expr.getChild().isDynamic()) { 909716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab("private ${expr.getChild().getResolvedType().toJavaCode()} value;") 910716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab("public ${expr.listenerClassName} setValue(${expr.getChild().getResolvedType().toJavaCode()} value) {") { 911716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab("this.value = value;") 912716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab("return value == null ? null : this;") 913716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 914716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab("}") 915716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 916716ba89e7f459f49ea85070d4710c1d79d715298George Mount val signatures = HashSet<String>() 917716ba89e7f459f49ea85070d4710c1d79d715298George Mount expr.getListenerMethods().withIndex().forEach { 918716ba89e7f459f49ea85070d4710c1d79d715298George Mount val listener = it.value 919716ba89e7f459f49ea85070d4710c1d79d715298George Mount val calledMethod = expr.getCalledMethods().get(it.index) 920716ba89e7f459f49ea85070d4710c1d79d715298George Mount val parameterTypes = listener.getParameterTypes() 921716ba89e7f459f49ea85070d4710c1d79d715298George Mount val returnType = listener.getReturnType(parameterTypes.toArrayList()) 922716ba89e7f459f49ea85070d4710c1d79d715298George Mount val signature = "public ${returnType} ${listener.getName()}(${ 923716ba89e7f459f49ea85070d4710c1d79d715298George Mount parameterTypes.withIndex().map { 924716ba89e7f459f49ea85070d4710c1d79d715298George Mount "${it.value.toJavaCode()} arg${it.index}" 925716ba89e7f459f49ea85070d4710c1d79d715298George Mount }.joinToString(", ") 926716ba89e7f459f49ea85070d4710c1d79d715298George Mount }) {" 927716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (!signatures.contains(signature)) { 928716ba89e7f459f49ea85070d4710c1d79d715298George Mount signatures.add(signature) 929716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab("@Override") 930716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab(signature) { 931716ba89e7f459f49ea85070d4710c1d79d715298George Mount val obj : String 932716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (expr.getChild().isDynamic()) { 933716ba89e7f459f49ea85070d4710c1d79d715298George Mount obj = "this.value" 934716ba89e7f459f49ea85070d4710c1d79d715298George Mount } else { 935716ba89e7f459f49ea85070d4710c1d79d715298George Mount obj = expr.getChild().toCode(false).generate(); 936716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 937716ba89e7f459f49ea85070d4710c1d79d715298George Mount val returnStr : String 938716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (!returnType.isVoid()) { 939716ba89e7f459f49ea85070d4710c1d79d715298George Mount returnStr = "return " 940716ba89e7f459f49ea85070d4710c1d79d715298George Mount } else { 941716ba89e7f459f49ea85070d4710c1d79d715298George Mount returnStr = "" 942716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 943716ba89e7f459f49ea85070d4710c1d79d715298George Mount val args = parameterTypes.withIndex().map { 944716ba89e7f459f49ea85070d4710c1d79d715298George Mount "arg${it.index}" 945716ba89e7f459f49ea85070d4710c1d79d715298George Mount }.joinToString(", ") 946716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab("${returnStr}${obj}.${calledMethod.getName()}(${args});") 947716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 948716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab("}") 949716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 950716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 951716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 952716ba89e7f459f49ea85070d4710c1d79d715298George Mount nl("}") 953716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 954716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 95543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 956dea555cf42dc3583604699c8c018d22681f56166George Mount fun declareFactories() = kcode("") { 957081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount nl("public static ${baseClassName} inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot) {") { 958e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return inflate(inflater, root, attachToRoot, android.databinding.DataBindingUtil.getDefaultComponent());") 959e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 960e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount nl("}") 961e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount nl("public static ${baseClassName} inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot, android.databinding.DataBindingComponent bindingComponent) {") { 962e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return android.databinding.DataBindingUtil.<${baseClassName}>inflate(inflater, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, root, attachToRoot, bindingComponent);") 963081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount } 964081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount nl("}") 96596e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (!layoutBinder.isMerge()) { 966081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount nl("public static ${baseClassName} inflate(android.view.LayoutInflater inflater) {") { 967e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return inflate(inflater, android.databinding.DataBindingUtil.getDefaultComponent());") 968e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 969e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount nl("}") 970e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount nl("public static ${baseClassName} inflate(android.view.LayoutInflater inflater, android.databinding.DataBindingComponent bindingComponent) {") { 971e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return bind(inflater.inflate(${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, null, false), bindingComponent);") 97296e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 97396e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 97496e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public static ${baseClassName} bind(android.view.View view) {") { 975e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return bind(view, android.databinding.DataBindingUtil.getDefaultComponent());") 976e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 977e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount nl("}") 978e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount nl("public static ${baseClassName} bind(android.view.View view, android.databinding.DataBindingComponent bindingComponent) {") { 97996e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("if (!\"${layoutBinder.getTag()}_0\".equals(view.getTag())) {") { 980f80b08430f11515ff944f89006799f21545602b9George Mount tab("throw new RuntimeException(\"view tag isn't correct on view:\" + view.getTag());") 98196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 98296e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("}") 983e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return new ${baseClassName}(bindingComponent, view);") 98496e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 98596e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 986dea555cf42dc3583604699c8c018d22681f56166George Mount } 987dea555cf42dc3583604699c8c018d22681f56166George Mount } 988dea555cf42dc3583604699c8c018d22681f56166George Mount 9898b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar /** 9908b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar * When called for a library compilation, we do not generate real implementations 9918b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar */ 9928b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar public fun writeBaseClass(forLibrary : Boolean) : String = 99343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar kcode("package ${layoutBinder.getPackage()};") { 994fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.Bindable;") 995fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.DataBindingUtil;") 996fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.ViewDataBinding;") 9974c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("public abstract class ${baseClassName} extends ViewDataBinding {") 99896e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 999de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("public final ${it.interfaceType} ${it.fieldName};") 100034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 100134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 1002e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("protected ${baseClassName}(android.databinding.DataBindingComponent bindingComponent, android.view.View root_, int localFieldCount") { 100396e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 1004019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab(", ${it.interfaceType} ${it.constructorParamName}") 100534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 100634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 100734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab(") {") { 1008e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("super(bindingComponent, root_, localFieldCount);") 100996e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 1010019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("this.${it.fieldName} = ${it.constructorParamName};") 101134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 10124c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 10134c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 10144c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("") 101543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar variables.forEach { 101618243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.getUserDefinedType() != null) { 1017895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar val type = ModelAnalyzer.getInstance().applyImports(it.getUserDefinedType(), model.getImports()) 1018019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("public abstract void ${it.setterName}(${type} ${it.readableName});") 101918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 102043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 10219bdb2415487832e88a05c7bd19391b05440b468eGeorge Mount tab("public static ${baseClassName} inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot) {") { 1022e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return inflate(inflater, root, attachToRoot, android.databinding.DataBindingUtil.getDefaultComponent());") 1023e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1024e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("}") 1025e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("public static ${baseClassName} inflate(android.view.LayoutInflater inflater) {") { 1026e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return inflate(inflater, android.databinding.DataBindingUtil.getDefaultComponent());") 1027e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1028e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("}") 1029e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("public static ${baseClassName} bind(android.view.View view) {") { 10308b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar if (forLibrary) { 10318b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar tab("return null;") 10328b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar } else { 1033e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return bind(view, android.databinding.DataBindingUtil.getDefaultComponent());") 10348b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar } 103543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 10364c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 1037e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("public static ${baseClassName} inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot, android.databinding.DataBindingComponent bindingComponent) {") { 10388b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar if (forLibrary) { 10398b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar tab("return null;") 10408b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar } else { 1041e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return DataBindingUtil.<${baseClassName}>inflate(inflater, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, root, attachToRoot, bindingComponent);") 10428b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar } 10434c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 10444c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 1045e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("public static ${baseClassName} inflate(android.view.LayoutInflater inflater, android.databinding.DataBindingComponent bindingComponent) {") { 1046e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount if (forLibrary) { 1047e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return null;") 1048e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } else { 1049e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return DataBindingUtil.<${baseClassName}>inflate(inflater, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, null, false, bindingComponent);") 1050e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1051e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1052e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("}") 1053e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("public static ${baseClassName} bind(android.view.View view, android.databinding.DataBindingComponent bindingComponent) {") { 10548b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar if (forLibrary) { 10558b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar tab("return null;") 10568b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar } else { 1057e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return (${baseClassName})bind(bindingComponent, view, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()});") 10588b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar } 10594c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 10604c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 106143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar nl("}") 106243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.generate() 1063dea555cf42dc3583604699c8c018d22681f56166George Mount} 1064