LayoutBinderWriter.kt revision 20c7182163d99575d382e065f5a5fe45ed6b87e2
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 16fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.LayoutBinder 17e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarimport kotlin.properties.Delegates 18e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarimport android.databinding.tool.BindingTarget 19fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.Expr 20d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport kotlin.properties.Delegates 21fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.BindingTarget 22fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.IdentifierExpr 23d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.BitSet 24fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ExprModel 25d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.Arrays 26c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mountimport android.databinding.tool.expr.BitShiftExpr 27fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.TernaryExpr 28fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.FieldAccessExpr 29fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ComparisonExpr 30fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.GroupExpr 31c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mountimport android.databinding.tool.expr.InstanceOfExpr 32fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.MathExpr 33fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.MethodCallExpr 34fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.StaticIdentifierExpr 35fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.SymbolExpr 36c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mountimport android.databinding.tool.expr.UnaryExpr 37fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ResourceExpr 38fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.BracketExpr 39e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarimport android.databinding.tool.ext; 407b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarimport android.databinding.tool.ext.androidId 417b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarimport android.databinding.tool.ext.lazy 427b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarimport android.databinding.tool.ext.versionedLazy 437b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarimport android.databinding.tool.ext.br 447b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarimport android.databinding.tool.ext.joinToCamelCaseAsVar 45e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarimport java.util.BitSet 46e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarimport java.util.Arrays 47fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.Callable 48fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelAnalyzer 497b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarimport android.databinding.tool.util.L 507b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarimport com.google.common.collect.Iterables 5196e1c821dd446d1ed78f8ae61131550588f60a24George Mountimport java.util.ArrayList 5234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport java.util.HashMap 5343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 54fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyarfun String.stripNonJava() = this.split("[^a-zA-Z0-9]".toRegex()).map{ it.trim() }.joinToCamelCaseAsVar() 55d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 56019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarenum class Scope { 57fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar FIELD, 58fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar METHOD, 59fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar FLAG, 60fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar EXECUTE_PENDING_METHOD, 61019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar CONSTRUCTOR_PARAM 62019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar} 63019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar 64d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarclass ExprModelExt { 65019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val usedFieldNames = hashMapOf<Scope, MutableSet<String>>(); 66fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar init { 67019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Scope.values().forEach { usedFieldNames[it] = hashSetOf<String>() } 68019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar } 69d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val localizedFlags = arrayListOf<FlagSet>() 70d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 71d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun localizeFlag(set : FlagSet, name:String) : FlagSet { 72d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar localizedFlags.add(set) 73019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val result = getUniqueName(name, Scope.FLAG) 74d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar set.setLocalName(result) 75d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return set 76d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 77d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 78019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar fun getUniqueName(base : String, scope : Scope) : String { 79d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var candidate = base 80d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var i = 0 81019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar while (usedFieldNames[scope].contains(candidate)) { 82d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar i ++ 83d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar candidate = base + i 84d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 85019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar usedFieldNames[scope].add(candidate) 86d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return candidate 87d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 88d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 89d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 90de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval ExprModel.ext by Delegates.lazy { target : ExprModel -> 91d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar ExprModelExt() 92d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 93d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 94019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getUniqueFieldName(base : String) : String = ext.getUniqueName(base, Scope.FIELD) 95019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getUniqueMethodName(base : String) : String = ext.getUniqueName(base, Scope.METHOD) 96019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getUniqueFlagName(base : String) : String = ext.getUniqueName(base, Scope.FLAG) 97019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getConstructorParamName(base : String) : String = ext.getUniqueName(base, Scope.CONSTRUCTOR_PARAM) 98d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 99d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun ExprModel.localizeFlag(set : FlagSet, base : String) : FlagSet = ext.localizeFlag(set, base) 100d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 101019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar// not necessarily unique. Uniqueness is solved per scope 102019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval BindingTarget.readableName by Delegates.lazy { target: BindingTarget -> 10300da715547ee7d5d38a3b8576090ca427a94daa5George Mount if (target.getId() == null) { 104019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar "boundView" + indexFromTag(target.getTag()) 10500da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 106019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar target.getId().androidId().stripNonJava() 10700da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 108d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 1097551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 110de38dd3ef0577d25b2d59863603abe5750d0c231George Mountfun BindingTarget.superConversion(variable : String) : String { 11196e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (getResolvedType() != null && getResolvedType().extendsViewStub()) { 112de38dd3ef0577d25b2d59863603abe5750d0c231George Mount return "new android.databinding.ViewStubProxy((android.view.ViewStub) ${variable})" 113de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } else { 114de38dd3ef0577d25b2d59863603abe5750d0c231George Mount return "(${interfaceType}) ${variable}" 115de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 116de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 117de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 118019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval BindingTarget.fieldName : String by Delegates.lazy { target : BindingTarget -> 119019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val name : String 120019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar if (target.getId() == null) { 121019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar name = "m${target.readableName}" 122019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar } else { 123019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar name = target.readableName 12434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 125019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar target.getModel().getUniqueFieldName(name) 126d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 127d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 128de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.androidId by Delegates.lazy { target : BindingTarget -> 12943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar "R.id.${target.getId().androidId()}" 130d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 131d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 132de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.interfaceType by Delegates.lazy { target : BindingTarget -> 133de38dd3ef0577d25b2d59863603abe5750d0c231George Mount if (target.getResolvedType() != null && target.getResolvedType().extendsViewStub()) { 134de38dd3ef0577d25b2d59863603abe5750d0c231George Mount "android.databinding.ViewStubProxy" 135de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } else { 136de38dd3ef0577d25b2d59863603abe5750d0c231George Mount target.getInterfaceType() 137de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 138de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 139de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 140019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval BindingTarget.constructorParamName by Delegates.lazy { target : BindingTarget -> 141019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar target.getModel().getConstructorParamName(target.readableName) 142d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 143d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 144019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar// not necessarily unique. Uniqueness is decided per scope 145de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.readableName by Delegates.lazy { expr : Expr -> 146019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val stripped = "${expr.getUniqueKey().stripNonJava()}" 147b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("readableUniqueName for [%s] %s is %s", System.identityHashCode(expr), expr.getUniqueKey(), stripped) 148019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar stripped 149de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 150de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 151de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.fieldName by Delegates.lazy { expr : Expr -> 152019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueFieldName("m${expr.readableName.capitalize()}") 153d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 154d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 15520c7182163d99575d382e065f5a5fe45ed6b87e2George Mountval Expr.oldValueName by Delegates.lazy { expr : Expr -> 15620c7182163d99575d382e065f5a5fe45ed6b87e2George Mount expr.getModel().getUniqueFieldName("mOld${expr.readableName.capitalize()}") 15720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount} 15820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 159019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval Expr.executePendingLocalName by Delegates.lazy { expr : Expr -> 1604a81aabc49f6c881d960cd541adda7de9625277aYigit Boyar "${expr.getModel().ext.getUniqueName(expr.readableName, Scope.EXECUTE_PENDING_METHOD)}" 161d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 162d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 163de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.setterName by Delegates.lazy { expr : Expr -> 164019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueMethodName("set${expr.readableName.capitalize()}") 165d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 166d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 167de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.onChangeName by Delegates.lazy { expr : Expr -> 168019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueMethodName("onChange${expr.readableName.capitalize()}") 169d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 170d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 171de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.getterName by Delegates.lazy { expr : Expr -> 172019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueMethodName("get${expr.readableName.capitalize()}") 173d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 174d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 175de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.dirtyFlagName by Delegates.lazy { expr : Expr -> 176019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueFlagName("sFlag${expr.readableName.capitalize()}") 177d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 178d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 179d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 180e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarfun Expr.toCode(full : Boolean = false) : KCode = CodeGenUtil.toCode(this, full) 181d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 182d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.isVariable() = this is IdentifierExpr && this.isDynamic() 183d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 184d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.conditionalFlagName(output : Boolean, suffix : String) = "${dirtyFlagName}_${output}$suffix" 185d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 186d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 187de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.dirtyFlagSet by Delegates.lazy { expr : Expr -> 188d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getInvalidFlags(), expr.getModel().getFlagBucketCount()) 189d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 190d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 191de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.invalidateFlagSet by Delegates.lazy { expr : Expr -> 192d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getId()) 193d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 194d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 1957b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarval Expr.shouldReadFlagSet by Delegates.versionedLazy { expr : Expr -> 196d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getShouldReadFlags(), expr.getModel().getFlagBucketCount()) 197d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 198d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 199de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.conditionalFlags by Delegates.lazy { expr : Expr -> 200d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar arrayListOf(FlagSet(expr.getRequirementFlagIndex(false)), 201d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getRequirementFlagIndex(true))) 202d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 203d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 204d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.getRequirementFlagSet(expected : Boolean) : FlagSet = conditionalFlags[if(expected) 1 else 0] 205d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 206d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.notEmpty(cb : (suffix : String, value : Long) -> Unit) { 207d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar buckets.withIndex().forEach { 208d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (it.value != 0L) { 209d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar cb(getWordSuffix(it.index), buckets[it.index]) 210d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 211d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 212d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 213d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 214d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.getWordSuffix(wordIndex : Int) : String { 215d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return if(wordIndex == 0) "" else "_${wordIndex}" 216d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 217d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 218d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.localValue(bucketIndex : Int) = 219d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar if (getLocalName() == null) binaryCode(bucketIndex) 220d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar else "${getLocalName()}${getWordSuffix(bucketIndex)}" 221d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 222d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyarfun FlagSet.binaryCode(bucketIndex : Int) = longToBinary(buckets[bucketIndex]) 223d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 224d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 225d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyarfun longToBinary(l : Long) = 226d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar "0b${java.lang.Long.toBinaryString(l)}L" 227d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 228d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun <T> FlagSet.mapOr(other : FlagSet, cb : (suffix : String, index : Int) -> T) : List<T> { 229d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val min = Math.min(buckets.size(), other.buckets.size()) 230d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val result = arrayListOf<T>() 231d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in 0..(min - 1)) { 232d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // if these two can match by any chance, call the callback 233d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (intersect(other, i)) { 234d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar result.add(cb(getWordSuffix(i), i)) 235d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 236d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 237d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return result 238d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 239d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 24096e1c821dd446d1ed78f8ae61131550588f60a24George Mountfun indexFromTag(tag : String) : kotlin.Int { 24196e1c821dd446d1ed78f8ae61131550588f60a24George Mount val startIndex : kotlin.Int 2427ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount if (tag.startsWith("binding_")) { 2437ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount startIndex = "binding_".length(); 24496e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 24596e1c821dd446d1ed78f8ae61131550588f60a24George Mount startIndex = tag.lastIndexOf('_') + 1 24696e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 24796e1c821dd446d1ed78f8ae61131550588f60a24George Mount return Integer.parseInt(tag.substring(startIndex)) 24896e1c821dd446d1ed78f8ae61131550588f60a24George Mount} 24996e1c821dd446d1ed78f8ae61131550588f60a24George Mount 25043596c2b2997e40b709627419732100d78a62ff0Yigit Boyarclass LayoutBinderWriter(val layoutBinder : LayoutBinder) { 251d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val model = layoutBinder.getModel() 25234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val indices = HashMap<BindingTarget, kotlin.Int>() 25343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val mDirtyFlags by Delegates.lazy { 25443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val fs = FlagSet(BitSet(), model.getFlagBucketCount()); 25543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Arrays.fill(fs.buckets, -1) 25643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs.setDynamic(true) 25743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.localizeFlag(fs, "mDirtyFlags") 25843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs 259d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 260d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 26143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val dynamics by Delegates.lazy { model.getExprMap().values().filter { it.isDynamic() } } 262dea555cf42dc3583604699c8c018d22681f56166George Mount val className = layoutBinder.getImplementationName() 263d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 264dea555cf42dc3583604699c8c018d22681f56166George Mount val baseClassName = "${layoutBinder.getClassName()}" 265d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 2667551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar val includedBinders by Delegates.lazy { 2677551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar layoutBinder.getBindingTargets().filter { it.isBinder() } 2687551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 2697551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 27043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val variables by Delegates.lazy { 27143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.getExprMap().values().filterIsInstance(javaClass<IdentifierExpr>()).filter { it.isVariable() } 27243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 273d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 2745bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar val usedVariables by Delegates.lazy { 2755bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar variables.filter {it.isUsed()} 2765bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 277d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 27896e1c821dd446d1ed78f8ae61131550588f60a24George Mount public fun write(minSdk : kotlin.Int) : String { 2795bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar layoutBinder.resolveWhichExpressionsAreUsed() 28034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount calculateIndices(); 2815bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar return kcode("package ${layoutBinder.getPackage()};") { 282a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar nl("import ${layoutBinder.getModulePackage()}.R;") 283a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar nl("import ${layoutBinder.getModulePackage()}.BR;") 2845bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("import android.view.View;") 285dea555cf42dc3583604699c8c018d22681f56166George Mount val classDeclaration : String 286dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 287dea555cf42dc3583604699c8c018d22681f56166George Mount classDeclaration = "${className} extends ${baseClassName}" 288dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 289dea555cf42dc3583604699c8c018d22681f56166George Mount classDeclaration = "${className} extends android.databinding.ViewDataBinding" 290dea555cf42dc3583604699c8c018d22681f56166George Mount } 291dea555cf42dc3583604699c8c018d22681f56166George Mount nl("public class ${classDeclaration} {") { 2924c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(declareIncludeViews()) 2935bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareViews()) 2945bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareVariables()) 29520c7182163d99575d382e065f5a5fe45ed6b87e2George Mount tab(declareBoundValues()) 29696e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab(declareConstructor(minSdk)) 2975bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareInvalidateAll()) 298447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab(declareHasPendingBindings()) 2995bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareLog()) 3005bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareSetVariable()) 3015bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(variableSettersAndGetters()) 3025bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(onFieldChange()) 3035bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 3044c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(executePendingBindings()) 3055bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 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("") { 33196e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("private static final android.databinding.ViewDataBinding.IncludedLayoutIndex[][] 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() 33996e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("sIncludes = new android.databinding.ViewDataBinding.IncludedLayoutIndex[${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) 35996e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("sIncludes[${index}] = new android.databinding.ViewDataBinding.IncludedLayoutIndex[] {") { 36096e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.get(it).forEach { 36196e1c821dd446d1ed78f8ae61131550588f60a24George Mount val bindingIndex = indices.get(it) 36296e1c821dd446d1ed78f8ae61131550588f60a24George Mount val layoutName = it.getIncludedLayout() 36396e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("new android.databinding.ViewDataBinding.IncludedLayoutIndex(\"${layoutName}\", ${bindingIndex}, R.layout.${layoutName}),") 36496e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 36596e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 36696e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("};") 36796e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 36896e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 36996e1c821dd446d1ed78f8ae61131550588f60a24George Mount val viewsWithIds = layoutBinder.getBindingTargets().filter { 370d6527ee28cc3aa05818799af8def9593346f91bcGeorge Mount it.isUsed() && !it.isBinder() && (!it.supportsTag() || (it.getId() != null && it.getTag() == null)) 37100da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 37296e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (viewsWithIds.isEmpty()) { 3734c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = null;") 37400da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 3754c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = new android.util.SparseIntArray();") 37696e1c821dd446d1ed78f8ae61131550588f60a24George Mount viewsWithIds.forEach { 37734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("sViewsWithIds.put(${it.androidId}, ${indices.get(it)});") 3784c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 37900da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 3804c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 3814c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("}") 3824c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 38396e1c821dd446d1ed78f8ae61131550588f60a24George Mount 38496e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun maxIndex() : kotlin.Int { 38596e1c821dd446d1ed78f8ae61131550588f60a24George Mount val maxIndex = indices.values().max() 38696e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (maxIndex == null) { 38796e1c821dd446d1ed78f8ae61131550588f60a24George Mount return -1 38896e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 38996e1c821dd446d1ed78f8ae61131550588f60a24George Mount return maxIndex 39096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 39196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 39296e1c821dd446d1ed78f8ae61131550588f60a24George Mount 39396e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun declareConstructor(minSdk : kotlin.Int) = kcode("") { 39496e1c821dd446d1ed78f8ae61131550588f60a24George Mount val bindingCount = maxIndex() + 1 39596e1c821dd446d1ed78f8ae61131550588f60a24George Mount val parameterType : String 39696e1c821dd446d1ed78f8ae61131550588f60a24George Mount val superParam : String 39796e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (layoutBinder.isMerge()) { 39896e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View[]" 39996e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root[0]" 40096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 40196e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View" 40296e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root" 40396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 40496e1c821dd446d1ed78f8ae61131550588f60a24George Mount val rootTagsSupported = minSdk >= 14 405dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 406dea555cf42dc3583604699c8c018d22681f56166George Mount nl("") 40796e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public ${className}(${parameterType} root) {") { 40896e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("this(${superParam}, mapBindings(root, ${bindingCount}, sIncludes, sViewsWithIds));") 409dea555cf42dc3583604699c8c018d22681f56166George Mount } 410dea555cf42dc3583604699c8c018d22681f56166George Mount nl("}") 41196e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("private ${className}(${parameterType} root, Object[] bindings) {") { 41296e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("super(${superParam}, ${model.getObservables().size()}") { 41396e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter { it.getId() != null }.forEach { 414dea555cf42dc3583604699c8c018d22681f56166George Mount tab(", ${fieldConversion(it)}") 41534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 416dea555cf42dc3583604699c8c018d22681f56166George Mount tab(");") 41734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 41834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 419dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 42096e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public ${baseClassName}(${parameterType} root) {") { 42196e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("super(${superParam}, ${model.getObservables().size()});") 42296e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("final Object[] bindings = mapBindings(root, ${bindingCount}, sIncludes, sViewsWithIds);") 423dea555cf42dc3583604699c8c018d22681f56166George Mount } 424dea555cf42dc3583604699c8c018d22681f56166George Mount } 42596e1c821dd446d1ed78f8ae61131550588f60a24George Mount val taggedViews = layoutBinder.getSortedTargets().filter{it.isUsed()} 426dea555cf42dc3583604699c8c018d22681f56166George Mount taggedViews.forEach { 427dea555cf42dc3583604699c8c018d22681f56166George Mount if (!layoutBinder.hasVariations() || it.getId() == null) { 428dea555cf42dc3583604699c8c018d22681f56166George Mount tab("this.${it.fieldName} = ${fieldConversion(it)};") 429dea555cf42dc3583604699c8c018d22681f56166George Mount } 430d6527ee28cc3aa05818799af8def9593346f91bcGeorge Mount if (!it.isBinder()) { 431de38dd3ef0577d25b2d59863603abe5750d0c231George Mount if (it.getResolvedType() != null && it.getResolvedType().extendsViewStub()) { 432de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("this.${it.fieldName}.setContainingBinding(this);") 433de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 43496e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (it.supportsTag() && it.getTag() != null && 4357ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount (rootTagsSupported || it.getTag().startsWith("binding_"))) { 436dea555cf42dc3583604699c8c018d22681f56166George Mount val originalTag = it.getOriginalTag(); 437dea555cf42dc3583604699c8c018d22681f56166George Mount var tagValue = "null" 438dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag != null) { 439dea555cf42dc3583604699c8c018d22681f56166George Mount tagValue = "\"${originalTag}\"" 440dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@")) { 441dea555cf42dc3583604699c8c018d22681f56166George Mount var packageName = layoutBinder.getModulePackage() 442dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@android:")) { 443dea555cf42dc3583604699c8c018d22681f56166George Mount packageName = "android" 44400da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 445dea555cf42dc3583604699c8c018d22681f56166George Mount val slashIndex = originalTag.indexOf('/') 446dea555cf42dc3583604699c8c018d22681f56166George Mount val resourceId = originalTag.substring(slashIndex + 1) 447dea555cf42dc3583604699c8c018d22681f56166George Mount tagValue = "root.getResources().getString(${packageName}.R.string.${resourceId})" 44800da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 44900da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 450dea555cf42dc3583604699c8c018d22681f56166George Mount tab("this.${it.fieldName}.setTag(${tagValue});") 4517551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 452d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 453d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 4544d4979490e1fa374c0d7f3599fed0a9e83a579d0George Mount tab("setRootTag(root);") 455dea555cf42dc3583604699c8c018d22681f56166George Mount tab("invalidateAll();"); 4560fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 457d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 458d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 459dea555cf42dc3583604699c8c018d22681f56166George Mount fun fieldConversion(target : BindingTarget) : String { 460dea555cf42dc3583604699c8c018d22681f56166George Mount if (!target.isUsed()) { 461dea555cf42dc3583604699c8c018d22681f56166George Mount return "null" 462dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 46396e1c821dd446d1ed78f8ae61131550588f60a24George Mount val index = indices.get(target) 464dea555cf42dc3583604699c8c018d22681f56166George Mount if (index == null) { 46596e1c821dd446d1ed78f8ae61131550588f60a24George Mount throw IllegalStateException("Unknown binding target") 466dea555cf42dc3583604699c8c018d22681f56166George Mount } 46796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val variableName = "bindings[${index}]" 468dea555cf42dc3583604699c8c018d22681f56166George Mount return target.superConversion(variableName) 469dea555cf42dc3583604699c8c018d22681f56166George Mount } 470dea555cf42dc3583604699c8c018d22681f56166George Mount } 471dea555cf42dc3583604699c8c018d22681f56166George Mount 472d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareInvalidateAll() = kcode("") { 4737551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("@Override") 4747551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("public void invalidateAll() {") { 475019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val fs = FlagSet(layoutBinder.getModel().getInvalidateAnyBitSet(), 476019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar layoutBinder.getModel().getFlagBucketCount()); 4771c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 4781c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar for (i in (0..(mDirtyFlags.buckets.size() - 1))) { 4791c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.localValue(i)} = ${fs.localValue(i)};") 4801c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 4811c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 4825bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar includedBinders.filter{it.isUsed()}.forEach { binder -> 4837551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar tab("${binder.fieldName}.invalidateAll();") 4847551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 4852f64c44e4fa296cf658ca986c095eab62f82a31dYigit Boyar tab("requestRebind();"); 486d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 4870fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 488d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 489d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 490447971abca811b11b8c1d8e7bfaa294856d03c16George Mount fun declareHasPendingBindings() = kcode("") { 491447971abca811b11b8c1d8e7bfaa294856d03c16George Mount nl("@Override") 492447971abca811b11b8c1d8e7bfaa294856d03c16George Mount nl("public boolean hasPendingBindings() {") { 493447971abca811b11b8c1d8e7bfaa294856d03c16George Mount if (mDirtyFlags.buckets.size() > 0) { 494447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("synchronized(this) {") { 495447971abca811b11b8c1d8e7bfaa294856d03c16George Mount val flagCheck = 0.rangeTo(mDirtyFlags.buckets.size() - 1).map { 496447971abca811b11b8c1d8e7bfaa294856d03c16George Mount "${mDirtyFlags.localValue(it)} != 0" 497447971abca811b11b8c1d8e7bfaa294856d03c16George Mount }.joinToString(" || ") 498447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("if (${flagCheck}) {") { 499447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("return true;") 500447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 501447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("}") 502447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 503447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("}") 504447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 505447971abca811b11b8c1d8e7bfaa294856d03c16George Mount includedBinders.filter{it.isUsed()}.forEach { binder -> 506447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("if (${binder.fieldName}.hasPendingBindings()) {") { 507447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("return true;") 508447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 509447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("}") 510447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 511447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("return false;") 512447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 513447971abca811b11b8c1d8e7bfaa294856d03c16George Mount nl("}") 514447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 515447971abca811b11b8c1d8e7bfaa294856d03c16George Mount 516d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareSetVariable() = kcode("") { 5170fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("public boolean setVariable(int variableId, Object variable) {") { 518d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch(variableId) {") { 5195bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 52043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab ("case ${it.getName().br()} :") { 521d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${it.setterName}((${it.getResolvedType().toJavaCode()}) variable);") 522d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 523d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 524d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 525d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 526d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 527d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 528d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 5290fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 530d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 531d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 532d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareLog() = kcode("") { 5330fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private void log(String msg, long i) {") { 534d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("""android.util.Log.d("BINDER", msg + ":" + Long.toHexString(i));""") 5350fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 5360fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 537d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 538d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 539d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun variableSettersAndGetters() = kcode("") { 5405bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar variables.filterNot{it.isUsed()}.forEach { 541019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar nl("public void ${it.setterName}(${it.getResolvedType().toJavaCode()} ${it.readableName}) {") { 5425bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("// not used, ignore") 5435bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5445bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 5455bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("") 5465bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("public ${it.getResolvedType().toJavaCode()} ${it.getterName}() {") { 5475bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("return ${it.getDefaultValue()};") 5485bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5495bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 5505bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5515bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 55218243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.getUserDefinedType() != null) { 553019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar nl("public void ${it.setterName}(${it.getResolvedType().toJavaCode()} ${it.readableName}) {") { 55418243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.isObservable()) { 555019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("updateRegistration(${it.getId()}, ${it.readableName});"); 55618243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 557019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("this.${it.fieldName} = ${it.readableName};") 55818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount // set dirty flags! 55918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount val flagSet = it.invalidateFlagSet 5601c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 5611c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 5621c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.getLocalName()}$suffix |= ${flagSet.localValue(index)};") 5631c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 5641c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab ("}") 56518243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("super.requestRebind();") 566d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 56718243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 56818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("") 56918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("public ${it.getResolvedType().toJavaCode()} ${it.getterName}() {") { 57018243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("return ${it.fieldName};") 571d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 57218243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 573d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 574d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 575d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 576d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 577d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun onFieldChange() = kcode("") { 57834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("@Override") 57934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {") { 5804c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("switch (localFieldId) {") { 581d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getObservables().forEach { 582d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("case ${it.getId()} :") { 583d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return ${it.onChangeName}((${it.getResolvedType().toJavaCode()}) object, fieldId);") 584d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 585d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 586d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 587d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 588d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 589d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 59034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 59134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 592d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 593d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getObservables().forEach { 594019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar nl("private boolean ${it.onChangeName}(${it.getResolvedType().toJavaCode()} ${it.readableName}, int fieldId) {") { 595d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch (fieldId) {", { 596d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val accessedFields: List<FieldAccessExpr> = it.getParents().filterIsInstance(javaClass<FieldAccessExpr>()) 597c4a07bddb4dd5c3bfbecf4d87909c5b447ae56dcGeorge Mount accessedFields.filter { it.hasBindableAnnotations() } 598d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .groupBy { it.getName() } 599d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 60043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${it.key.br()}:") { 601d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val field = it.value.first() 6021c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 6031c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(field.invalidateFlagSet) { suffix, index -> 6041c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.localValue(index)} |= ${field.invalidateFlagSet.localValue(index)};") 6051c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 6061c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 607d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 608d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 609d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 610d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 61143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${"".br()}:") { 612d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.invalidateFlagSet 6131c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 6141c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 6151c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.getLocalName()}$suffix |= ${flagSet.localValue(index)};") 6161c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 6171c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 618d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 619d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 620d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 621d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) 622d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 623d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 624d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 62534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 62634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 627d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 628d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 629d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 630d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareViews() = kcode("// views") { 631dea555cf42dc3583604699c8c018d22681f56166George Mount val oneLayout = !layoutBinder.hasVariations(); 63296e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter {it.isUsed() && (oneLayout || it.getId() == null)}.forEach { 633dea555cf42dc3583604699c8c018d22681f56166George Mount val access : String 634dea555cf42dc3583604699c8c018d22681f56166George Mount if (oneLayout && it.getId() != null) { 635dea555cf42dc3583604699c8c018d22681f56166George Mount access = "public" 636dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 637dea555cf42dc3583604699c8c018d22681f56166George Mount access = "private" 638dea555cf42dc3583604699c8c018d22681f56166George Mount } 639dea555cf42dc3583604699c8c018d22681f56166George Mount nl("${access} final ${it.interfaceType} ${it.fieldName};") 640d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 641d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 642d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 643d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareVariables() = kcode("// variables") { 6445bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 6450fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private ${it.getResolvedType().toJavaCode()} ${it.fieldName};") 646d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 647d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 648d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 64920c7182163d99575d382e065f5a5fe45ed6b87e2George Mount fun declareBoundValues() = kcode("// values") { 65020c7182163d99575d382e065f5a5fe45ed6b87e2George Mount layoutBinder.getSortedTargets().filter { it.isUsed() } 65120c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .flatMap { it.getBindings() } 65220c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .filter { it.requiresOldValue() } 65320c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .flatMap{ it.getComponentExpressions().toArrayList() } 65420c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .groupBy { it } 65520c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .forEach { 65620c7182163d99575d382e065f5a5fe45ed6b87e2George Mount val expr = it.getKey() 65720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount nl("private ${expr.getResolvedType().toJavaCode()} ${expr.oldValueName};") 65820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 65920c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 66020c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 661d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareDirtyFlags() = kcode("// dirty flag") { 662d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.ext.localizedFlags.forEach { flag -> 663de38dd3ef0577d25b2d59863603abe5750d0c231George Mount flag.notEmpty { suffix, value -> 6640fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private") 665d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(" ", if(flag.isDynamic()) null else "static final"); 666d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar app(" ", " ${flag.type} ${flag.getLocalName()}$suffix = ${longToBinary(value)};") 667d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 668d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 669d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 670d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 671d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun flagMapping() = kcode("/* flag mapping") { 672d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (model.getFlagMapping() != null) { 673d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val mapping = model.getFlagMapping() 674d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in mapping.indices) { 675d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("flag $i: ${mapping[i]}") 676d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 677d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 678d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nl("flag mapping end*/") 679d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 680d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 6814c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun executePendingBindings() = kcode("") { 6820fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("@Override") 683e725f0d81e1b07e88f819be9a82181eeeb680dbfGeorge Mount nl("protected void executeBindings() {") { 684d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val tmpDirtyFlags = FlagSet(mDirtyFlags.buckets) 685d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tmpDirtyFlags.setLocalName("dirtyFlags"); 686d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in (0..mDirtyFlags.buckets.size() - 1)) { 6871c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${tmpDirtyFlags.type} ${tmpDirtyFlags.localValue(i)} = 0;") 688d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 6891c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 6901c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar for (i in (0..mDirtyFlags.buckets.size() - 1)) { 6911c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${tmpDirtyFlags.localValue(i)} = ${mDirtyFlags.localValue(i)};") 6921c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.localValue(i)} = 0;") 6931c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 6941c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 6954a81aabc49f6c881d960cd541adda7de9625277aYigit Boyar model.getPendingExpressions().filterNot {!it.canBeEvaluatedToAVariable() || (it.isVariable() && !it.isUsed())}.forEach { 6964a81aabc49f6c881d960cd541adda7de9625277aYigit Boyar tab("${it.getResolvedType().toJavaCode()} ${it.executePendingLocalName} = ${if(it.isVariable()) it.fieldName else it.getDefaultValue()};") 697d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 698b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("writing executePendingBindings for %s", className) 699d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar do { 70074f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyar val batch = ExprModel.filterShouldRead(model.getPendingExpressions()).toArrayList() 701b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("batch: %s", batch) 702d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val mJustRead = arrayListOf<Expr>() 703d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar while (!batch.none()) { 7040fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val readNow = batch.filter { it.shouldReadNow(mJustRead) } 705d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (readNow.isEmpty()) { 706d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar throw IllegalStateException("do not know what I can read. bailing out ${batch.joinToString("\n")}") 707d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 708b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("new read now. batch size: %d, readNow size: %d", batch.size(), readNow.size()) 709d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 710d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar readNow.forEach { 7110fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl(readWithDependants(it, mJustRead, batch, tmpDirtyFlags)) 712d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 713d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar batch.removeAll(mJustRead) 714d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7150fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// batch finished") 716d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } while(model.markBitsRead()) 7177b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar // verify everything is read. 7187b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar val batch = ExprModel.filterShouldRead(model.getPendingExpressions()).toArrayList() 7197b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar if (batch.isNotEmpty()) { 7207b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar L.e("could not generate code for %s. This might be caused by circular dependencies." 7217b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar + "Please report on b.android.com", layoutBinder.getLayoutname()) 7227b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar } 723d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // 72496e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter { it.isUsed() } 725d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .flatMap { it.getBindings() } 726d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .groupBy { it.getExpr() } 727d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 728d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.key.dirtyFlagSet 729d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 730d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 731d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }.joinToString(" || ") 732d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) {") { 733d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.value.forEach { binding -> 73497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("// api target ${binding.getMinApi()}") 73534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val fieldName : String 736d6527ee28cc3aa05818799af8def9593346f91bcGeorge Mount if (binding.getTarget().getViewClass(). 73734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount equals(binding.getTarget().getInterfaceType())) { 73834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fieldName = "this.${binding.getTarget().fieldName}" 73934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } else { 74034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fieldName = "((${binding.getTarget().getViewClass()}) this.${binding.getTarget().fieldName})" 74134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 742e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar val bindingCode = binding.toJavaCode(fieldName) 74397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar if (binding.getMinApi() > 1) { 7444c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("if(getBuildSdkInt() >= ${binding.getMinApi()}) {") { 74597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("$bindingCode;") 74697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 74797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("}") 74897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } else { 74997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("$bindingCode;") 75097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 751d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 75220c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 75320c7182163d99575d382e065f5a5fe45ed6b87e2George Mount tab("}") 75420c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 75520c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 75620c7182163d99575d382e065f5a5fe45ed6b87e2George Mount layoutBinder.getSortedTargets().filter { it.isUsed() } 75720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .flatMap { it.getBindings() } 75820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .filter { it.requiresOldValue() } 75920c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .groupBy { it.getExpr() } 76020c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .forEach { 76120c7182163d99575d382e065f5a5fe45ed6b87e2George Mount val flagSet = it.key.dirtyFlagSet 76220c7182163d99575d382e065f5a5fe45ed6b87e2George Mount tab("if (${tmpDirtyFlags.mapOr(flagSet) { suffix, index -> 76320c7182163d99575d382e065f5a5fe45ed6b87e2George Mount "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 76420c7182163d99575d382e065f5a5fe45ed6b87e2George Mount }.joinToString(" || ") 76520c7182163d99575d382e065f5a5fe45ed6b87e2George Mount }) {") { 76620c7182163d99575d382e065f5a5fe45ed6b87e2George Mount it.value.first().getComponentExpressions().forEach { expr -> 76720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount tab("this.${expr.oldValueName} = ${expr.toCode(false).generate()};") 76820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 769d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 770d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 771d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7725bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar includedBinders.filter{it.isUsed()}.forEach { binder -> 7734c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("${binder.fieldName}.executePendingBindings();") 7747551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 77596e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{ 776de38dd3ef0577d25b2d59863603abe5750d0c231George Mount it.isUsed() && it.getResolvedType() != null && it.getResolvedType().extendsViewStub() 777de38dd3ef0577d25b2d59863603abe5750d0c231George Mount }.forEach { 778de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("if (${it.fieldName}.getBinding() != null) {") { 779de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("${it.fieldName}.getBinding().executePendingBindings();") 780de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 781de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("}") 782de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 783d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7840fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 785d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 786d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 787d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar fun readWithDependants(expr : Expr, mJustRead : MutableList<Expr>, batch : MutableList<Expr>, 788d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tmpDirtyFlags : FlagSet, inheritedFlags : FlagSet? = null) : KCode = kcode("") { 789d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mJustRead.add(expr) 790b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("%s / readWithDependants %s", className, expr.getUniqueKey()); 791d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = expr.shouldReadFlagSet 792d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val needsIfWrapper = inheritedFlags == null || !flagSet.bitsEqual(inheritedFlags) 793b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("flag set:%s . inherited flags: %s. need another if: %s", flagSet, inheritedFlags, needsIfWrapper); 794d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val ifClause = "if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 79543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 79643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.joinToString(" || ") 797d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar })" 798d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 799d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val readCode = kcode("") { 800e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar if (expr.canBeEvaluatedToAVariable() && !expr.isVariable()) { 801d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // it is not a variable read it. 802d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("// read ${expr.getUniqueKey()}") 803d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // create an if case for all dependencies that might be null 804d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val nullables = expr.getDependencies().filter { 805e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount it.isMandatory() && it.getOther().getResolvedType().isNullable() 80674f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyar }.map { it.getOther() } 807d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (!expr.isEqualityCheck() && nullables.isNotEmpty()) { 808019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab ("if ( ${nullables.map { "${it.executePendingLocalName} != null" }.joinToString(" && ")}) {") { 809019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("${expr.executePendingLocalName}").app(" = ", expr.toCode(true)).app(";") 810d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 811d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 812d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } else { 813019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("${expr.executePendingLocalName}").app(" = ", expr.toCode(true)).app(";") 814d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8157920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount if (expr.isObservable()) { 816019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("updateRegistration(${expr.getId()}, ${expr.executePendingLocalName});") 817d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8180fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 819d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 8200fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar // if I am the condition for an expression, set its flag 8210fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val conditionals = expr.getDependants().filter { !it.isConditional() 8220fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar && it.getDependant() is TernaryExpr && (it.getDependant() as TernaryExpr).getPred() == expr } 8230fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar .map { it.getDependant() } 8240fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar if (conditionals.isNotEmpty()) { 8250fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// setting conditional flags") 826019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("if (${expr.executePendingLocalName}) {") { 8270fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar conditionals.forEach { 8280fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val set = it.getRequirementFlagSet(true) 8290fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar mDirtyFlags.mapOr(set) { suffix , index -> 8300fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 831d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 832d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 833d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8340fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("} else {") { 8350fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar conditionals.forEach { 8360fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val set = it.getRequirementFlagSet(false) 8370fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar mDirtyFlags.mapOr(set) { suffix , index -> 8380fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 8390fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 8400fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 8410fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } tab("}") 842d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8430fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar 844d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val chosen = expr.getDependants().filter { 845d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val dependant = it.getDependant() 846d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar batch.contains(dependant) && 847d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar dependant.shouldReadFlagSet.andNot(flagSet).isEmpty() && 848d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar dependant.shouldReadNow(mJustRead) 849d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 850d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (chosen.isNotEmpty()) { 851d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val nextInheritedFlags = if (needsIfWrapper) flagSet else inheritedFlags 852d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar chosen.forEach { 853d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readWithDependants(it.getDependant(), mJustRead, batch, tmpDirtyFlags, nextInheritedFlags)) 854d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 855d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 856d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 857d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar if (needsIfWrapper) { 858d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tab(ifClause) { 859d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar app(" {") 860d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readCode) 861d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 862d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tab("}") 863d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } else { 864d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readCode) 865d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 866d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 86743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 868dea555cf42dc3583604699c8c018d22681f56166George Mount fun declareFactories() = kcode("") { 869081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount nl("public static ${baseClassName} inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot) {") { 870081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount tab("return android.databinding.DataBindingUtil.<${baseClassName}>inflate(inflater, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, root, attachToRoot);") 871081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount } 872081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount nl("}") 87396e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (!layoutBinder.isMerge()) { 874081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount nl("public static ${baseClassName} inflate(android.view.LayoutInflater inflater) {") { 8759bdb2415487832e88a05c7bd19391b05440b468eGeorge Mount tab("return bind(inflater.inflate(${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, null, false));") 87696e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 87796e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 87896e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public static ${baseClassName} bind(android.view.View view) {") { 87996e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("if (!\"${layoutBinder.getTag()}_0\".equals(view.getTag())) {") { 880f80b08430f11515ff944f89006799f21545602b9George Mount tab("throw new RuntimeException(\"view tag isn't correct on view:\" + view.getTag());") 88196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 88296e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("}") 88396e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("return new ${baseClassName}(view);") 88496e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 88596e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 886dea555cf42dc3583604699c8c018d22681f56166George Mount } 887dea555cf42dc3583604699c8c018d22681f56166George Mount } 888dea555cf42dc3583604699c8c018d22681f56166George Mount 8894c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount public fun writeBaseClass() : String = 89043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar kcode("package ${layoutBinder.getPackage()};") { 891fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.Bindable;") 892fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.DataBindingUtil;") 893fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.ViewDataBinding;") 8944c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("public abstract class ${baseClassName} extends ViewDataBinding {") 89596e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 896de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("public final ${it.interfaceType} ${it.fieldName};") 89734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 89834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 89934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("protected ${baseClassName}(android.view.View root_, int localFieldCount") { 90096e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 901019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab(", ${it.interfaceType} ${it.constructorParamName}") 90234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 90334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 90434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab(") {") { 90534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("super(root_, localFieldCount);") 90696e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 907019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("this.${it.fieldName} = ${it.constructorParamName};") 90834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 9094c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 9104c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 9114c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("") 91243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar variables.forEach { 91318243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.getUserDefinedType() != null) { 914895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar val type = ModelAnalyzer.getInstance().applyImports(it.getUserDefinedType(), model.getImports()) 915019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("public abstract void ${it.setterName}(${type} ${it.readableName});") 91618243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 91743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 9189bdb2415487832e88a05c7bd19391b05440b468eGeorge Mount tab("public static ${baseClassName} inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot) {") { 919081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount tab("return DataBindingUtil.<${baseClassName}>inflate(inflater, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, root, attachToRoot);") 92043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 9214c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 9229bdb2415487832e88a05c7bd19391b05440b468eGeorge Mount tab("public static ${baseClassName} inflate(android.view.LayoutInflater inflater) {") { 9239bdb2415487832e88a05c7bd19391b05440b468eGeorge Mount tab("return DataBindingUtil.<${baseClassName}>inflate(inflater, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, null, false);") 9244c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 9254c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 9264c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public static ${baseClassName} bind(android.view.View view) {") { 927ed6428586a939e00d9e66314d5cf1056ad48767eGeorge Mount tab("return (${baseClassName})bind(view, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()});") 9284c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 9294c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 93043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar nl("}") 93143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.generate() 932dea555cf42dc3583604699c8c018d22681f56166George Mount} 933