LayoutBinderWriter.kt revision e9b33bac04bb1ce1444d7f1744fcec1ecd3a57da
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.ext.joinToCamelCaseAsVar 22fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.BindingTarget 23fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.IdentifierExpr 24fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.util.Log 25d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.BitSet 26fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ExprModel 27d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.Arrays 28c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mountimport android.databinding.tool.expr.BitShiftExpr 29fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.TernaryExpr 30fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.FieldAccessExpr 31fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ComparisonExpr 32fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.GroupExpr 33c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mountimport android.databinding.tool.expr.InstanceOfExpr 34fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.MathExpr 35fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.MethodCallExpr 36fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.StaticIdentifierExpr 37fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.SymbolExpr 38c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mountimport android.databinding.tool.expr.UnaryExpr 39fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.ext.androidId 40fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.ext.lazy 41fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.ext.br 42fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ResourceExpr 43fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.BracketExpr 44e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarimport android.databinding.tool.ext; 45e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarimport android.databinding.tool.util.Log 46e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarimport java.util.BitSet 47e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarimport java.util.Arrays 48fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.Callable 49fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelAnalyzer 5096e1c821dd446d1ed78f8ae61131550588f60a24George Mountimport java.util.ArrayList 5134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport java.util.HashMap 5243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 53d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun String.stripNonJava() = this.split("[^a-zA-Z0-9]").map{ it.trim() }.joinToCamelCaseAsVar() 54d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 55019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarenum class Scope { 56019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar FIELD 57019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar METHOD 58019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar FLAG 59019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar EXECUTE_PENDING_METHOD 60019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar CONSTRUCTOR_PARAM 61019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar} 62019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar 63d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarclass ExprModelExt { 64019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val usedFieldNames = hashMapOf<Scope, MutableSet<String>>(); 65019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar { 66019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Scope.values().forEach { usedFieldNames[it] = hashSetOf<String>() } 67019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar } 68d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val localizedFlags = arrayListOf<FlagSet>() 69d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 70d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun localizeFlag(set : FlagSet, name:String) : FlagSet { 71d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar localizedFlags.add(set) 72019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val result = getUniqueName(name, Scope.FLAG) 73d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar set.setLocalName(result) 74d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return set 75d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 76d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 77019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar fun getUniqueName(base : String, scope : Scope) : String { 78d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var candidate = base 79d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var i = 0 80019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar while (usedFieldNames[scope].contains(candidate)) { 81d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar i ++ 82d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar candidate = base + i 83d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 84019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar usedFieldNames[scope].add(candidate) 85d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return candidate 86d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 87d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 88d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 89de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval ExprModel.ext by Delegates.lazy { target : ExprModel -> 90d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar ExprModelExt() 91d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 92d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 93019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getUniqueFieldName(base : String) : String = ext.getUniqueName(base, Scope.FIELD) 94019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getUniqueMethodName(base : String) : String = ext.getUniqueName(base, Scope.METHOD) 95019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getUniqueFlagName(base : String) : String = ext.getUniqueName(base, Scope.FLAG) 96019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getConstructorParamName(base : String) : String = ext.getUniqueName(base, Scope.CONSTRUCTOR_PARAM) 97d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 98d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun ExprModel.localizeFlag(set : FlagSet, base : String) : FlagSet = ext.localizeFlag(set, base) 99d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 100019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar// not necessarily unique. Uniqueness is solved per scope 101019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval BindingTarget.readableName by Delegates.lazy { target: BindingTarget -> 10200da715547ee7d5d38a3b8576090ca427a94daa5George Mount if (target.getId() == null) { 103019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar "boundView" + indexFromTag(target.getTag()) 10400da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 105019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar target.getId().androidId().stripNonJava() 10600da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 107d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 1087551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 109de38dd3ef0577d25b2d59863603abe5750d0c231George Mountfun BindingTarget.superConversion(variable : String) : String { 11096e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (getResolvedType() != null && getResolvedType().extendsViewStub()) { 111de38dd3ef0577d25b2d59863603abe5750d0c231George Mount return "new android.databinding.ViewStubProxy((android.view.ViewStub) ${variable})" 112de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } else { 113de38dd3ef0577d25b2d59863603abe5750d0c231George Mount return "(${interfaceType}) ${variable}" 114de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 115de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 116de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 117019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval BindingTarget.fieldName : String by Delegates.lazy { target : BindingTarget -> 118019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val name : String 119019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar if (target.getId() == null) { 120019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar name = "m${target.readableName}" 121019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar } else { 122019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar name = target.readableName 12334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 124019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar target.getModel().getUniqueFieldName(name) 125d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 126d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 127de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.androidId by Delegates.lazy { target : BindingTarget -> 12843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar "R.id.${target.getId().androidId()}" 129d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 130d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 131de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.interfaceType by Delegates.lazy { target : BindingTarget -> 132de38dd3ef0577d25b2d59863603abe5750d0c231George Mount if (target.getResolvedType() != null && target.getResolvedType().extendsViewStub()) { 133de38dd3ef0577d25b2d59863603abe5750d0c231George Mount "android.databinding.ViewStubProxy" 134de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } else { 135de38dd3ef0577d25b2d59863603abe5750d0c231George Mount target.getInterfaceType() 136de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 137de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 138de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 139019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval BindingTarget.constructorParamName by Delegates.lazy { target : BindingTarget -> 140019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar target.getModel().getConstructorParamName(target.readableName) 141d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 142d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 143019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar// not necessarily unique. Uniqueness is decided per scope 144de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.readableName by Delegates.lazy { expr : Expr -> 145019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val stripped = "${expr.getUniqueKey().stripNonJava()}" 146019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Log.d { "readableUniqueName for [${System.identityHashCode(expr)}] ${expr.getUniqueKey()} is $stripped" } 147019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar stripped 148de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 149de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 150de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.fieldName by Delegates.lazy { expr : Expr -> 151019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueFieldName("m${expr.readableName.capitalize()}") 152d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 153d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 154019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval Expr.executePendingLocalName by Delegates.lazy { expr : Expr -> 155019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar if(expr.isVariable()) expr.fieldName else "${expr.getModel().ext.getUniqueName(expr.readableName, Scope.EXECUTE_PENDING_METHOD)}" 156d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 157d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 158de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.setterName by Delegates.lazy { expr : Expr -> 159019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueMethodName("set${expr.readableName.capitalize()}") 160d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 161d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 162de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.onChangeName by Delegates.lazy { expr : Expr -> 163019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueMethodName("onChange${expr.readableName.capitalize()}") 164d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 165d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 166de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.getterName by Delegates.lazy { expr : Expr -> 167019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueMethodName("get${expr.readableName.capitalize()}") 168d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 169d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 170de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.dirtyFlagName by Delegates.lazy { expr : Expr -> 171019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueFlagName("sFlag${expr.readableName.capitalize()}") 172d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 173d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 174d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 175e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarfun Expr.toCode(full : Boolean = false) : KCode = CodeGenUtil.toCode(this, full) 176d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 177d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.isVariable() = this is IdentifierExpr && this.isDynamic() 178d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 179d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.conditionalFlagName(output : Boolean, suffix : String) = "${dirtyFlagName}_${output}$suffix" 180d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 181d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 182de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.dirtyFlagSet by Delegates.lazy { expr : Expr -> 183d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getInvalidFlags(), expr.getModel().getFlagBucketCount()) 184d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 185d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 186de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.invalidateFlagSet by Delegates.lazy { expr : Expr -> 187d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getId()) 188d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 189d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 190de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.shouldReadFlagSet by Delegates.lazy { expr : Expr -> 191d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getShouldReadFlags(), expr.getModel().getFlagBucketCount()) 192d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 193d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 194de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.conditionalFlags by Delegates.lazy { expr : Expr -> 195d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar arrayListOf(FlagSet(expr.getRequirementFlagIndex(false)), 196d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getRequirementFlagIndex(true))) 197d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 198d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 199d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.getRequirementFlagSet(expected : Boolean) : FlagSet = conditionalFlags[if(expected) 1 else 0] 200d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 201d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.notEmpty(cb : (suffix : String, value : Long) -> Unit) { 202d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar buckets.withIndex().forEach { 203d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (it.value != 0L) { 204d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar cb(getWordSuffix(it.index), buckets[it.index]) 205d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 206d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 207d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 208d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 209d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.getWordSuffix(wordIndex : Int) : String { 210d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return if(wordIndex == 0) "" else "_${wordIndex}" 211d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 212d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 213d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.localValue(bucketIndex : Int) = 214d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar if (getLocalName() == null) binaryCode(bucketIndex) 215d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar else "${getLocalName()}${getWordSuffix(bucketIndex)}" 216d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 217d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyarfun FlagSet.binaryCode(bucketIndex : Int) = longToBinary(buckets[bucketIndex]) 218d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 219d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 220d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyarfun longToBinary(l : Long) = 221d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar "0b${java.lang.Long.toBinaryString(l)}L" 222d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 223d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun <T> FlagSet.mapOr(other : FlagSet, cb : (suffix : String, index : Int) -> T) : List<T> { 224d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val min = Math.min(buckets.size(), other.buckets.size()) 225d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val result = arrayListOf<T>() 226d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in 0..(min - 1)) { 227d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // if these two can match by any chance, call the callback 228d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (intersect(other, i)) { 229d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar result.add(cb(getWordSuffix(i), i)) 230d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 231d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 232d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return result 233d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 234d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 23596e1c821dd446d1ed78f8ae61131550588f60a24George Mountfun indexFromTag(tag : String) : kotlin.Int { 23696e1c821dd446d1ed78f8ae61131550588f60a24George Mount val startIndex : kotlin.Int 2377ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount if (tag.startsWith("binding_")) { 2387ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount startIndex = "binding_".length(); 23996e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 24096e1c821dd446d1ed78f8ae61131550588f60a24George Mount startIndex = tag.lastIndexOf('_') + 1 24196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 24296e1c821dd446d1ed78f8ae61131550588f60a24George Mount return Integer.parseInt(tag.substring(startIndex)) 24396e1c821dd446d1ed78f8ae61131550588f60a24George Mount} 24496e1c821dd446d1ed78f8ae61131550588f60a24George Mount 24543596c2b2997e40b709627419732100d78a62ff0Yigit Boyarclass LayoutBinderWriter(val layoutBinder : LayoutBinder) { 246d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val model = layoutBinder.getModel() 24734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val indices = HashMap<BindingTarget, kotlin.Int>() 24843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val mDirtyFlags by Delegates.lazy { 24943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val fs = FlagSet(BitSet(), model.getFlagBucketCount()); 25043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Arrays.fill(fs.buckets, -1) 25143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs.setDynamic(true) 25243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.localizeFlag(fs, "mDirtyFlags") 25343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs 254d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 255d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 25643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val dynamics by Delegates.lazy { model.getExprMap().values().filter { it.isDynamic() } } 257dea555cf42dc3583604699c8c018d22681f56166George Mount val className = layoutBinder.getImplementationName() 258d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 259dea555cf42dc3583604699c8c018d22681f56166George Mount val baseClassName = "${layoutBinder.getClassName()}" 260d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 2617551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar val includedBinders by Delegates.lazy { 2627551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar layoutBinder.getBindingTargets().filter { it.isBinder() } 2637551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 2647551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 26543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val variables by Delegates.lazy { 26643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.getExprMap().values().filterIsInstance(javaClass<IdentifierExpr>()).filter { it.isVariable() } 26743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 268d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 2695bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar val usedVariables by Delegates.lazy { 2705bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar variables.filter {it.isUsed()} 2715bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 272d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 27396e1c821dd446d1ed78f8ae61131550588f60a24George Mount public fun write(minSdk : kotlin.Int) : String { 2745bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar layoutBinder.resolveWhichExpressionsAreUsed() 27534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount calculateIndices(); 2765bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar return kcode("package ${layoutBinder.getPackage()};") { 277a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar nl("import ${layoutBinder.getModulePackage()}.R;") 278a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar nl("import ${layoutBinder.getModulePackage()}.BR;") 2795bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("import android.view.View;") 280dea555cf42dc3583604699c8c018d22681f56166George Mount val classDeclaration : String 281dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 282dea555cf42dc3583604699c8c018d22681f56166George Mount classDeclaration = "${className} extends ${baseClassName}" 283dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 284dea555cf42dc3583604699c8c018d22681f56166George Mount classDeclaration = "${className} extends android.databinding.ViewDataBinding" 285dea555cf42dc3583604699c8c018d22681f56166George Mount } 286dea555cf42dc3583604699c8c018d22681f56166George Mount nl("public class ${classDeclaration} {") { 2874c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(declareIncludeViews()) 2885bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareViews()) 2895bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareVariables()) 29096e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab(declareConstructor(minSdk)) 2915bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareInvalidateAll()) 2925bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareLog()) 2935bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareSetVariable()) 2945bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(variableSettersAndGetters()) 2955bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(onFieldChange()) 2965bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 2974c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(executePendingBindings()) 2985bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 2995bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareDirtyFlags()) 300dea555cf42dc3583604699c8c018d22681f56166George Mount if (!layoutBinder.hasVariations()) { 301dea555cf42dc3583604699c8c018d22681f56166George Mount tab(declareFactories()) 302dea555cf42dc3583604699c8c018d22681f56166George Mount } 3035bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 3045bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 3055bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(flagMapping()) 3065bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("//end") 3075bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar }.generate() 3085bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 30934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fun calculateIndices() : Unit { 31096e1c821dd446d1ed78f8ae61131550588f60a24George Mount val taggedViews = layoutBinder.getBindingTargets().filter{ 31196e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && it.getTag() != null && !it.isBinder() 31234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 31396e1c821dd446d1ed78f8ae61131550588f60a24George Mount taggedViews.forEach { 31496e1c821dd446d1ed78f8ae61131550588f60a24George Mount indices.put(it, indexFromTag(it.getTag())) 31596e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 31696e1c821dd446d1ed78f8ae61131550588f60a24George Mount val indexStart = maxIndex() + 1 31796e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getBindingTargets().filter{ 31896e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !taggedViews.contains(it) 31996e1c821dd446d1ed78f8ae61131550588f60a24George Mount }.withIndex().forEach { 32096e1c821dd446d1ed78f8ae61131550588f60a24George Mount indices.put(it.value, it.index + indexStart) 32134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 32234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 3234c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun declareIncludeViews() = kcode("") { 32496e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("private static final android.databinding.ViewDataBinding.IncludedLayoutIndex[][] sIncludes;") 3254c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("private static final android.util.SparseIntArray sViewsWithIds;") 3264c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("static {") { 3274c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount val hasBinders = layoutBinder.getBindingTargets().firstOrNull{ it.isUsed() && it.isBinder()} != null 3284c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount if (!hasBinders) { 3294c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sIncludes = null;") 33000da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 33196e1c821dd446d1ed78f8ae61131550588f60a24George Mount val numBindings = layoutBinder.getBindingTargets().filter{ it.isUsed() }.count() 33296e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("sIncludes = new android.databinding.ViewDataBinding.IncludedLayoutIndex[${numBindings}][];") 33396e1c821dd446d1ed78f8ae61131550588f60a24George Mount val includeMap = HashMap<BindingTarget, ArrayList<BindingTarget>>() 33496e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getBindingTargets().filter{ it.isUsed() && it.isBinder() }.forEach { 33596e1c821dd446d1ed78f8ae61131550588f60a24George Mount val includeTag = it.getTag(); 33696e1c821dd446d1ed78f8ae61131550588f60a24George Mount val parent = layoutBinder.getBindingTargets().firstOrNull { 33796e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !it.isBinder() && includeTag.equals(it.getTag()) 33896e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 33996e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (parent == null) { 34096e1c821dd446d1ed78f8ae61131550588f60a24George Mount throw IllegalStateException("Could not find parent of include file") 34196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 34296e1c821dd446d1ed78f8ae61131550588f60a24George Mount var list = includeMap.get(parent) 34396e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (list == null) { 34496e1c821dd446d1ed78f8ae61131550588f60a24George Mount list = ArrayList<BindingTarget>() 34596e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.put(parent, list) 34696e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 34796e1c821dd446d1ed78f8ae61131550588f60a24George Mount list.add(it) 3484c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 34996e1c821dd446d1ed78f8ae61131550588f60a24George Mount 35096e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.keySet().forEach { 35196e1c821dd446d1ed78f8ae61131550588f60a24George Mount val index = indices.get(it) 35296e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("sIncludes[${index}] = new android.databinding.ViewDataBinding.IncludedLayoutIndex[] {") { 35396e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.get(it).forEach { 35496e1c821dd446d1ed78f8ae61131550588f60a24George Mount val bindingIndex = indices.get(it) 35596e1c821dd446d1ed78f8ae61131550588f60a24George Mount val layoutName = it.getIncludedLayout() 35696e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("new android.databinding.ViewDataBinding.IncludedLayoutIndex(\"${layoutName}\", ${bindingIndex}, R.layout.${layoutName}),") 35796e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 35896e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 35996e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("};") 36096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 36196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 36296e1c821dd446d1ed78f8ae61131550588f60a24George Mount val viewsWithIds = layoutBinder.getBindingTargets().filter { 36396e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !it.isBinder() && (!it.supportsTag() || (it.getId() != null && it.getTag() == null)) 36400da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 36596e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (viewsWithIds.isEmpty()) { 3664c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = null;") 36700da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 3684c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = new android.util.SparseIntArray();") 36996e1c821dd446d1ed78f8ae61131550588f60a24George Mount viewsWithIds.forEach { 37034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("sViewsWithIds.put(${it.androidId}, ${indices.get(it)});") 3714c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 37200da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 3734c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 3744c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("}") 3754c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 37696e1c821dd446d1ed78f8ae61131550588f60a24George Mount 37796e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun maxIndex() : kotlin.Int { 37896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val maxIndex = indices.values().max() 37996e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (maxIndex == null) { 38096e1c821dd446d1ed78f8ae61131550588f60a24George Mount return -1 38196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 38296e1c821dd446d1ed78f8ae61131550588f60a24George Mount return maxIndex 38396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 38496e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 38596e1c821dd446d1ed78f8ae61131550588f60a24George Mount 38696e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun declareConstructor(minSdk : kotlin.Int) = kcode("") { 38796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val bindingCount = maxIndex() + 1 38896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val parameterType : String 38996e1c821dd446d1ed78f8ae61131550588f60a24George Mount val superParam : String 39096e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (layoutBinder.isMerge()) { 39196e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View[]" 39296e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root[0]" 39396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 39496e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View" 39596e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root" 39696e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 39796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val rootTagsSupported = minSdk >= 14 398dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 399dea555cf42dc3583604699c8c018d22681f56166George Mount nl("") 40096e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public ${className}(${parameterType} root) {") { 40196e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("this(${superParam}, mapBindings(root, ${bindingCount}, sIncludes, sViewsWithIds));") 402dea555cf42dc3583604699c8c018d22681f56166George Mount } 403dea555cf42dc3583604699c8c018d22681f56166George Mount nl("}") 40496e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("private ${className}(${parameterType} root, Object[] bindings) {") { 40596e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("super(${superParam}, ${model.getObservables().size()}") { 40696e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter { it.getId() != null }.forEach { 407dea555cf42dc3583604699c8c018d22681f56166George Mount tab(", ${fieldConversion(it)}") 40834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 409dea555cf42dc3583604699c8c018d22681f56166George Mount tab(");") 41034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 41134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 412dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 41396e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public ${baseClassName}(${parameterType} root) {") { 41496e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("super(${superParam}, ${model.getObservables().size()});") 41596e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("final Object[] bindings = mapBindings(root, ${bindingCount}, sIncludes, sViewsWithIds);") 416dea555cf42dc3583604699c8c018d22681f56166George Mount } 417dea555cf42dc3583604699c8c018d22681f56166George Mount } 41896e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("setRootTag(root);") 41996e1c821dd446d1ed78f8ae61131550588f60a24George Mount val taggedViews = layoutBinder.getSortedTargets().filter{it.isUsed()} 420dea555cf42dc3583604699c8c018d22681f56166George Mount taggedViews.forEach { 421dea555cf42dc3583604699c8c018d22681f56166George Mount if (!layoutBinder.hasVariations() || it.getId() == null) { 422dea555cf42dc3583604699c8c018d22681f56166George Mount tab("this.${it.fieldName} = ${fieldConversion(it)};") 423dea555cf42dc3583604699c8c018d22681f56166George Mount } 424dea555cf42dc3583604699c8c018d22681f56166George Mount if (!it.isBinder()) { 425de38dd3ef0577d25b2d59863603abe5750d0c231George Mount if (it.getResolvedType() != null && it.getResolvedType().extendsViewStub()) { 426de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("this.${it.fieldName}.setContainingBinding(this);") 427de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 42896e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (it.supportsTag() && it.getTag() != null && 4297ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount (rootTagsSupported || it.getTag().startsWith("binding_"))) { 430dea555cf42dc3583604699c8c018d22681f56166George Mount val originalTag = it.getOriginalTag(); 431dea555cf42dc3583604699c8c018d22681f56166George Mount var tagValue = "null" 432dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag != null) { 433dea555cf42dc3583604699c8c018d22681f56166George Mount tagValue = "\"${originalTag}\"" 434dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@")) { 435dea555cf42dc3583604699c8c018d22681f56166George Mount var packageName = layoutBinder.getModulePackage() 436dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@android:")) { 437dea555cf42dc3583604699c8c018d22681f56166George Mount packageName = "android" 43800da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 439dea555cf42dc3583604699c8c018d22681f56166George Mount val slashIndex = originalTag.indexOf('/') 440dea555cf42dc3583604699c8c018d22681f56166George Mount val resourceId = originalTag.substring(slashIndex + 1) 441dea555cf42dc3583604699c8c018d22681f56166George Mount tagValue = "root.getResources().getString(${packageName}.R.string.${resourceId})" 44200da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 44300da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 444dea555cf42dc3583604699c8c018d22681f56166George Mount tab("this.${it.fieldName}.setTag(${tagValue});") 4457551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 446d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 447d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 448dea555cf42dc3583604699c8c018d22681f56166George Mount tab("invalidateAll();"); 4490fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 450d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 451d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 452dea555cf42dc3583604699c8c018d22681f56166George Mount fun fieldConversion(target : BindingTarget) : String { 453dea555cf42dc3583604699c8c018d22681f56166George Mount if (!target.isUsed()) { 454dea555cf42dc3583604699c8c018d22681f56166George Mount return "null" 455dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 45696e1c821dd446d1ed78f8ae61131550588f60a24George Mount val index = indices.get(target) 457dea555cf42dc3583604699c8c018d22681f56166George Mount if (index == null) { 45896e1c821dd446d1ed78f8ae61131550588f60a24George Mount throw IllegalStateException("Unknown binding target") 459dea555cf42dc3583604699c8c018d22681f56166George Mount } 46096e1c821dd446d1ed78f8ae61131550588f60a24George Mount val variableName = "bindings[${index}]" 461dea555cf42dc3583604699c8c018d22681f56166George Mount return target.superConversion(variableName) 462dea555cf42dc3583604699c8c018d22681f56166George Mount } 463dea555cf42dc3583604699c8c018d22681f56166George Mount } 464dea555cf42dc3583604699c8c018d22681f56166George Mount 465d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareInvalidateAll() = kcode("") { 4667551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("@Override") 4677551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("public void invalidateAll() {") { 468019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val fs = FlagSet(layoutBinder.getModel().getInvalidateAnyBitSet(), 469019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar layoutBinder.getModel().getFlagBucketCount()); 4701c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 4711c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar for (i in (0..(mDirtyFlags.buckets.size() - 1))) { 4721c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.localValue(i)} = ${fs.localValue(i)};") 4731c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 4741c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 4755bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar includedBinders.filter{it.isUsed()}.forEach { binder -> 4767551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar tab("${binder.fieldName}.invalidateAll();") 4777551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 478d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 4790fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 480d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 481d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 482d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareSetVariable() = kcode("") { 4830fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("public boolean setVariable(int variableId, Object variable) {") { 484d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch(variableId) {") { 4855bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 48643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab ("case ${it.getName().br()} :") { 487d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${it.setterName}((${it.getResolvedType().toJavaCode()}) variable);") 488d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 489d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 490d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 491d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 492d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 493d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 494d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 4950fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 496d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 497d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 498d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareLog() = kcode("") { 4990fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private void log(String msg, long i) {") { 500d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("""android.util.Log.d("BINDER", msg + ":" + Long.toHexString(i));""") 5010fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 5020fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 503d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 504d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 505d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun variableSettersAndGetters() = kcode("") { 5065bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar variables.filterNot{it.isUsed()}.forEach { 507019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar nl("public void ${it.setterName}(${it.getResolvedType().toJavaCode()} ${it.readableName}) {") { 5085bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("// not used, ignore") 5095bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5105bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 5115bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("") 5125bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("public ${it.getResolvedType().toJavaCode()} ${it.getterName}() {") { 5135bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("return ${it.getDefaultValue()};") 5145bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5155bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 5165bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5175bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 51818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.getUserDefinedType() != null) { 519019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar nl("public void ${it.setterName}(${it.getResolvedType().toJavaCode()} ${it.readableName}) {") { 52018243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.isObservable()) { 521019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("updateRegistration(${it.getId()}, ${it.readableName});"); 52218243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 523019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("this.${it.fieldName} = ${it.readableName};") 52418243f6f1b7527272ef4feccdf4327d80d9f2241George Mount // set dirty flags! 52518243f6f1b7527272ef4feccdf4327d80d9f2241George Mount val flagSet = it.invalidateFlagSet 5261c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 5271c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 5281c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.getLocalName()}$suffix |= ${flagSet.localValue(index)};") 5291c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 5301c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab ("}") 53118243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("super.requestRebind();") 532d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 53318243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 53418243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("") 53518243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("public ${it.getResolvedType().toJavaCode()} ${it.getterName}() {") { 53618243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("return ${it.fieldName};") 537d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 53818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 539d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 540d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 541d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 542d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 543d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun onFieldChange() = kcode("") { 54434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("@Override") 54534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {") { 5464c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("switch (localFieldId) {") { 547d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getObservables().forEach { 548d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("case ${it.getId()} :") { 549d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return ${it.onChangeName}((${it.getResolvedType().toJavaCode()}) object, fieldId);") 550d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 551d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 552d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 553d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 554d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 555d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 55634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 55734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 558d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 559d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getObservables().forEach { 560019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar nl("private boolean ${it.onChangeName}(${it.getResolvedType().toJavaCode()} ${it.readableName}, int fieldId) {") { 561d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch (fieldId) {", { 562d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val accessedFields: List<FieldAccessExpr> = it.getParents().filterIsInstance(javaClass<FieldAccessExpr>()) 563d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar accessedFields.filter { it.canBeInvalidated() } 564d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .groupBy { it.getName() } 565d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 56643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${it.key.br()}:") { 567d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val field = it.value.first() 5681c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 5691c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(field.invalidateFlagSet) { suffix, index -> 5701c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.localValue(index)} |= ${field.invalidateFlagSet.localValue(index)};") 5711c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 5721c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 573d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 574d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 575d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 576d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 57743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${"".br()}:") { 578d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.invalidateFlagSet 5791c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 5801c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 5811c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.getLocalName()}$suffix |= ${flagSet.localValue(index)};") 5821c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 5831c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 584d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 585d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 586d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 587d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) 588d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 589d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 590d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 59134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 59234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 593d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 594d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 595d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 596d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareViews() = kcode("// views") { 597dea555cf42dc3583604699c8c018d22681f56166George Mount val oneLayout = !layoutBinder.hasVariations(); 59896e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter {it.isUsed() && (oneLayout || it.getId() == null)}.forEach { 599dea555cf42dc3583604699c8c018d22681f56166George Mount val access : String 600dea555cf42dc3583604699c8c018d22681f56166George Mount if (oneLayout && it.getId() != null) { 601dea555cf42dc3583604699c8c018d22681f56166George Mount access = "public" 602dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 603dea555cf42dc3583604699c8c018d22681f56166George Mount access = "private" 604dea555cf42dc3583604699c8c018d22681f56166George Mount } 605dea555cf42dc3583604699c8c018d22681f56166George Mount nl("${access} final ${it.interfaceType} ${it.fieldName};") 606d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 607d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 608d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 609d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareVariables() = kcode("// variables") { 6105bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 6110fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private ${it.getResolvedType().toJavaCode()} ${it.fieldName};") 612d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 613d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 614d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 615d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareDirtyFlags() = kcode("// dirty flag") { 616d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.ext.localizedFlags.forEach { flag -> 617de38dd3ef0577d25b2d59863603abe5750d0c231George Mount flag.notEmpty { suffix, value -> 6180fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private") 619d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(" ", if(flag.isDynamic()) null else "static final"); 620d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar app(" ", " ${flag.type} ${flag.getLocalName()}$suffix = ${longToBinary(value)};") 621d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 622d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 623d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 624d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 625d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun flagMapping() = kcode("/* flag mapping") { 626d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (model.getFlagMapping() != null) { 627d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val mapping = model.getFlagMapping() 628d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in mapping.indices) { 629d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("flag $i: ${mapping[i]}") 630d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 631d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 632d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nl("flag mapping end*/") 633d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 634d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 6354c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun executePendingBindings() = kcode("") { 6360fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("@Override") 637e725f0d81e1b07e88f819be9a82181eeeb680dbfGeorge Mount nl("protected void executeBindings() {") { 638d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val tmpDirtyFlags = FlagSet(mDirtyFlags.buckets) 639d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tmpDirtyFlags.setLocalName("dirtyFlags"); 640d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in (0..mDirtyFlags.buckets.size() - 1)) { 6411c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${tmpDirtyFlags.type} ${tmpDirtyFlags.localValue(i)} = 0;") 642d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 6431c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 6441c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar for (i in (0..mDirtyFlags.buckets.size() - 1)) { 6451c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${tmpDirtyFlags.localValue(i)} = ${mDirtyFlags.localValue(i)};") 6461c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.localValue(i)} = 0;") 6471c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 6481c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 649e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar model.getPendingExpressions().filterNot {!it.canBeEvaluatedToAVariable() || it.isVariable()}.forEach { 650019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("${it.getResolvedType().toJavaCode()} ${it.executePendingLocalName} = ${it.getDefaultValue()};") 651d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 652019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Log.d {"writing executePendingBindings for $className"} 653d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar do { 65474f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyar val batch = ExprModel.filterShouldRead(model.getPendingExpressions()).toArrayList() 655019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Log.d {"batch: $batch"} 656d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val mJustRead = arrayListOf<Expr>() 657d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar while (!batch.none()) { 6580fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val readNow = batch.filter { it.shouldReadNow(mJustRead) } 659d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (readNow.isEmpty()) { 660d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar throw IllegalStateException("do not know what I can read. bailing out ${batch.joinToString("\n")}") 661d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 66243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Log.d { "new read now. batch size: ${batch.size()}, readNow size: ${readNow.size()}" } 663d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 664d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar readNow.forEach { 6650fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl(readWithDependants(it, mJustRead, batch, tmpDirtyFlags)) 666d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 667d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar batch.removeAll(mJustRead) 668d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 6690fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// batch finished") 670d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } while(model.markBitsRead()) 671d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 672d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // 67396e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter { it.isUsed() } 674d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .flatMap { it.getBindings() } 675d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .groupBy { it.getExpr() } 676d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 677d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.key.dirtyFlagSet 678d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 679d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 680d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }.joinToString(" || ") 681d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) {") { 682d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.value.forEach { binding -> 68397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("// api target ${binding.getMinApi()}") 68434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val fieldName : String 68534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount if (binding.getTarget().getViewClass(). 68634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount equals(binding.getTarget().getInterfaceType())) { 68734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fieldName = "this.${binding.getTarget().fieldName}" 68834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } else { 68934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fieldName = "((${binding.getTarget().getViewClass()}) this.${binding.getTarget().fieldName})" 69034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 691e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar val bindingCode = binding.toJavaCode(fieldName) 69297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar if (binding.getMinApi() > 1) { 6934c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("if(getBuildSdkInt() >= ${binding.getMinApi()}) {") { 69497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("$bindingCode;") 69597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 69697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("}") 69797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } else { 69897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("$bindingCode;") 69997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 700d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 701d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 702d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 703d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7045bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar includedBinders.filter{it.isUsed()}.forEach { binder -> 7054c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("${binder.fieldName}.executePendingBindings();") 7067551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 70796e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{ 708de38dd3ef0577d25b2d59863603abe5750d0c231George Mount it.isUsed() && it.getResolvedType() != null && it.getResolvedType().extendsViewStub() 709de38dd3ef0577d25b2d59863603abe5750d0c231George Mount }.forEach { 710de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("if (${it.fieldName}.getBinding() != null) {") { 711de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("${it.fieldName}.getBinding().executePendingBindings();") 712de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 713de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("}") 714de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 715d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7160fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 717d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 718d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 719d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar fun readWithDependants(expr : Expr, mJustRead : MutableList<Expr>, batch : MutableList<Expr>, 720d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tmpDirtyFlags : FlagSet, inheritedFlags : FlagSet? = null) : KCode = kcode("") { 721d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mJustRead.add(expr) 722019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Log.d { "$className / readWithDependants: ${expr.getUniqueKey()}" } 723d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = expr.shouldReadFlagSet 724d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val needsIfWrapper = inheritedFlags == null || !flagSet.bitsEqual(inheritedFlags) 725019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Log.d { "flag set:$flagSet . inherited flags: $inheritedFlags. need another if: $needsIfWrapper"} 726d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val ifClause = "if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 72743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 72843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.joinToString(" || ") 729d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar })" 730d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 731d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val readCode = kcode("") { 732e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar if (expr.canBeEvaluatedToAVariable() && !expr.isVariable()) { 733d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // it is not a variable read it. 734d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("// read ${expr.getUniqueKey()}") 735d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // create an if case for all dependencies that might be null 736d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val nullables = expr.getDependencies().filter { 737e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount it.isMandatory() && it.getOther().getResolvedType().isNullable() 73874f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyar }.map { it.getOther() } 739d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (!expr.isEqualityCheck() && nullables.isNotEmpty()) { 740019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab ("if ( ${nullables.map { "${it.executePendingLocalName} != null" }.joinToString(" && ")}) {") { 741019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("${expr.executePendingLocalName}").app(" = ", expr.toCode(true)).app(";") 742d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 743d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 744d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } else { 745019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("${expr.executePendingLocalName}").app(" = ", expr.toCode(true)).app(";") 746d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7477920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount if (expr.isObservable()) { 748019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("updateRegistration(${expr.getId()}, ${expr.executePendingLocalName});") 749d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7500fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 751d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 7520fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar // if I am the condition for an expression, set its flag 7530fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val conditionals = expr.getDependants().filter { !it.isConditional() 7540fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar && it.getDependant() is TernaryExpr && (it.getDependant() as TernaryExpr).getPred() == expr } 7550fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar .map { it.getDependant() } 7560fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar if (conditionals.isNotEmpty()) { 7570fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// setting conditional flags") 758019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("if (${expr.executePendingLocalName}) {") { 7590fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar conditionals.forEach { 7600fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val set = it.getRequirementFlagSet(true) 7610fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar mDirtyFlags.mapOr(set) { suffix , index -> 7620fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 763d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 764d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 765d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7660fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("} else {") { 7670fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar conditionals.forEach { 7680fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val set = it.getRequirementFlagSet(false) 7690fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar mDirtyFlags.mapOr(set) { suffix , index -> 7700fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 7710fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 7720fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 7730fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } tab("}") 774d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7750fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar 776d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val chosen = expr.getDependants().filter { 777d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val dependant = it.getDependant() 778d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar batch.contains(dependant) && 779d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar dependant.shouldReadFlagSet.andNot(flagSet).isEmpty() && 780d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar dependant.shouldReadNow(mJustRead) 781d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 782d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (chosen.isNotEmpty()) { 783d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val nextInheritedFlags = if (needsIfWrapper) flagSet else inheritedFlags 784d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar chosen.forEach { 785d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readWithDependants(it.getDependant(), mJustRead, batch, tmpDirtyFlags, nextInheritedFlags)) 786d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 787d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 788d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 789d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar if (needsIfWrapper) { 790d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tab(ifClause) { 791d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar app(" {") 792d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readCode) 793d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 794d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tab("}") 795d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } else { 796d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readCode) 797d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 798d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 79943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 800dea555cf42dc3583604699c8c018d22681f56166George Mount fun declareFactories() = kcode("") { 80196e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (!layoutBinder.isMerge()) { 8029bdb2415487832e88a05c7bd19391b05440b468eGeorge Mount tab("public static ${baseClassName} inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot) {") { 8039bdb2415487832e88a05c7bd19391b05440b468eGeorge Mount tab("return bind(inflater.inflate(${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, root, true));") 804dea555cf42dc3583604699c8c018d22681f56166George Mount } 80596e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 8069bdb2415487832e88a05c7bd19391b05440b468eGeorge Mount tab("public static ${baseClassName} inflate(android.view.LayoutInflater inflater) {") { 8079bdb2415487832e88a05c7bd19391b05440b468eGeorge Mount tab("return bind(inflater.inflate(${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, null, false));") 80896e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 80996e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 81096e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public static ${baseClassName} bind(android.view.View view) {") { 81196e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("if (!\"${layoutBinder.getTag()}_0\".equals(view.getTag())) {") { 81296e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("throw new RuntimeException(\"view tag isn't correct on view\");") 81396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 81496e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("}") 81596e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("return new ${baseClassName}(view);") 81696e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 81796e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 818dea555cf42dc3583604699c8c018d22681f56166George Mount } 819dea555cf42dc3583604699c8c018d22681f56166George Mount } 820dea555cf42dc3583604699c8c018d22681f56166George Mount 8214c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount public fun writeBaseClass() : String = 82243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar kcode("package ${layoutBinder.getPackage()};") { 823fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.Bindable;") 824fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.DataBindingUtil;") 825fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.ViewDataBinding;") 8264c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("public abstract class ${baseClassName} extends ViewDataBinding {") 82796e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 828de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("public final ${it.interfaceType} ${it.fieldName};") 82934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 83034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 83134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("protected ${baseClassName}(android.view.View root_, int localFieldCount") { 83296e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 833019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab(", ${it.interfaceType} ${it.constructorParamName}") 83434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 83534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 83634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab(") {") { 83734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("super(root_, localFieldCount);") 83896e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 839019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("this.${it.fieldName} = ${it.constructorParamName};") 84034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 8414c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 8424c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 8434c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("") 84443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar variables.forEach { 84518243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.getUserDefinedType() != null) { 846895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar //it.getExpandedUserDefinedType(ModelAnalyzer.getInstance()); 847895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar val type = ModelAnalyzer.getInstance().applyImports(it.getUserDefinedType(), model.getImports()) 848019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("public abstract void ${it.setterName}(${type} ${it.readableName});") 84918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 85043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 8519bdb2415487832e88a05c7bd19391b05440b468eGeorge Mount tab("public static ${baseClassName} inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot) {") { 8529bdb2415487832e88a05c7bd19391b05440b468eGeorge Mount tab("return DataBindingUtil.<${baseClassName}>inflate(inflater, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, root, true);") 85343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 8544c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 8559bdb2415487832e88a05c7bd19391b05440b468eGeorge Mount tab("public static ${baseClassName} inflate(android.view.LayoutInflater inflater) {") { 8569bdb2415487832e88a05c7bd19391b05440b468eGeorge Mount tab("return DataBindingUtil.<${baseClassName}>inflate(inflater, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, null, false);") 8574c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 8584c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 8594c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public static ${baseClassName} bind(android.view.View view) {") { 860ed6428586a939e00d9e66314d5cf1056ad48767eGeorge Mount tab("return (${baseClassName})bind(view, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()});") 8614c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 8624c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 86343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar nl("}") 86443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.generate() 865dea555cf42dc3583604699c8c018d22681f56166George Mount} 866