LayoutBinderWriter.kt revision 1c44adacab2c1baa937a604da136024f1e92a088
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 17fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.Expr 18d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport kotlin.properties.Delegates 19fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.ext.joinToCamelCaseAsVar 20fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.BindingTarget 21fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.IdentifierExpr 22fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.util.Log 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.ext.androidId 38fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.ext.lazy 39fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.ext.br 40fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ResourceExpr 41fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.BracketExpr 42fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.Callable 43fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.CastExpr 44fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelAnalyzer 4596e1c821dd446d1ed78f8ae61131550588f60a24George Mountimport java.util.ArrayList 4634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport java.util.HashMap 4743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 48d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun String.stripNonJava() = this.split("[^a-zA-Z0-9]").map{ it.trim() }.joinToCamelCaseAsVar() 49d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 50019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarenum class Scope { 51019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar FIELD 52019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar METHOD 53019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar FLAG 54019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar EXECUTE_PENDING_METHOD 55019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar CONSTRUCTOR_PARAM 56019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar} 57019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar 58d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarclass ExprModelExt { 59019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val usedFieldNames = hashMapOf<Scope, MutableSet<String>>(); 60019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar { 61019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Scope.values().forEach { usedFieldNames[it] = hashSetOf<String>() } 62019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar } 63d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val localizedFlags = arrayListOf<FlagSet>() 64d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 65d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun localizeFlag(set : FlagSet, name:String) : FlagSet { 66d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar localizedFlags.add(set) 67019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val result = getUniqueName(name, Scope.FLAG) 68d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar set.setLocalName(result) 69d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return set 70d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 71d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 72019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar fun getUniqueName(base : String, scope : Scope) : String { 73d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var candidate = base 74d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var i = 0 75019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar while (usedFieldNames[scope].contains(candidate)) { 76d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar i ++ 77d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar candidate = base + i 78d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 79019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar usedFieldNames[scope].add(candidate) 80d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return candidate 81d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 82d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 83d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 84de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval ExprModel.ext by Delegates.lazy { target : ExprModel -> 85d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar ExprModelExt() 86d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 87d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 88019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getUniqueFieldName(base : String) : String = ext.getUniqueName(base, Scope.FIELD) 89019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getUniqueMethodName(base : String) : String = ext.getUniqueName(base, Scope.METHOD) 90019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getUniqueFlagName(base : String) : String = ext.getUniqueName(base, Scope.FLAG) 91019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getConstructorParamName(base : String) : String = ext.getUniqueName(base, Scope.CONSTRUCTOR_PARAM) 92d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 93d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun ExprModel.localizeFlag(set : FlagSet, base : String) : FlagSet = ext.localizeFlag(set, base) 94d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 95019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar// not necessarily unique. Uniqueness is solved per scope 96019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval BindingTarget.readableName by Delegates.lazy { target: BindingTarget -> 9700da715547ee7d5d38a3b8576090ca427a94daa5George Mount if (target.getId() == null) { 98019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar "boundView" + indexFromTag(target.getTag()) 9900da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 100019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar target.getId().androidId().stripNonJava() 10100da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 102d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 1037551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 104de38dd3ef0577d25b2d59863603abe5750d0c231George Mountfun BindingTarget.superConversion(variable : String) : String { 10596e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (getResolvedType() != null && getResolvedType().extendsViewStub()) { 106de38dd3ef0577d25b2d59863603abe5750d0c231George Mount return "new android.databinding.ViewStubProxy((android.view.ViewStub) ${variable})" 107de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } else { 108de38dd3ef0577d25b2d59863603abe5750d0c231George Mount return "(${interfaceType}) ${variable}" 109de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 110de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 111de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 112019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval BindingTarget.fieldName : String by Delegates.lazy { target : BindingTarget -> 113019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val name : String 114019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar if (target.getId() == null) { 115019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar name = "m${target.readableName}" 116019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar } else { 117019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar name = target.readableName 11834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 119019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar target.getModel().getUniqueFieldName(name) 120d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 121d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 122de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.androidId by Delegates.lazy { target : BindingTarget -> 12343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar "R.id.${target.getId().androidId()}" 124d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 125d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 126de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.interfaceType by Delegates.lazy { target : BindingTarget -> 127de38dd3ef0577d25b2d59863603abe5750d0c231George Mount if (target.getResolvedType() != null && target.getResolvedType().extendsViewStub()) { 128de38dd3ef0577d25b2d59863603abe5750d0c231George Mount "android.databinding.ViewStubProxy" 129de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } else { 130de38dd3ef0577d25b2d59863603abe5750d0c231George Mount target.getInterfaceType() 131de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 132de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 133de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 134019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval BindingTarget.constructorParamName by Delegates.lazy { target : BindingTarget -> 135019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar target.getModel().getConstructorParamName(target.readableName) 136d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 137d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 138019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar// not necessarily unique. Uniqueness is decided per scope 139de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.readableName by Delegates.lazy { expr : Expr -> 140019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val stripped = "${expr.getUniqueKey().stripNonJava()}" 141019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Log.d { "readableUniqueName for [${System.identityHashCode(expr)}] ${expr.getUniqueKey()} is $stripped" } 142019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar stripped 143de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 144de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 145de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.fieldName by Delegates.lazy { expr : Expr -> 146019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueFieldName("m${expr.readableName.capitalize()}") 147d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 148d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 149019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval Expr.executePendingLocalName by Delegates.lazy { expr : Expr -> 150019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar if(expr.isVariable()) expr.fieldName else "${expr.getModel().ext.getUniqueName(expr.readableName, Scope.EXECUTE_PENDING_METHOD)}" 151d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 152d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 153de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.setterName by Delegates.lazy { expr : Expr -> 154019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueMethodName("set${expr.readableName.capitalize()}") 155d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 156d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 157de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.onChangeName by Delegates.lazy { expr : Expr -> 158019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueMethodName("onChange${expr.readableName.capitalize()}") 159d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 160d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 161de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.getterName by Delegates.lazy { expr : Expr -> 162019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueMethodName("get${expr.readableName.capitalize()}") 163d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 164d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 165de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.dirtyFlagName by Delegates.lazy { expr : Expr -> 166019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueFlagName("sFlag${expr.readableName.capitalize()}") 167d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 168d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 169d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 170d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.toCode(full : Boolean = false) : KCode { 171d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val it = this 172d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (isDynamic() && !full) { 173019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar return kcode(executePendingLocalName) 174d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 175d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return when (it) { 176d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is ComparisonExpr -> kcode("") { 177d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getLeft().toCode()) 178d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(it.getOp()) 179d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getRight().toCode()) 180d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 181c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount is InstanceOfExpr -> kcode("") { 182c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount app("", it.getExpr().toCode()) 183c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount app(" instanceof ") 184c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount app("", it.getType().toJavaCode()) 185c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount } 186d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is FieldAccessExpr -> kcode("") { 187a70fed6415aa1e8bbbe929aee776402ac3b81c86George Mount app("", it.getChild().toCode()) 188e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount if (it.getGetter().type == Callable.Type.FIELD) { 189d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(".", it.getGetter().name) 190d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } else { 191d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(".", it.getGetter().name).app("()") 192d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 193d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 194d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is GroupExpr -> kcode("(").app("", it.getWrapped().toCode()).app(")") 195d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is StaticIdentifierExpr -> kcode(it.getResolvedType().toJavaCode()) 196019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar is IdentifierExpr -> kcode(it.executePendingLocalName) 197d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is MathExpr -> kcode("") { 198d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getLeft().toCode()) 199d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(it.getOp()) 200d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getRight().toCode()) 201d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 202c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount is UnaryExpr -> kcode("") { 203c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount app(it.getOp(), it.getExpr().toCode()) 204c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount } 205c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount is BitShiftExpr -> kcode("") { 206c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount app("", it.getLeft().toCode()) 207c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount app(it.getOp()) 208c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount app("", it.getRight().toCode()) 209c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount } 210d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is MethodCallExpr -> kcode("") { 211d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getTarget().toCode()) 212d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(".", it.getGetter().name) 213d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("(") 214d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var first = true 215d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.getArgs().forEach { 216d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar apps(if (first) "" else ",", it.toCode()) 217d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar first = false 218d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 219d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(")") 220d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 221d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is SymbolExpr -> kcode(it.getText()) // TODO 222d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is TernaryExpr -> kcode("") { 223d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getPred().toCode()) 224d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("?", it.getIfTrue().toCode()) 225d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(":", it.getIfFalse().toCode()) 226d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 227c752a5f795baf6df435ef60881316cb748df407cGeorge Mount is ResourceExpr -> kcode("") { 228c752a5f795baf6df435ef60881316cb748df407cGeorge Mount app("", it.toJava()) 229c752a5f795baf6df435ef60881316cb748df407cGeorge Mount } 2305cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount is BracketExpr -> kcode("") { 2315cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("", it.getTarget().toCode()) 2325cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount val bracketType = it.getAccessor(); 2335cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount when (bracketType) { 2345cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount BracketExpr.BracketAccessor.ARRAY -> { 2355cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("[", it.getArg().toCode()) 2365cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("]") 2375cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2385cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount BracketExpr.BracketAccessor.LIST -> { 2395cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(".get(") 2405cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount if (it.argCastsInteger()) { 2415cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("(Integer)") 2425cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2435cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("", it.getArg().toCode()) 2445cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(")") 2455cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2465cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount BracketExpr.BracketAccessor.MAP -> { 2475cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(".get(", it.getArg().toCode()) 2485cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(")") 2495cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2505cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2515cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 252e4b93061ac703e48fc2c9994c9059ed016f05559George Mount is CastExpr -> kcode("") { 253e4b93061ac703e48fc2c9994c9059ed016f05559George Mount app("(", it.getCastType()) 254e4b93061ac703e48fc2c9994c9059ed016f05559George Mount app(") ", it.getCastExpr().toCode()) 255e4b93061ac703e48fc2c9994c9059ed016f05559George Mount } 256d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar else -> kcode("//NOT IMPLEMENTED YET") 257d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 258d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 259d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 260d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 261d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.isVariable() = this is IdentifierExpr && this.isDynamic() 262d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 263d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.conditionalFlagName(output : Boolean, suffix : String) = "${dirtyFlagName}_${output}$suffix" 264d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 265d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 266de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.dirtyFlagSet by Delegates.lazy { expr : Expr -> 267d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getInvalidFlags(), expr.getModel().getFlagBucketCount()) 268d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 269d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 270de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.invalidateFlagSet by Delegates.lazy { expr : Expr -> 271d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getId()) 272d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 273d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 274de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.shouldReadFlagSet by Delegates.lazy { expr : Expr -> 275d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getShouldReadFlags(), expr.getModel().getFlagBucketCount()) 276d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 277d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 278de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.conditionalFlags by Delegates.lazy { expr : Expr -> 279d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar arrayListOf(FlagSet(expr.getRequirementFlagIndex(false)), 280d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getRequirementFlagIndex(true))) 281d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 282d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 283d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.getRequirementFlagSet(expected : Boolean) : FlagSet = conditionalFlags[if(expected) 1 else 0] 284d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 285d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.notEmpty(cb : (suffix : String, value : Long) -> Unit) { 286d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar buckets.withIndex().forEach { 287d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (it.value != 0L) { 288d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar cb(getWordSuffix(it.index), buckets[it.index]) 289d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 290d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 291d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 292d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 293d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.getWordSuffix(wordIndex : Int) : String { 294d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return if(wordIndex == 0) "" else "_${wordIndex}" 295d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 296d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 297d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.localValue(bucketIndex : Int) = 298d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar if (getLocalName() == null) binaryCode(bucketIndex) 299d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar else "${getLocalName()}${getWordSuffix(bucketIndex)}" 300d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 301d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyarfun FlagSet.binaryCode(bucketIndex : Int) = longToBinary(buckets[bucketIndex]) 302d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 303d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 304d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyarfun longToBinary(l : Long) = 305d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar "0b${java.lang.Long.toBinaryString(l)}L" 306d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 307d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun <T> FlagSet.mapOr(other : FlagSet, cb : (suffix : String, index : Int) -> T) : List<T> { 308d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val min = Math.min(buckets.size(), other.buckets.size()) 309d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val result = arrayListOf<T>() 310d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in 0..(min - 1)) { 311d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // if these two can match by any chance, call the callback 312d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (intersect(other, i)) { 313d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar result.add(cb(getWordSuffix(i), i)) 314d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 315d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 316d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return result 317d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 318d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 31996e1c821dd446d1ed78f8ae61131550588f60a24George Mountfun indexFromTag(tag : String) : kotlin.Int { 32096e1c821dd446d1ed78f8ae61131550588f60a24George Mount val startIndex : kotlin.Int 3217ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount if (tag.startsWith("binding_")) { 3227ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount startIndex = "binding_".length(); 32396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 32496e1c821dd446d1ed78f8ae61131550588f60a24George Mount startIndex = tag.lastIndexOf('_') + 1 32596e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 32696e1c821dd446d1ed78f8ae61131550588f60a24George Mount return Integer.parseInt(tag.substring(startIndex)) 32796e1c821dd446d1ed78f8ae61131550588f60a24George Mount} 32896e1c821dd446d1ed78f8ae61131550588f60a24George Mount 32943596c2b2997e40b709627419732100d78a62ff0Yigit Boyarclass LayoutBinderWriter(val layoutBinder : LayoutBinder) { 330d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val model = layoutBinder.getModel() 33134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val indices = HashMap<BindingTarget, kotlin.Int>() 33243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val mDirtyFlags by Delegates.lazy { 33343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val fs = FlagSet(BitSet(), model.getFlagBucketCount()); 33443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Arrays.fill(fs.buckets, -1) 33543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs.setDynamic(true) 33643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.localizeFlag(fs, "mDirtyFlags") 33743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs 338d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 339d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 34043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val dynamics by Delegates.lazy { model.getExprMap().values().filter { it.isDynamic() } } 341dea555cf42dc3583604699c8c018d22681f56166George Mount val className = layoutBinder.getImplementationName() 342d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 343dea555cf42dc3583604699c8c018d22681f56166George Mount val baseClassName = "${layoutBinder.getClassName()}" 344d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 3457551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar val includedBinders by Delegates.lazy { 3467551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar layoutBinder.getBindingTargets().filter { it.isBinder() } 3477551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 3487551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 34943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val variables by Delegates.lazy { 35043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.getExprMap().values().filterIsInstance(javaClass<IdentifierExpr>()).filter { it.isVariable() } 35143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 352d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 3535bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar val usedVariables by Delegates.lazy { 3545bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar variables.filter {it.isUsed()} 3555bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 356d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 35796e1c821dd446d1ed78f8ae61131550588f60a24George Mount public fun write(minSdk : kotlin.Int) : String { 3585bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar layoutBinder.resolveWhichExpressionsAreUsed() 35934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount calculateIndices(); 3605bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar return kcode("package ${layoutBinder.getPackage()};") { 361a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar nl("import ${layoutBinder.getModulePackage()}.R;") 362a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar nl("import ${layoutBinder.getModulePackage()}.BR;") 3635bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("import android.view.View;") 364dea555cf42dc3583604699c8c018d22681f56166George Mount val classDeclaration : String 365dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 366dea555cf42dc3583604699c8c018d22681f56166George Mount classDeclaration = "${className} extends ${baseClassName}" 367dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 368dea555cf42dc3583604699c8c018d22681f56166George Mount classDeclaration = "${className} extends android.databinding.ViewDataBinding" 369dea555cf42dc3583604699c8c018d22681f56166George Mount } 370dea555cf42dc3583604699c8c018d22681f56166George Mount nl("public class ${classDeclaration} {") { 3714c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(declareIncludeViews()) 3725bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareViews()) 3735bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareVariables()) 37496e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab(declareConstructor(minSdk)) 3755bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareInvalidateAll()) 3765bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareLog()) 3775bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareSetVariable()) 3785bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(variableSettersAndGetters()) 3795bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(onFieldChange()) 3805bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 3814c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(executePendingBindings()) 3825bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 3835bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareDirtyFlags()) 384dea555cf42dc3583604699c8c018d22681f56166George Mount if (!layoutBinder.hasVariations()) { 385dea555cf42dc3583604699c8c018d22681f56166George Mount tab(declareFactories()) 386dea555cf42dc3583604699c8c018d22681f56166George Mount } 3875bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 3885bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 3895bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(flagMapping()) 3905bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("//end") 3915bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar }.generate() 3925bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 39334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fun calculateIndices() : Unit { 39496e1c821dd446d1ed78f8ae61131550588f60a24George Mount val taggedViews = layoutBinder.getBindingTargets().filter{ 39596e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && it.getTag() != null && !it.isBinder() 39634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 39796e1c821dd446d1ed78f8ae61131550588f60a24George Mount taggedViews.forEach { 39896e1c821dd446d1ed78f8ae61131550588f60a24George Mount indices.put(it, indexFromTag(it.getTag())) 39996e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 40096e1c821dd446d1ed78f8ae61131550588f60a24George Mount val indexStart = maxIndex() + 1 40196e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getBindingTargets().filter{ 40296e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !taggedViews.contains(it) 40396e1c821dd446d1ed78f8ae61131550588f60a24George Mount }.withIndex().forEach { 40496e1c821dd446d1ed78f8ae61131550588f60a24George Mount indices.put(it.value, it.index + indexStart) 40534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 40634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 4074c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun declareIncludeViews() = kcode("") { 40896e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("private static final android.databinding.ViewDataBinding.IncludedLayoutIndex[][] sIncludes;") 4094c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("private static final android.util.SparseIntArray sViewsWithIds;") 4104c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("static {") { 4114c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount val hasBinders = layoutBinder.getBindingTargets().firstOrNull{ it.isUsed() && it.isBinder()} != null 4124c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount if (!hasBinders) { 4134c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sIncludes = null;") 41400da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 41596e1c821dd446d1ed78f8ae61131550588f60a24George Mount val numBindings = layoutBinder.getBindingTargets().filter{ it.isUsed() }.count() 41696e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("sIncludes = new android.databinding.ViewDataBinding.IncludedLayoutIndex[${numBindings}][];") 41796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val includeMap = HashMap<BindingTarget, ArrayList<BindingTarget>>() 41896e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getBindingTargets().filter{ it.isUsed() && it.isBinder() }.forEach { 41996e1c821dd446d1ed78f8ae61131550588f60a24George Mount val includeTag = it.getTag(); 42096e1c821dd446d1ed78f8ae61131550588f60a24George Mount val parent = layoutBinder.getBindingTargets().firstOrNull { 42196e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !it.isBinder() && includeTag.equals(it.getTag()) 42296e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 42396e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (parent == null) { 42496e1c821dd446d1ed78f8ae61131550588f60a24George Mount throw IllegalStateException("Could not find parent of include file") 42596e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 42696e1c821dd446d1ed78f8ae61131550588f60a24George Mount var list = includeMap.get(parent) 42796e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (list == null) { 42896e1c821dd446d1ed78f8ae61131550588f60a24George Mount list = ArrayList<BindingTarget>() 42996e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.put(parent, list) 43096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 43196e1c821dd446d1ed78f8ae61131550588f60a24George Mount list.add(it) 4324c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 43396e1c821dd446d1ed78f8ae61131550588f60a24George Mount 43496e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.keySet().forEach { 43596e1c821dd446d1ed78f8ae61131550588f60a24George Mount val index = indices.get(it) 43696e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("sIncludes[${index}] = new android.databinding.ViewDataBinding.IncludedLayoutIndex[] {") { 43796e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.get(it).forEach { 43896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val bindingIndex = indices.get(it) 43996e1c821dd446d1ed78f8ae61131550588f60a24George Mount val layoutName = it.getIncludedLayout() 44096e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("new android.databinding.ViewDataBinding.IncludedLayoutIndex(\"${layoutName}\", ${bindingIndex}, R.layout.${layoutName}),") 44196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 44296e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 44396e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("};") 44496e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 44596e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 44696e1c821dd446d1ed78f8ae61131550588f60a24George Mount val viewsWithIds = layoutBinder.getBindingTargets().filter { 44796e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !it.isBinder() && (!it.supportsTag() || (it.getId() != null && it.getTag() == null)) 44800da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 44996e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (viewsWithIds.isEmpty()) { 4504c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = null;") 45100da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 4524c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = new android.util.SparseIntArray();") 45396e1c821dd446d1ed78f8ae61131550588f60a24George Mount viewsWithIds.forEach { 45434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("sViewsWithIds.put(${it.androidId}, ${indices.get(it)});") 4554c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 45600da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 4574c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 4584c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("}") 4594c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 46096e1c821dd446d1ed78f8ae61131550588f60a24George Mount 46196e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun maxIndex() : kotlin.Int { 46296e1c821dd446d1ed78f8ae61131550588f60a24George Mount val maxIndex = indices.values().max() 46396e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (maxIndex == null) { 46496e1c821dd446d1ed78f8ae61131550588f60a24George Mount return -1 46596e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 46696e1c821dd446d1ed78f8ae61131550588f60a24George Mount return maxIndex 46796e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 46896e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 46996e1c821dd446d1ed78f8ae61131550588f60a24George Mount 47096e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun declareConstructor(minSdk : kotlin.Int) = kcode("") { 47196e1c821dd446d1ed78f8ae61131550588f60a24George Mount val bindingCount = maxIndex() + 1 47296e1c821dd446d1ed78f8ae61131550588f60a24George Mount val parameterType : String 47396e1c821dd446d1ed78f8ae61131550588f60a24George Mount val superParam : String 47496e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (layoutBinder.isMerge()) { 47596e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View[]" 47696e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root[0]" 47796e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 47896e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View" 47996e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root" 48096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 48196e1c821dd446d1ed78f8ae61131550588f60a24George Mount val rootTagsSupported = minSdk >= 14 482dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 483dea555cf42dc3583604699c8c018d22681f56166George Mount nl("") 48496e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public ${className}(${parameterType} root) {") { 48596e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("this(${superParam}, mapBindings(root, ${bindingCount}, sIncludes, sViewsWithIds));") 486dea555cf42dc3583604699c8c018d22681f56166George Mount } 487dea555cf42dc3583604699c8c018d22681f56166George Mount nl("}") 48896e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("private ${className}(${parameterType} root, Object[] bindings) {") { 48996e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("super(${superParam}, ${model.getObservables().size()}") { 49096e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter { it.getId() != null }.forEach { 491dea555cf42dc3583604699c8c018d22681f56166George Mount tab(", ${fieldConversion(it)}") 49234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 493dea555cf42dc3583604699c8c018d22681f56166George Mount tab(");") 49434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 49534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 496dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 49796e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public ${baseClassName}(${parameterType} root) {") { 49896e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("super(${superParam}, ${model.getObservables().size()});") 49996e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("final Object[] bindings = mapBindings(root, ${bindingCount}, sIncludes, sViewsWithIds);") 500dea555cf42dc3583604699c8c018d22681f56166George Mount } 501dea555cf42dc3583604699c8c018d22681f56166George Mount } 50296e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("setRootTag(root);") 50396e1c821dd446d1ed78f8ae61131550588f60a24George Mount val taggedViews = layoutBinder.getSortedTargets().filter{it.isUsed()} 504dea555cf42dc3583604699c8c018d22681f56166George Mount taggedViews.forEach { 505dea555cf42dc3583604699c8c018d22681f56166George Mount if (!layoutBinder.hasVariations() || it.getId() == null) { 506dea555cf42dc3583604699c8c018d22681f56166George Mount tab("this.${it.fieldName} = ${fieldConversion(it)};") 507dea555cf42dc3583604699c8c018d22681f56166George Mount } 508dea555cf42dc3583604699c8c018d22681f56166George Mount if (!it.isBinder()) { 509de38dd3ef0577d25b2d59863603abe5750d0c231George Mount if (it.getResolvedType() != null && it.getResolvedType().extendsViewStub()) { 510de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("this.${it.fieldName}.setContainingBinding(this);") 511de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 51296e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (it.supportsTag() && it.getTag() != null && 5137ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount (rootTagsSupported || it.getTag().startsWith("binding_"))) { 514dea555cf42dc3583604699c8c018d22681f56166George Mount val originalTag = it.getOriginalTag(); 515dea555cf42dc3583604699c8c018d22681f56166George Mount var tagValue = "null" 516dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag != null) { 517dea555cf42dc3583604699c8c018d22681f56166George Mount tagValue = "\"${originalTag}\"" 518dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@")) { 519dea555cf42dc3583604699c8c018d22681f56166George Mount var packageName = layoutBinder.getModulePackage() 520dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@android:")) { 521dea555cf42dc3583604699c8c018d22681f56166George Mount packageName = "android" 52200da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 523dea555cf42dc3583604699c8c018d22681f56166George Mount val slashIndex = originalTag.indexOf('/') 524dea555cf42dc3583604699c8c018d22681f56166George Mount val resourceId = originalTag.substring(slashIndex + 1) 525dea555cf42dc3583604699c8c018d22681f56166George Mount tagValue = "root.getResources().getString(${packageName}.R.string.${resourceId})" 52600da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 52700da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 528dea555cf42dc3583604699c8c018d22681f56166George Mount tab("this.${it.fieldName}.setTag(${tagValue});") 5297551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 530d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 531d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 532dea555cf42dc3583604699c8c018d22681f56166George Mount tab("invalidateAll();"); 5330fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 534d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 535d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 536dea555cf42dc3583604699c8c018d22681f56166George Mount fun fieldConversion(target : BindingTarget) : String { 537dea555cf42dc3583604699c8c018d22681f56166George Mount if (!target.isUsed()) { 538dea555cf42dc3583604699c8c018d22681f56166George Mount return "null" 539dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 54096e1c821dd446d1ed78f8ae61131550588f60a24George Mount val index = indices.get(target) 541dea555cf42dc3583604699c8c018d22681f56166George Mount if (index == null) { 54296e1c821dd446d1ed78f8ae61131550588f60a24George Mount throw IllegalStateException("Unknown binding target") 543dea555cf42dc3583604699c8c018d22681f56166George Mount } 54496e1c821dd446d1ed78f8ae61131550588f60a24George Mount val variableName = "bindings[${index}]" 545dea555cf42dc3583604699c8c018d22681f56166George Mount return target.superConversion(variableName) 546dea555cf42dc3583604699c8c018d22681f56166George Mount } 547dea555cf42dc3583604699c8c018d22681f56166George Mount } 548dea555cf42dc3583604699c8c018d22681f56166George Mount 549d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareInvalidateAll() = kcode("") { 5507551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("@Override") 5517551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("public void invalidateAll() {") { 552019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val fs = FlagSet(layoutBinder.getModel().getInvalidateAnyBitSet(), 553019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar layoutBinder.getModel().getFlagBucketCount()); 5541c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 5551c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar for (i in (0..(mDirtyFlags.buckets.size() - 1))) { 5561c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.localValue(i)} = ${fs.localValue(i)};") 5571c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 5581c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 5595bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar includedBinders.filter{it.isUsed()}.forEach { binder -> 5607551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar tab("${binder.fieldName}.invalidateAll();") 5617551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 562d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 5630fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 564d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 565d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 566d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareSetVariable() = kcode("") { 5670fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("public boolean setVariable(int variableId, Object variable) {") { 568d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch(variableId) {") { 5695bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 57043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab ("case ${it.getName().br()} :") { 571d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${it.setterName}((${it.getResolvedType().toJavaCode()}) variable);") 572d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 573d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 574d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 575d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 576d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 577d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 578d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 5790fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 580d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 581d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 582d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareLog() = kcode("") { 5830fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private void log(String msg, long i) {") { 584d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("""android.util.Log.d("BINDER", msg + ":" + Long.toHexString(i));""") 5850fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 5860fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 587d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 588d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 589d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun variableSettersAndGetters() = kcode("") { 5905bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar variables.filterNot{it.isUsed()}.forEach { 591019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar nl("public void ${it.setterName}(${it.getResolvedType().toJavaCode()} ${it.readableName}) {") { 5925bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("// not used, ignore") 5935bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5945bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 5955bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("") 5965bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("public ${it.getResolvedType().toJavaCode()} ${it.getterName}() {") { 5975bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("return ${it.getDefaultValue()};") 5985bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5995bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 6005bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 6015bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 60218243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.getUserDefinedType() != null) { 603019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar nl("public void ${it.setterName}(${it.getResolvedType().toJavaCode()} ${it.readableName}) {") { 60418243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.isObservable()) { 605019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("updateRegistration(${it.getId()}, ${it.readableName});"); 60618243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 607019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("this.${it.fieldName} = ${it.readableName};") 60818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount // set dirty flags! 60918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount val flagSet = it.invalidateFlagSet 6101c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 6111c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 6121c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.getLocalName()}$suffix |= ${flagSet.localValue(index)};") 6131c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 6141c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab ("}") 61518243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("super.requestRebind();") 616d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 61718243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 61818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("") 61918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("public ${it.getResolvedType().toJavaCode()} ${it.getterName}() {") { 62018243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("return ${it.fieldName};") 621d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 62218243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 623d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 624d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 625d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 626d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 627d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun onFieldChange() = kcode("") { 62834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("@Override") 62934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {") { 6304c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("switch (localFieldId) {") { 631d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getObservables().forEach { 632d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("case ${it.getId()} :") { 633d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return ${it.onChangeName}((${it.getResolvedType().toJavaCode()}) object, fieldId);") 634d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 635d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 636d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 637d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 638d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 639d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 64034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 64134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 642d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 643d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getObservables().forEach { 644019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar nl("private boolean ${it.onChangeName}(${it.getResolvedType().toJavaCode()} ${it.readableName}, int fieldId) {") { 645d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch (fieldId) {", { 646d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val accessedFields: List<FieldAccessExpr> = it.getParents().filterIsInstance(javaClass<FieldAccessExpr>()) 647d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar accessedFields.filter { it.canBeInvalidated() } 648d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .groupBy { it.getName() } 649d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 65043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${it.key.br()}:") { 651d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val field = it.value.first() 6521c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 6531c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(field.invalidateFlagSet) { suffix, index -> 6541c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.localValue(index)} |= ${field.invalidateFlagSet.localValue(index)};") 6551c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 6561c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 657d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 658d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 659d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 660d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 66143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${"".br()}:") { 662d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.invalidateFlagSet 6631c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 6641c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 6651c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.getLocalName()}$suffix |= ${flagSet.localValue(index)};") 6661c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 6671c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 668d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 669d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 670d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 671d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) 672d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 673d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 674d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 67534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 67634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 677d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 678d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 679d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 680d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareViews() = kcode("// views") { 681dea555cf42dc3583604699c8c018d22681f56166George Mount val oneLayout = !layoutBinder.hasVariations(); 68296e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter {it.isUsed() && (oneLayout || it.getId() == null)}.forEach { 683dea555cf42dc3583604699c8c018d22681f56166George Mount val access : String 684dea555cf42dc3583604699c8c018d22681f56166George Mount if (oneLayout && it.getId() != null) { 685dea555cf42dc3583604699c8c018d22681f56166George Mount access = "public" 686dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 687dea555cf42dc3583604699c8c018d22681f56166George Mount access = "private" 688dea555cf42dc3583604699c8c018d22681f56166George Mount } 689dea555cf42dc3583604699c8c018d22681f56166George Mount nl("${access} final ${it.interfaceType} ${it.fieldName};") 690d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 691d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 692d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 693d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareVariables() = kcode("// variables") { 6945bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 6950fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private ${it.getResolvedType().toJavaCode()} ${it.fieldName};") 696d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 697d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 698d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 699d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareDirtyFlags() = kcode("// dirty flag") { 700d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.ext.localizedFlags.forEach { flag -> 701de38dd3ef0577d25b2d59863603abe5750d0c231George Mount flag.notEmpty { suffix, value -> 7020fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private") 703d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(" ", if(flag.isDynamic()) null else "static final"); 704d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar app(" ", " ${flag.type} ${flag.getLocalName()}$suffix = ${longToBinary(value)};") 705d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 706d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 707d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 708d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 709d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun flagMapping() = kcode("/* flag mapping") { 710d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (model.getFlagMapping() != null) { 711d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val mapping = model.getFlagMapping() 712d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in mapping.indices) { 713d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("flag $i: ${mapping[i]}") 714d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 715d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 716d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nl("flag mapping end*/") 717d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 718d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 7194c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun executePendingBindings() = kcode("") { 7200fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("@Override") 7214c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("public void executePendingBindings() {") { 722d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val tmpDirtyFlags = FlagSet(mDirtyFlags.buckets) 723d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tmpDirtyFlags.setLocalName("dirtyFlags"); 724d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in (0..mDirtyFlags.buckets.size() - 1)) { 7251c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${tmpDirtyFlags.type} ${tmpDirtyFlags.localValue(i)} = 0;") 726d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7271c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 7281c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar for (i in (0..mDirtyFlags.buckets.size() - 1)) { 7291c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${tmpDirtyFlags.localValue(i)} = ${mDirtyFlags.localValue(i)};") 7301c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.localValue(i)} = 0;") 7311c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 7321c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 733d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getPendingExpressions().filterNot {it.isVariable()}.forEach { 734019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("${it.getResolvedType().toJavaCode()} ${it.executePendingLocalName} = ${it.getDefaultValue()};") 735d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 736019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Log.d {"writing executePendingBindings for $className"} 737d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar do { 73874f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyar val batch = ExprModel.filterShouldRead(model.getPendingExpressions()).toArrayList() 739019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Log.d {"batch: $batch"} 740d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val mJustRead = arrayListOf<Expr>() 741d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar while (!batch.none()) { 7420fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val readNow = batch.filter { it.shouldReadNow(mJustRead) } 743d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (readNow.isEmpty()) { 744d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar throw IllegalStateException("do not know what I can read. bailing out ${batch.joinToString("\n")}") 745d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 74643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Log.d { "new read now. batch size: ${batch.size()}, readNow size: ${readNow.size()}" } 747d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 748d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar readNow.forEach { 7490fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl(readWithDependants(it, mJustRead, batch, tmpDirtyFlags)) 750d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 751d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar batch.removeAll(mJustRead) 752d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7530fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// batch finished") 754d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } while(model.markBitsRead()) 755d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 756d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // 75796e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter { it.isUsed() } 758d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .flatMap { it.getBindings() } 759d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .groupBy { it.getExpr() } 760d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 761d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.key.dirtyFlagSet 762d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 763d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 764d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }.joinToString(" || ") 765d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) {") { 766d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.value.forEach { binding -> 76797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("// api target ${binding.getMinApi()}") 76834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val fieldName : String 76934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount if (binding.getTarget().getViewClass(). 77034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount equals(binding.getTarget().getInterfaceType())) { 77134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fieldName = "this.${binding.getTarget().fieldName}" 77234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } else { 77334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fieldName = "((${binding.getTarget().getViewClass()}) this.${binding.getTarget().fieldName})" 77434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 77534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val bindingCode = binding.toJavaCode(fieldName, binding.getExpr().toCode().generate()) 77697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar if (binding.getMinApi() > 1) { 7774c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("if(getBuildSdkInt() >= ${binding.getMinApi()}) {") { 77897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("$bindingCode;") 77997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 78097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("}") 78197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } else { 78297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("$bindingCode;") 78397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 784d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 785d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 786d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 787d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7885bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar includedBinders.filter{it.isUsed()}.forEach { binder -> 7894c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("${binder.fieldName}.executePendingBindings();") 7907551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 79196e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{ 792de38dd3ef0577d25b2d59863603abe5750d0c231George Mount it.isUsed() && it.getResolvedType() != null && it.getResolvedType().extendsViewStub() 793de38dd3ef0577d25b2d59863603abe5750d0c231George Mount }.forEach { 794de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("if (${it.fieldName}.getBinding() != null) {") { 795de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("${it.fieldName}.getBinding().executePendingBindings();") 796de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 797de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("}") 798de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 799d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8000fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 801d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 802d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 803d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar fun readWithDependants(expr : Expr, mJustRead : MutableList<Expr>, batch : MutableList<Expr>, 804d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tmpDirtyFlags : FlagSet, inheritedFlags : FlagSet? = null) : KCode = kcode("") { 805d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mJustRead.add(expr) 806019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Log.d { "$className / readWithDependants: ${expr.getUniqueKey()}" } 807d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = expr.shouldReadFlagSet 808d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val needsIfWrapper = inheritedFlags == null || !flagSet.bitsEqual(inheritedFlags) 809019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Log.d { "flag set:$flagSet . inherited flags: $inheritedFlags. need another if: $needsIfWrapper"} 810d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val ifClause = "if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 81143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 81243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.joinToString(" || ") 813d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar })" 814d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 815d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val readCode = kcode("") { 816d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (!expr.isVariable()) { 817d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // it is not a variable read it. 818d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("// read ${expr.getUniqueKey()}") 819d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // create an if case for all dependencies that might be null 820d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val nullables = expr.getDependencies().filter { 821e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount it.isMandatory() && it.getOther().getResolvedType().isNullable() 82274f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyar }.map { it.getOther() } 823d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (!expr.isEqualityCheck() && nullables.isNotEmpty()) { 824019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab ("if ( ${nullables.map { "${it.executePendingLocalName} != null" }.joinToString(" && ")}) {") { 825019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("${expr.executePendingLocalName}").app(" = ", expr.toCode(true)).app(";") 826d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 827d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 828d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } else { 829019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("${expr.executePendingLocalName}").app(" = ", expr.toCode(true)).app(";") 830d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8317920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount if (expr.isObservable()) { 832019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("updateRegistration(${expr.getId()}, ${expr.executePendingLocalName});") 833d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8340fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 835d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 8360fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar // if I am the condition for an expression, set its flag 8370fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val conditionals = expr.getDependants().filter { !it.isConditional() 8380fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar && it.getDependant() is TernaryExpr && (it.getDependant() as TernaryExpr).getPred() == expr } 8390fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar .map { it.getDependant() } 8400fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar if (conditionals.isNotEmpty()) { 8410fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// setting conditional flags") 842019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("if (${expr.executePendingLocalName}) {") { 8430fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar conditionals.forEach { 8440fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val set = it.getRequirementFlagSet(true) 8450fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar mDirtyFlags.mapOr(set) { suffix , index -> 8460fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 847d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 848d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 849d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8500fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("} else {") { 8510fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar conditionals.forEach { 8520fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val set = it.getRequirementFlagSet(false) 8530fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar mDirtyFlags.mapOr(set) { suffix , index -> 8540fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 8550fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 8560fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 8570fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } tab("}") 858d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8590fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar 860d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val chosen = expr.getDependants().filter { 861d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val dependant = it.getDependant() 862d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar batch.contains(dependant) && 863d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar dependant.shouldReadFlagSet.andNot(flagSet).isEmpty() && 864d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar dependant.shouldReadNow(mJustRead) 865d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 866d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (chosen.isNotEmpty()) { 867d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val nextInheritedFlags = if (needsIfWrapper) flagSet else inheritedFlags 868d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar chosen.forEach { 869d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readWithDependants(it.getDependant(), mJustRead, batch, tmpDirtyFlags, nextInheritedFlags)) 870d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 871d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 872d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 873d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar if (needsIfWrapper) { 874d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tab(ifClause) { 875d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar app(" {") 876d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readCode) 877d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 878d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tab("}") 879d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } else { 880d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readCode) 881d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 882d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 88343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 884dea555cf42dc3583604699c8c018d22681f56166George Mount fun declareFactories() = kcode("") { 88596e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (!layoutBinder.isMerge()) { 88696e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public static ${baseClassName} inflate(android.view.ViewGroup root) {") { 88796e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("return bind(android.view.LayoutInflater.from(root.getContext()).inflate(${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, root, true));") 888dea555cf42dc3583604699c8c018d22681f56166George Mount } 88996e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 89096e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public static ${baseClassName} inflate(android.content.Context context) {") { 89196e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("return bind(android.view.LayoutInflater.from(context).inflate(${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, null, false));") 89296e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 89396e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 89496e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public static ${baseClassName} bind(android.view.View view) {") { 89596e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("if (!\"${layoutBinder.getTag()}_0\".equals(view.getTag())) {") { 89696e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("throw new RuntimeException(\"view tag isn't correct on view\");") 89796e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 89896e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("}") 89996e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("return new ${baseClassName}(view);") 90096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 90196e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 902dea555cf42dc3583604699c8c018d22681f56166George Mount } 903dea555cf42dc3583604699c8c018d22681f56166George Mount } 904dea555cf42dc3583604699c8c018d22681f56166George Mount 9054c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount public fun writeBaseClass() : String = 90643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar kcode("package ${layoutBinder.getPackage()};") { 907fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.Bindable;") 908fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.DataBindingUtil;") 909fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.ViewDataBinding;") 9104c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("public abstract class ${baseClassName} extends ViewDataBinding {") 91196e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 912de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("public final ${it.interfaceType} ${it.fieldName};") 91334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 91434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 91534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("protected ${baseClassName}(android.view.View root_, int localFieldCount") { 91696e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 917019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab(", ${it.interfaceType} ${it.constructorParamName}") 91834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 91934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 92034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab(") {") { 92134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("super(root_, localFieldCount);") 92296e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 923019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("this.${it.fieldName} = ${it.constructorParamName};") 92434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 9254c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 9264c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 9274c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("") 92843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar variables.forEach { 92918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.getUserDefinedType() != null) { 930895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar //it.getExpandedUserDefinedType(ModelAnalyzer.getInstance()); 931895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar val type = ModelAnalyzer.getInstance().applyImports(it.getUserDefinedType(), model.getImports()) 932019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("public abstract void ${it.setterName}(${type} ${it.readableName});") 93318243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 93443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 9354c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public static ${baseClassName} inflate(android.view.ViewGroup root) {") { 936a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar tab("return DataBindingUtil.<${baseClassName}>inflate(root.getContext(), ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, root, true);") 93743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 9384c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 9394c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public static ${baseClassName} inflate(android.content.Context context) {") { 940a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar tab("return DataBindingUtil.<${baseClassName}>inflate(context, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, null, false);") 9414c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 9424c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 9434c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public static ${baseClassName} bind(android.view.View view) {") { 944a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar tab("return (${baseClassName})DataBindingUtil.bindTo(view, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()});") 9454c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 9464c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 94743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar nl("}") 94843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.generate() 949dea555cf42dc3583604699c8c018d22681f56166George Mount} 950