LayoutBinderWriter.kt revision c4a07bddb4dd5c3bfbecf4d87909c5b447ae56dc
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 54d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun String.stripNonJava() = this.split("[^a-zA-Z0-9]").map{ it.trim() }.joinToCamelCaseAsVar() 55d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 56019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarenum class Scope { 57019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar FIELD 58019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar METHOD 59019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar FLAG 60019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar EXECUTE_PENDING_METHOD 61019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar CONSTRUCTOR_PARAM 62019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar} 63019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar 64d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarclass ExprModelExt { 65019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val usedFieldNames = hashMapOf<Scope, MutableSet<String>>(); 66019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar { 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 155019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval Expr.executePendingLocalName by Delegates.lazy { expr : Expr -> 1564a81aabc49f6c881d960cd541adda7de9625277aYigit Boyar "${expr.getModel().ext.getUniqueName(expr.readableName, Scope.EXECUTE_PENDING_METHOD)}" 157d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 158d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 159de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.setterName by Delegates.lazy { expr : Expr -> 160019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueMethodName("set${expr.readableName.capitalize()}") 161d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 162d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 163de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.onChangeName by Delegates.lazy { expr : Expr -> 164019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueMethodName("onChange${expr.readableName.capitalize()}") 165d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 166d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 167de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.getterName by Delegates.lazy { expr : Expr -> 168019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueMethodName("get${expr.readableName.capitalize()}") 169d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 170d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 171de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.dirtyFlagName by Delegates.lazy { expr : Expr -> 172019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueFlagName("sFlag${expr.readableName.capitalize()}") 173d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 174d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 175d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 176e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarfun Expr.toCode(full : Boolean = false) : KCode = CodeGenUtil.toCode(this, full) 177d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 178d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.isVariable() = this is IdentifierExpr && this.isDynamic() 179d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 180d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.conditionalFlagName(output : Boolean, suffix : String) = "${dirtyFlagName}_${output}$suffix" 181d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 182d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 183de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.dirtyFlagSet by Delegates.lazy { expr : Expr -> 184d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getInvalidFlags(), expr.getModel().getFlagBucketCount()) 185d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 186d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 187de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.invalidateFlagSet by Delegates.lazy { expr : Expr -> 188d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getId()) 189d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 190d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 1917b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarval Expr.shouldReadFlagSet by Delegates.versionedLazy { expr : Expr -> 192d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getShouldReadFlags(), expr.getModel().getFlagBucketCount()) 193d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 194d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 195de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.conditionalFlags by Delegates.lazy { expr : Expr -> 196d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar arrayListOf(FlagSet(expr.getRequirementFlagIndex(false)), 197d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getRequirementFlagIndex(true))) 198d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 199d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 200d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.getRequirementFlagSet(expected : Boolean) : FlagSet = conditionalFlags[if(expected) 1 else 0] 201d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 202d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.notEmpty(cb : (suffix : String, value : Long) -> Unit) { 203d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar buckets.withIndex().forEach { 204d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (it.value != 0L) { 205d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar cb(getWordSuffix(it.index), buckets[it.index]) 206d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 207d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 208d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 209d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 210d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.getWordSuffix(wordIndex : Int) : String { 211d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return if(wordIndex == 0) "" else "_${wordIndex}" 212d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 213d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 214d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.localValue(bucketIndex : Int) = 215d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar if (getLocalName() == null) binaryCode(bucketIndex) 216d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar else "${getLocalName()}${getWordSuffix(bucketIndex)}" 217d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 218d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyarfun FlagSet.binaryCode(bucketIndex : Int) = longToBinary(buckets[bucketIndex]) 219d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 220d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 221d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyarfun longToBinary(l : Long) = 222d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar "0b${java.lang.Long.toBinaryString(l)}L" 223d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 224d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun <T> FlagSet.mapOr(other : FlagSet, cb : (suffix : String, index : Int) -> T) : List<T> { 225d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val min = Math.min(buckets.size(), other.buckets.size()) 226d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val result = arrayListOf<T>() 227d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in 0..(min - 1)) { 228d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // if these two can match by any chance, call the callback 229d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (intersect(other, i)) { 230d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar result.add(cb(getWordSuffix(i), i)) 231d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 232d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 233d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return result 234d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 235d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 23696e1c821dd446d1ed78f8ae61131550588f60a24George Mountfun indexFromTag(tag : String) : kotlin.Int { 23796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val startIndex : kotlin.Int 2387ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount if (tag.startsWith("binding_")) { 2397ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount startIndex = "binding_".length(); 24096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 24196e1c821dd446d1ed78f8ae61131550588f60a24George Mount startIndex = tag.lastIndexOf('_') + 1 24296e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 24396e1c821dd446d1ed78f8ae61131550588f60a24George Mount return Integer.parseInt(tag.substring(startIndex)) 24496e1c821dd446d1ed78f8ae61131550588f60a24George Mount} 24596e1c821dd446d1ed78f8ae61131550588f60a24George Mount 24643596c2b2997e40b709627419732100d78a62ff0Yigit Boyarclass LayoutBinderWriter(val layoutBinder : LayoutBinder) { 247d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val model = layoutBinder.getModel() 24834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val indices = HashMap<BindingTarget, kotlin.Int>() 24943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val mDirtyFlags by Delegates.lazy { 25043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val fs = FlagSet(BitSet(), model.getFlagBucketCount()); 25143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Arrays.fill(fs.buckets, -1) 25243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs.setDynamic(true) 25343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.localizeFlag(fs, "mDirtyFlags") 25443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs 255d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 256d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 25743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val dynamics by Delegates.lazy { model.getExprMap().values().filter { it.isDynamic() } } 258dea555cf42dc3583604699c8c018d22681f56166George Mount val className = layoutBinder.getImplementationName() 259d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 260dea555cf42dc3583604699c8c018d22681f56166George Mount val baseClassName = "${layoutBinder.getClassName()}" 261d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 2627551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar val includedBinders by Delegates.lazy { 2637551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar layoutBinder.getBindingTargets().filter { it.isBinder() } 2647551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 2657551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 26643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val variables by Delegates.lazy { 26743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.getExprMap().values().filterIsInstance(javaClass<IdentifierExpr>()).filter { it.isVariable() } 26843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 269d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 2705bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar val usedVariables by Delegates.lazy { 2715bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar variables.filter {it.isUsed()} 2725bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 273d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 27496e1c821dd446d1ed78f8ae61131550588f60a24George Mount public fun write(minSdk : kotlin.Int) : String { 2755bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar layoutBinder.resolveWhichExpressionsAreUsed() 27634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount calculateIndices(); 2775bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar return kcode("package ${layoutBinder.getPackage()};") { 278a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar nl("import ${layoutBinder.getModulePackage()}.R;") 279a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar nl("import ${layoutBinder.getModulePackage()}.BR;") 2805bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("import android.view.View;") 281dea555cf42dc3583604699c8c018d22681f56166George Mount val classDeclaration : String 282dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 283dea555cf42dc3583604699c8c018d22681f56166George Mount classDeclaration = "${className} extends ${baseClassName}" 284dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 285dea555cf42dc3583604699c8c018d22681f56166George Mount classDeclaration = "${className} extends android.databinding.ViewDataBinding" 286dea555cf42dc3583604699c8c018d22681f56166George Mount } 287dea555cf42dc3583604699c8c018d22681f56166George Mount nl("public class ${classDeclaration} {") { 2884c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(declareIncludeViews()) 2895bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareViews()) 2905bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareVariables()) 29196e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab(declareConstructor(minSdk)) 2925bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareInvalidateAll()) 293447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab(declareHasPendingBindings()) 2945bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareLog()) 2955bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareSetVariable()) 2965bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(variableSettersAndGetters()) 2975bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(onFieldChange()) 2985bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 2994c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(executePendingBindings()) 3005bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 3015bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareDirtyFlags()) 302dea555cf42dc3583604699c8c018d22681f56166George Mount if (!layoutBinder.hasVariations()) { 303dea555cf42dc3583604699c8c018d22681f56166George Mount tab(declareFactories()) 304dea555cf42dc3583604699c8c018d22681f56166George Mount } 3055bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 3065bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 3075bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(flagMapping()) 3085bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("//end") 3095bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar }.generate() 3105bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 31134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fun calculateIndices() : Unit { 31296e1c821dd446d1ed78f8ae61131550588f60a24George Mount val taggedViews = layoutBinder.getBindingTargets().filter{ 31396e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && it.getTag() != null && !it.isBinder() 31434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 31596e1c821dd446d1ed78f8ae61131550588f60a24George Mount taggedViews.forEach { 31696e1c821dd446d1ed78f8ae61131550588f60a24George Mount indices.put(it, indexFromTag(it.getTag())) 31796e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 31896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val indexStart = maxIndex() + 1 31996e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getBindingTargets().filter{ 32096e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !taggedViews.contains(it) 32196e1c821dd446d1ed78f8ae61131550588f60a24George Mount }.withIndex().forEach { 32296e1c821dd446d1ed78f8ae61131550588f60a24George Mount indices.put(it.value, it.index + indexStart) 32334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 32434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 3254c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun declareIncludeViews() = kcode("") { 32696e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("private static final android.databinding.ViewDataBinding.IncludedLayoutIndex[][] sIncludes;") 3274c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("private static final android.util.SparseIntArray sViewsWithIds;") 3284c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("static {") { 3294c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount val hasBinders = layoutBinder.getBindingTargets().firstOrNull{ it.isUsed() && it.isBinder()} != null 3304c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount if (!hasBinders) { 3314c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sIncludes = null;") 33200da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 33396e1c821dd446d1ed78f8ae61131550588f60a24George Mount val numBindings = layoutBinder.getBindingTargets().filter{ it.isUsed() }.count() 33496e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("sIncludes = new android.databinding.ViewDataBinding.IncludedLayoutIndex[${numBindings}][];") 33596e1c821dd446d1ed78f8ae61131550588f60a24George Mount val includeMap = HashMap<BindingTarget, ArrayList<BindingTarget>>() 33696e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getBindingTargets().filter{ it.isUsed() && it.isBinder() }.forEach { 33796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val includeTag = it.getTag(); 33896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val parent = layoutBinder.getBindingTargets().firstOrNull { 33996e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !it.isBinder() && includeTag.equals(it.getTag()) 34096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 34196e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (parent == null) { 34296e1c821dd446d1ed78f8ae61131550588f60a24George Mount throw IllegalStateException("Could not find parent of include file") 34396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 34496e1c821dd446d1ed78f8ae61131550588f60a24George Mount var list = includeMap.get(parent) 34596e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (list == null) { 34696e1c821dd446d1ed78f8ae61131550588f60a24George Mount list = ArrayList<BindingTarget>() 34796e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.put(parent, list) 34896e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 34996e1c821dd446d1ed78f8ae61131550588f60a24George Mount list.add(it) 3504c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 35196e1c821dd446d1ed78f8ae61131550588f60a24George Mount 35296e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.keySet().forEach { 35396e1c821dd446d1ed78f8ae61131550588f60a24George Mount val index = indices.get(it) 35496e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("sIncludes[${index}] = new android.databinding.ViewDataBinding.IncludedLayoutIndex[] {") { 35596e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.get(it).forEach { 35696e1c821dd446d1ed78f8ae61131550588f60a24George Mount val bindingIndex = indices.get(it) 35796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val layoutName = it.getIncludedLayout() 35896e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("new android.databinding.ViewDataBinding.IncludedLayoutIndex(\"${layoutName}\", ${bindingIndex}, R.layout.${layoutName}),") 35996e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 36096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 36196e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("};") 36296e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 36396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 36496e1c821dd446d1ed78f8ae61131550588f60a24George Mount val viewsWithIds = layoutBinder.getBindingTargets().filter { 36596e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !it.isBinder() && (!it.supportsTag() || (it.getId() != null && it.getTag() == null)) 36600da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 36796e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (viewsWithIds.isEmpty()) { 3684c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = null;") 36900da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 3704c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = new android.util.SparseIntArray();") 37196e1c821dd446d1ed78f8ae61131550588f60a24George Mount viewsWithIds.forEach { 37234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("sViewsWithIds.put(${it.androidId}, ${indices.get(it)});") 3734c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 37400da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 3754c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 3764c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("}") 3774c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 37896e1c821dd446d1ed78f8ae61131550588f60a24George Mount 37996e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun maxIndex() : kotlin.Int { 38096e1c821dd446d1ed78f8ae61131550588f60a24George Mount val maxIndex = indices.values().max() 38196e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (maxIndex == null) { 38296e1c821dd446d1ed78f8ae61131550588f60a24George Mount return -1 38396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 38496e1c821dd446d1ed78f8ae61131550588f60a24George Mount return maxIndex 38596e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 38696e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 38796e1c821dd446d1ed78f8ae61131550588f60a24George Mount 38896e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun declareConstructor(minSdk : kotlin.Int) = kcode("") { 38996e1c821dd446d1ed78f8ae61131550588f60a24George Mount val bindingCount = maxIndex() + 1 39096e1c821dd446d1ed78f8ae61131550588f60a24George Mount val parameterType : String 39196e1c821dd446d1ed78f8ae61131550588f60a24George Mount val superParam : String 39296e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (layoutBinder.isMerge()) { 39396e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View[]" 39496e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root[0]" 39596e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 39696e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View" 39796e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root" 39896e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 39996e1c821dd446d1ed78f8ae61131550588f60a24George Mount val rootTagsSupported = minSdk >= 14 400dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 401dea555cf42dc3583604699c8c018d22681f56166George Mount nl("") 40296e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public ${className}(${parameterType} root) {") { 40396e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("this(${superParam}, mapBindings(root, ${bindingCount}, sIncludes, sViewsWithIds));") 404dea555cf42dc3583604699c8c018d22681f56166George Mount } 405dea555cf42dc3583604699c8c018d22681f56166George Mount nl("}") 40696e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("private ${className}(${parameterType} root, Object[] bindings) {") { 40796e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("super(${superParam}, ${model.getObservables().size()}") { 40896e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter { it.getId() != null }.forEach { 409dea555cf42dc3583604699c8c018d22681f56166George Mount tab(", ${fieldConversion(it)}") 41034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 411dea555cf42dc3583604699c8c018d22681f56166George Mount tab(");") 41234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 41334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 414dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 41596e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public ${baseClassName}(${parameterType} root) {") { 41696e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("super(${superParam}, ${model.getObservables().size()});") 41796e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("final Object[] bindings = mapBindings(root, ${bindingCount}, sIncludes, sViewsWithIds);") 418dea555cf42dc3583604699c8c018d22681f56166George Mount } 419dea555cf42dc3583604699c8c018d22681f56166George Mount } 42096e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("setRootTag(root);") 42196e1c821dd446d1ed78f8ae61131550588f60a24George Mount val taggedViews = layoutBinder.getSortedTargets().filter{it.isUsed()} 422dea555cf42dc3583604699c8c018d22681f56166George Mount taggedViews.forEach { 423dea555cf42dc3583604699c8c018d22681f56166George Mount if (!layoutBinder.hasVariations() || it.getId() == null) { 424dea555cf42dc3583604699c8c018d22681f56166George Mount tab("this.${it.fieldName} = ${fieldConversion(it)};") 425dea555cf42dc3583604699c8c018d22681f56166George Mount } 426dea555cf42dc3583604699c8c018d22681f56166George Mount if (!it.isBinder()) { 427de38dd3ef0577d25b2d59863603abe5750d0c231George Mount if (it.getResolvedType() != null && it.getResolvedType().extendsViewStub()) { 428de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("this.${it.fieldName}.setContainingBinding(this);") 429de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 43096e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (it.supportsTag() && it.getTag() != null && 4317ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount (rootTagsSupported || it.getTag().startsWith("binding_"))) { 432dea555cf42dc3583604699c8c018d22681f56166George Mount val originalTag = it.getOriginalTag(); 433dea555cf42dc3583604699c8c018d22681f56166George Mount var tagValue = "null" 434dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag != null) { 435dea555cf42dc3583604699c8c018d22681f56166George Mount tagValue = "\"${originalTag}\"" 436dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@")) { 437dea555cf42dc3583604699c8c018d22681f56166George Mount var packageName = layoutBinder.getModulePackage() 438dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@android:")) { 439dea555cf42dc3583604699c8c018d22681f56166George Mount packageName = "android" 44000da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 441dea555cf42dc3583604699c8c018d22681f56166George Mount val slashIndex = originalTag.indexOf('/') 442dea555cf42dc3583604699c8c018d22681f56166George Mount val resourceId = originalTag.substring(slashIndex + 1) 443dea555cf42dc3583604699c8c018d22681f56166George Mount tagValue = "root.getResources().getString(${packageName}.R.string.${resourceId})" 44400da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 44500da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 446dea555cf42dc3583604699c8c018d22681f56166George Mount tab("this.${it.fieldName}.setTag(${tagValue});") 4477551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 448d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 449d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 450dea555cf42dc3583604699c8c018d22681f56166George Mount tab("invalidateAll();"); 4510fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 452d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 453d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 454dea555cf42dc3583604699c8c018d22681f56166George Mount fun fieldConversion(target : BindingTarget) : String { 455dea555cf42dc3583604699c8c018d22681f56166George Mount if (!target.isUsed()) { 456dea555cf42dc3583604699c8c018d22681f56166George Mount return "null" 457dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 45896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val index = indices.get(target) 459dea555cf42dc3583604699c8c018d22681f56166George Mount if (index == null) { 46096e1c821dd446d1ed78f8ae61131550588f60a24George Mount throw IllegalStateException("Unknown binding target") 461dea555cf42dc3583604699c8c018d22681f56166George Mount } 46296e1c821dd446d1ed78f8ae61131550588f60a24George Mount val variableName = "bindings[${index}]" 463dea555cf42dc3583604699c8c018d22681f56166George Mount return target.superConversion(variableName) 464dea555cf42dc3583604699c8c018d22681f56166George Mount } 465dea555cf42dc3583604699c8c018d22681f56166George Mount } 466dea555cf42dc3583604699c8c018d22681f56166George Mount 467d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareInvalidateAll() = kcode("") { 4687551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("@Override") 4697551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("public void invalidateAll() {") { 470019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val fs = FlagSet(layoutBinder.getModel().getInvalidateAnyBitSet(), 471019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar layoutBinder.getModel().getFlagBucketCount()); 4721c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 4731c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar for (i in (0..(mDirtyFlags.buckets.size() - 1))) { 4741c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.localValue(i)} = ${fs.localValue(i)};") 4751c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 4761c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 4775bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar includedBinders.filter{it.isUsed()}.forEach { binder -> 4787551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar tab("${binder.fieldName}.invalidateAll();") 4797551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 480d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 4810fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 482d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 483d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 484447971abca811b11b8c1d8e7bfaa294856d03c16George Mount fun declareHasPendingBindings() = kcode("") { 485447971abca811b11b8c1d8e7bfaa294856d03c16George Mount nl("@Override") 486447971abca811b11b8c1d8e7bfaa294856d03c16George Mount nl("public boolean hasPendingBindings() {") { 487447971abca811b11b8c1d8e7bfaa294856d03c16George Mount if (mDirtyFlags.buckets.size() > 0) { 488447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("synchronized(this) {") { 489447971abca811b11b8c1d8e7bfaa294856d03c16George Mount val flagCheck = 0.rangeTo(mDirtyFlags.buckets.size() - 1).map { 490447971abca811b11b8c1d8e7bfaa294856d03c16George Mount "${mDirtyFlags.localValue(it)} != 0" 491447971abca811b11b8c1d8e7bfaa294856d03c16George Mount }.joinToString(" || ") 492447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("if (${flagCheck}) {") { 493447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("return true;") 494447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 495447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("}") 496447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 497447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("}") 498447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 499447971abca811b11b8c1d8e7bfaa294856d03c16George Mount includedBinders.filter{it.isUsed()}.forEach { binder -> 500447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("if (${binder.fieldName}.hasPendingBindings()) {") { 501447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("return true;") 502447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 503447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("}") 504447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 505447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("return false;") 506447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 507447971abca811b11b8c1d8e7bfaa294856d03c16George Mount nl("}") 508447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 509447971abca811b11b8c1d8e7bfaa294856d03c16George Mount 510d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareSetVariable() = kcode("") { 5110fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("public boolean setVariable(int variableId, Object variable) {") { 512d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch(variableId) {") { 5135bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 51443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab ("case ${it.getName().br()} :") { 515d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${it.setterName}((${it.getResolvedType().toJavaCode()}) variable);") 516d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 517d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 518d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 519d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 520d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 521d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 522d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 5230fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 524d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 525d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 526d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareLog() = kcode("") { 5270fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private void log(String msg, long i) {") { 528d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("""android.util.Log.d("BINDER", msg + ":" + Long.toHexString(i));""") 5290fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 5300fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 531d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 532d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 533d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun variableSettersAndGetters() = kcode("") { 5345bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar variables.filterNot{it.isUsed()}.forEach { 535019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar nl("public void ${it.setterName}(${it.getResolvedType().toJavaCode()} ${it.readableName}) {") { 5365bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("// not used, ignore") 5375bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5385bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 5395bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("") 5405bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("public ${it.getResolvedType().toJavaCode()} ${it.getterName}() {") { 5415bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("return ${it.getDefaultValue()};") 5425bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5435bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 5445bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5455bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 54618243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.getUserDefinedType() != null) { 547019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar nl("public void ${it.setterName}(${it.getResolvedType().toJavaCode()} ${it.readableName}) {") { 54818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.isObservable()) { 549019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("updateRegistration(${it.getId()}, ${it.readableName});"); 55018243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 551019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("this.${it.fieldName} = ${it.readableName};") 55218243f6f1b7527272ef4feccdf4327d80d9f2241George Mount // set dirty flags! 55318243f6f1b7527272ef4feccdf4327d80d9f2241George Mount val flagSet = it.invalidateFlagSet 5541c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 5551c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 5561c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.getLocalName()}$suffix |= ${flagSet.localValue(index)};") 5571c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 5581c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab ("}") 55918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("super.requestRebind();") 560d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 56118243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 56218243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("") 56318243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("public ${it.getResolvedType().toJavaCode()} ${it.getterName}() {") { 56418243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("return ${it.fieldName};") 565d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 56618243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 567d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 568d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 569d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 570d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 571d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun onFieldChange() = kcode("") { 57234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("@Override") 57334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {") { 5744c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("switch (localFieldId) {") { 575d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getObservables().forEach { 576d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("case ${it.getId()} :") { 577d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return ${it.onChangeName}((${it.getResolvedType().toJavaCode()}) object, fieldId);") 578d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 579d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 580d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 581d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 582d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 583d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 58434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 58534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 586d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 587d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getObservables().forEach { 588019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar nl("private boolean ${it.onChangeName}(${it.getResolvedType().toJavaCode()} ${it.readableName}, int fieldId) {") { 589d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch (fieldId) {", { 590d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val accessedFields: List<FieldAccessExpr> = it.getParents().filterIsInstance(javaClass<FieldAccessExpr>()) 591c4a07bddb4dd5c3bfbecf4d87909c5b447ae56dcGeorge Mount accessedFields.filter { it.hasBindableAnnotations() } 592d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .groupBy { it.getName() } 593d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 59443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${it.key.br()}:") { 595d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val field = it.value.first() 5961c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 5971c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(field.invalidateFlagSet) { suffix, index -> 5981c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.localValue(index)} |= ${field.invalidateFlagSet.localValue(index)};") 5991c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 6001c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 601d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 602d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 603d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 604d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 60543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${"".br()}:") { 606d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.invalidateFlagSet 6071c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 6081c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 6091c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.getLocalName()}$suffix |= ${flagSet.localValue(index)};") 6101c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 6111c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 612d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 613d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 614d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 615d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) 616d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 617d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 618d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 61934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 62034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 621d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 622d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 623d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 624d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareViews() = kcode("// views") { 625dea555cf42dc3583604699c8c018d22681f56166George Mount val oneLayout = !layoutBinder.hasVariations(); 62696e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter {it.isUsed() && (oneLayout || it.getId() == null)}.forEach { 627dea555cf42dc3583604699c8c018d22681f56166George Mount val access : String 628dea555cf42dc3583604699c8c018d22681f56166George Mount if (oneLayout && it.getId() != null) { 629dea555cf42dc3583604699c8c018d22681f56166George Mount access = "public" 630dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 631dea555cf42dc3583604699c8c018d22681f56166George Mount access = "private" 632dea555cf42dc3583604699c8c018d22681f56166George Mount } 633dea555cf42dc3583604699c8c018d22681f56166George Mount nl("${access} final ${it.interfaceType} ${it.fieldName};") 634d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 635d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 636d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 637d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareVariables() = kcode("// variables") { 6385bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 6390fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private ${it.getResolvedType().toJavaCode()} ${it.fieldName};") 640d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 641d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 642d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 643d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareDirtyFlags() = kcode("// dirty flag") { 644d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.ext.localizedFlags.forEach { flag -> 645de38dd3ef0577d25b2d59863603abe5750d0c231George Mount flag.notEmpty { suffix, value -> 6460fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private") 647d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(" ", if(flag.isDynamic()) null else "static final"); 648d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar app(" ", " ${flag.type} ${flag.getLocalName()}$suffix = ${longToBinary(value)};") 649d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 650d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 651d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 652d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 653d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun flagMapping() = kcode("/* flag mapping") { 654d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (model.getFlagMapping() != null) { 655d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val mapping = model.getFlagMapping() 656d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in mapping.indices) { 657d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("flag $i: ${mapping[i]}") 658d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 659d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 660d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nl("flag mapping end*/") 661d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 662d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 6634c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun executePendingBindings() = kcode("") { 6640fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("@Override") 665e725f0d81e1b07e88f819be9a82181eeeb680dbfGeorge Mount nl("protected void executeBindings() {") { 666d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val tmpDirtyFlags = FlagSet(mDirtyFlags.buckets) 667d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tmpDirtyFlags.setLocalName("dirtyFlags"); 668d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in (0..mDirtyFlags.buckets.size() - 1)) { 6691c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${tmpDirtyFlags.type} ${tmpDirtyFlags.localValue(i)} = 0;") 670d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 6711c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 6721c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar for (i in (0..mDirtyFlags.buckets.size() - 1)) { 6731c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${tmpDirtyFlags.localValue(i)} = ${mDirtyFlags.localValue(i)};") 6741c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.localValue(i)} = 0;") 6751c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 6761c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 6774a81aabc49f6c881d960cd541adda7de9625277aYigit Boyar model.getPendingExpressions().filterNot {!it.canBeEvaluatedToAVariable() || (it.isVariable() && !it.isUsed())}.forEach { 6784a81aabc49f6c881d960cd541adda7de9625277aYigit Boyar tab("${it.getResolvedType().toJavaCode()} ${it.executePendingLocalName} = ${if(it.isVariable()) it.fieldName else it.getDefaultValue()};") 679d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 680b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("writing executePendingBindings for %s", className) 681d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar do { 68274f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyar val batch = ExprModel.filterShouldRead(model.getPendingExpressions()).toArrayList() 683b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("batch: %s", batch) 684d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val mJustRead = arrayListOf<Expr>() 685d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar while (!batch.none()) { 6860fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val readNow = batch.filter { it.shouldReadNow(mJustRead) } 687d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (readNow.isEmpty()) { 688d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar throw IllegalStateException("do not know what I can read. bailing out ${batch.joinToString("\n")}") 689d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 690b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("new read now. batch size: %d, readNow size: %d", batch.size(), readNow.size()) 691d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 692d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar readNow.forEach { 6930fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl(readWithDependants(it, mJustRead, batch, tmpDirtyFlags)) 694d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 695d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar batch.removeAll(mJustRead) 696d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 6970fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// batch finished") 698d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } while(model.markBitsRead()) 6997b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar // verify everything is read. 7007b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar val batch = ExprModel.filterShouldRead(model.getPendingExpressions()).toArrayList() 7017b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar if (batch.isNotEmpty()) { 7027b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar L.e("could not generate code for %s. This might be caused by circular dependencies." 7037b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar + "Please report on b.android.com", layoutBinder.getLayoutname()) 7047b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar } 705d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // 70696e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter { it.isUsed() } 707d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .flatMap { it.getBindings() } 708d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .groupBy { it.getExpr() } 709d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 710d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.key.dirtyFlagSet 711d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 712d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 713d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }.joinToString(" || ") 714d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) {") { 715d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.value.forEach { binding -> 71697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("// api target ${binding.getMinApi()}") 71734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val fieldName : String 71834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount if (binding.getTarget().getViewClass(). 71934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount equals(binding.getTarget().getInterfaceType())) { 72034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fieldName = "this.${binding.getTarget().fieldName}" 72134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } else { 72234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fieldName = "((${binding.getTarget().getViewClass()}) this.${binding.getTarget().fieldName})" 72334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 724e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar val bindingCode = binding.toJavaCode(fieldName) 72597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar if (binding.getMinApi() > 1) { 7264c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("if(getBuildSdkInt() >= ${binding.getMinApi()}) {") { 72797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("$bindingCode;") 72897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 72997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("}") 73097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } else { 73197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("$bindingCode;") 73297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 733d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 734d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 735d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 736d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7375bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar includedBinders.filter{it.isUsed()}.forEach { binder -> 7384c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("${binder.fieldName}.executePendingBindings();") 7397551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 74096e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{ 741de38dd3ef0577d25b2d59863603abe5750d0c231George Mount it.isUsed() && it.getResolvedType() != null && it.getResolvedType().extendsViewStub() 742de38dd3ef0577d25b2d59863603abe5750d0c231George Mount }.forEach { 743de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("if (${it.fieldName}.getBinding() != null) {") { 744de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("${it.fieldName}.getBinding().executePendingBindings();") 745de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 746de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("}") 747de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 748d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7490fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 750d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 751d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 752d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar fun readWithDependants(expr : Expr, mJustRead : MutableList<Expr>, batch : MutableList<Expr>, 753d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tmpDirtyFlags : FlagSet, inheritedFlags : FlagSet? = null) : KCode = kcode("") { 754d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mJustRead.add(expr) 755b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("%s / readWithDependants %s", className, expr.getUniqueKey()); 756d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = expr.shouldReadFlagSet 757d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val needsIfWrapper = inheritedFlags == null || !flagSet.bitsEqual(inheritedFlags) 758b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("flag set:%s . inherited flags: %s. need another if: %s", flagSet, inheritedFlags, needsIfWrapper); 759d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val ifClause = "if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 76043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 76143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.joinToString(" || ") 762d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar })" 763d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 764d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val readCode = kcode("") { 765e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar if (expr.canBeEvaluatedToAVariable() && !expr.isVariable()) { 766d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // it is not a variable read it. 767d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("// read ${expr.getUniqueKey()}") 768d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // create an if case for all dependencies that might be null 769d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val nullables = expr.getDependencies().filter { 770e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount it.isMandatory() && it.getOther().getResolvedType().isNullable() 77174f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyar }.map { it.getOther() } 772d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (!expr.isEqualityCheck() && nullables.isNotEmpty()) { 773019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab ("if ( ${nullables.map { "${it.executePendingLocalName} != null" }.joinToString(" && ")}) {") { 774019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("${expr.executePendingLocalName}").app(" = ", expr.toCode(true)).app(";") 775d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 776d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 777d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } else { 778019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("${expr.executePendingLocalName}").app(" = ", expr.toCode(true)).app(";") 779d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7807920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount if (expr.isObservable()) { 781019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("updateRegistration(${expr.getId()}, ${expr.executePendingLocalName});") 782d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7830fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 784d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 7850fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar // if I am the condition for an expression, set its flag 7860fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val conditionals = expr.getDependants().filter { !it.isConditional() 7870fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar && it.getDependant() is TernaryExpr && (it.getDependant() as TernaryExpr).getPred() == expr } 7880fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar .map { it.getDependant() } 7890fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar if (conditionals.isNotEmpty()) { 7900fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// setting conditional flags") 791019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("if (${expr.executePendingLocalName}) {") { 7920fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar conditionals.forEach { 7930fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val set = it.getRequirementFlagSet(true) 7940fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar mDirtyFlags.mapOr(set) { suffix , index -> 7950fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 796d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 797d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 798d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7990fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("} else {") { 8000fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar conditionals.forEach { 8010fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val set = it.getRequirementFlagSet(false) 8020fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar mDirtyFlags.mapOr(set) { suffix , index -> 8030fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 8040fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 8050fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 8060fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } tab("}") 807d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8080fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar 809d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val chosen = expr.getDependants().filter { 810d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val dependant = it.getDependant() 811d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar batch.contains(dependant) && 812d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar dependant.shouldReadFlagSet.andNot(flagSet).isEmpty() && 813d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar dependant.shouldReadNow(mJustRead) 814d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 815d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (chosen.isNotEmpty()) { 816d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val nextInheritedFlags = if (needsIfWrapper) flagSet else inheritedFlags 817d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar chosen.forEach { 818d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readWithDependants(it.getDependant(), mJustRead, batch, tmpDirtyFlags, nextInheritedFlags)) 819d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 820d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 821d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 822d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar if (needsIfWrapper) { 823d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tab(ifClause) { 824d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar app(" {") 825d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readCode) 826d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 827d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tab("}") 828d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } else { 829d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readCode) 830d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 831d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 83243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 833dea555cf42dc3583604699c8c018d22681f56166George Mount fun declareFactories() = kcode("") { 834081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount nl("public static ${baseClassName} inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot) {") { 835081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount tab("return android.databinding.DataBindingUtil.<${baseClassName}>inflate(inflater, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, root, attachToRoot);") 836081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount } 837081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount nl("}") 83896e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (!layoutBinder.isMerge()) { 839081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount nl("public static ${baseClassName} inflate(android.view.LayoutInflater inflater) {") { 8409bdb2415487832e88a05c7bd19391b05440b468eGeorge Mount tab("return bind(inflater.inflate(${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, null, false));") 84196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 84296e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 84396e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public static ${baseClassName} bind(android.view.View view) {") { 84496e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("if (!\"${layoutBinder.getTag()}_0\".equals(view.getTag())) {") { 845f80b08430f11515ff944f89006799f21545602b9George Mount tab("throw new RuntimeException(\"view tag isn't correct on view:\" + view.getTag());") 84696e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 84796e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("}") 84896e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("return new ${baseClassName}(view);") 84996e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 85096e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 851dea555cf42dc3583604699c8c018d22681f56166George Mount } 852dea555cf42dc3583604699c8c018d22681f56166George Mount } 853dea555cf42dc3583604699c8c018d22681f56166George Mount 8544c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount public fun writeBaseClass() : String = 85543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar kcode("package ${layoutBinder.getPackage()};") { 856fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.Bindable;") 857fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.DataBindingUtil;") 858fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.ViewDataBinding;") 8594c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("public abstract class ${baseClassName} extends ViewDataBinding {") 86096e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 861de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("public final ${it.interfaceType} ${it.fieldName};") 86234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 86334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 86434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("protected ${baseClassName}(android.view.View root_, int localFieldCount") { 86596e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 866019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab(", ${it.interfaceType} ${it.constructorParamName}") 86734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 86834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 86934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab(") {") { 87034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("super(root_, localFieldCount);") 87196e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 872019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("this.${it.fieldName} = ${it.constructorParamName};") 87334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 8744c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 8754c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 8764c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("") 87743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar variables.forEach { 87818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.getUserDefinedType() != null) { 879895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar val type = ModelAnalyzer.getInstance().applyImports(it.getUserDefinedType(), model.getImports()) 880019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("public abstract void ${it.setterName}(${type} ${it.readableName});") 88118243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 88243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 8839bdb2415487832e88a05c7bd19391b05440b468eGeorge Mount tab("public static ${baseClassName} inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot) {") { 884081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount tab("return DataBindingUtil.<${baseClassName}>inflate(inflater, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, root, attachToRoot);") 88543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 8864c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 8879bdb2415487832e88a05c7bd19391b05440b468eGeorge Mount tab("public static ${baseClassName} inflate(android.view.LayoutInflater inflater) {") { 8889bdb2415487832e88a05c7bd19391b05440b468eGeorge Mount tab("return DataBindingUtil.<${baseClassName}>inflate(inflater, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, null, false);") 8894c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 8904c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 8914c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public static ${baseClassName} bind(android.view.View view) {") { 892ed6428586a939e00d9e66314d5cf1056ad48767eGeorge Mount tab("return (${baseClassName})bind(view, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()});") 8934c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 8944c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 89543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar nl("}") 89643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.generate() 897dea555cf42dc3583604699c8c018d22681f56166George Mount} 898