LayoutBinderWriter.kt revision 019c36b97c7c172ac03997f6bf170e65b2ed7fe4
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 26fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.TernaryExpr 27fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.FieldAccessExpr 28fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ComparisonExpr 29fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.GroupExpr 30fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.MathExpr 31fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.MethodCallExpr 32fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.StaticIdentifierExpr 33fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.SymbolExpr 34fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.ext.androidId 35fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.ext.lazy 36fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.ext.br 37fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ResourceExpr 38fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.BracketExpr 39fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.Callable 40fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.CastExpr 41fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelAnalyzer 4296e1c821dd446d1ed78f8ae61131550588f60a24George Mountimport java.util.ArrayList 4334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport java.util.HashMap 4443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 45d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun String.stripNonJava() = this.split("[^a-zA-Z0-9]").map{ it.trim() }.joinToCamelCaseAsVar() 46d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 47019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarenum class Scope { 48019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar FIELD 49019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar METHOD 50019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar FLAG 51019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar EXECUTE_PENDING_METHOD 52019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar CONSTRUCTOR_PARAM 53019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar} 54019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar 55d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarclass ExprModelExt { 56019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val usedFieldNames = hashMapOf<Scope, MutableSet<String>>(); 57019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar { 58019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Scope.values().forEach { usedFieldNames[it] = hashSetOf<String>() } 59019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar } 60d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val localizedFlags = arrayListOf<FlagSet>() 61d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 62d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun localizeFlag(set : FlagSet, name:String) : FlagSet { 63d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar localizedFlags.add(set) 64019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val result = getUniqueName(name, Scope.FLAG) 65d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar set.setLocalName(result) 66d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return set 67d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 68d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 69019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar fun getUniqueName(base : String, scope : Scope) : String { 70d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var candidate = base 71d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var i = 0 72019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar while (usedFieldNames[scope].contains(candidate)) { 73d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar i ++ 74d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar candidate = base + i 75d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 76019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar usedFieldNames[scope].add(candidate) 77d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return candidate 78d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 79d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 80d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 81de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval ExprModel.ext by Delegates.lazy { target : ExprModel -> 82d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar ExprModelExt() 83d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 84d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 85019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getUniqueFieldName(base : String) : String = ext.getUniqueName(base, Scope.FIELD) 86019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getUniqueMethodName(base : String) : String = ext.getUniqueName(base, Scope.METHOD) 87019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getUniqueFlagName(base : String) : String = ext.getUniqueName(base, Scope.FLAG) 88019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarfun ExprModel.getConstructorParamName(base : String) : String = ext.getUniqueName(base, Scope.CONSTRUCTOR_PARAM) 89d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 90d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun ExprModel.localizeFlag(set : FlagSet, base : String) : FlagSet = ext.localizeFlag(set, base) 91d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 92019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar// not necessarily unique. Uniqueness is solved per scope 93019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval BindingTarget.readableName by Delegates.lazy { target: BindingTarget -> 9400da715547ee7d5d38a3b8576090ca427a94daa5George Mount if (target.getId() == null) { 95019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar "boundView" + indexFromTag(target.getTag()) 9600da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 97019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar target.getId().androidId().stripNonJava() 9800da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 99d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 1007551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 101de38dd3ef0577d25b2d59863603abe5750d0c231George Mountfun BindingTarget.superConversion(variable : String) : String { 10296e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (getResolvedType() != null && getResolvedType().extendsViewStub()) { 103de38dd3ef0577d25b2d59863603abe5750d0c231George Mount return "new android.databinding.ViewStubProxy((android.view.ViewStub) ${variable})" 104de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } else { 105de38dd3ef0577d25b2d59863603abe5750d0c231George Mount return "(${interfaceType}) ${variable}" 106de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 107de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 108de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 109019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval BindingTarget.fieldName : String by Delegates.lazy { target : BindingTarget -> 110019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val name : String 111019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar if (target.getId() == null) { 112019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar name = "m${target.readableName}" 113019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar } else { 114019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar name = target.readableName 11534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 116019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar target.getModel().getUniqueFieldName(name) 117d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 118d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 119de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.androidId by Delegates.lazy { target : BindingTarget -> 12043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar "R.id.${target.getId().androidId()}" 121d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 122d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 123de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.interfaceType by Delegates.lazy { target : BindingTarget -> 124de38dd3ef0577d25b2d59863603abe5750d0c231George Mount if (target.getResolvedType() != null && target.getResolvedType().extendsViewStub()) { 125de38dd3ef0577d25b2d59863603abe5750d0c231George Mount "android.databinding.ViewStubProxy" 126de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } else { 127de38dd3ef0577d25b2d59863603abe5750d0c231George Mount target.getInterfaceType() 128de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 129de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 130de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 131019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval BindingTarget.constructorParamName by Delegates.lazy { target : BindingTarget -> 132019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar target.getModel().getConstructorParamName(target.readableName) 133d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 134d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 135019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar// not necessarily unique. Uniqueness is decided per scope 136de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.readableName by Delegates.lazy { expr : Expr -> 137019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val stripped = "${expr.getUniqueKey().stripNonJava()}" 138019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Log.d { "readableUniqueName for [${System.identityHashCode(expr)}] ${expr.getUniqueKey()} is $stripped" } 139019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar stripped 140de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 141de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 142de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.fieldName by Delegates.lazy { expr : Expr -> 143019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueFieldName("m${expr.readableName.capitalize()}") 144d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 145d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 146019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarval Expr.executePendingLocalName by Delegates.lazy { expr : Expr -> 147019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar if(expr.isVariable()) expr.fieldName else "${expr.getModel().ext.getUniqueName(expr.readableName, Scope.EXECUTE_PENDING_METHOD)}" 148d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 149d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 150de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.setterName by Delegates.lazy { expr : Expr -> 151019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueMethodName("set${expr.readableName.capitalize()}") 152d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 153d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 154de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.onChangeName by Delegates.lazy { expr : Expr -> 155019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueMethodName("onChange${expr.readableName.capitalize()}") 156d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 157d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 158de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.getterName by Delegates.lazy { expr : Expr -> 159019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueMethodName("get${expr.readableName.capitalize()}") 160d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 161d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 162de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.dirtyFlagName by Delegates.lazy { expr : Expr -> 163019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar expr.getModel().getUniqueFlagName("sFlag${expr.readableName.capitalize()}") 164d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 165d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 166d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 167d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.toCode(full : Boolean = false) : KCode { 168d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val it = this 169d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (isDynamic() && !full) { 170019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar return kcode(executePendingLocalName) 171d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 172d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return when (it) { 173d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is ComparisonExpr -> kcode("") { 174d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getLeft().toCode()) 175d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(it.getOp()) 176d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getRight().toCode()) 177d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 178d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is FieldAccessExpr -> kcode("") { 179a70fed6415aa1e8bbbe929aee776402ac3b81c86George Mount app("", it.getChild().toCode()) 180e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount if (it.getGetter().type == Callable.Type.FIELD) { 181d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(".", it.getGetter().name) 182d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } else { 183d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(".", it.getGetter().name).app("()") 184d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 185d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 186d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is GroupExpr -> kcode("(").app("", it.getWrapped().toCode()).app(")") 187d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is StaticIdentifierExpr -> kcode(it.getResolvedType().toJavaCode()) 188019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar is IdentifierExpr -> kcode(it.executePendingLocalName) 189d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is MathExpr -> kcode("") { 190d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getLeft().toCode()) 191d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(it.getOp()) 192d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getRight().toCode()) 193d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 194d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is MethodCallExpr -> kcode("") { 195d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getTarget().toCode()) 196d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(".", it.getGetter().name) 197d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("(") 198d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var first = true 199d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.getArgs().forEach { 200d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar apps(if (first) "" else ",", it.toCode()) 201d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar first = false 202d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 203d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(")") 204d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 205d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is SymbolExpr -> kcode(it.getText()) // TODO 206d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is TernaryExpr -> kcode("") { 207d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getPred().toCode()) 208d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("?", it.getIfTrue().toCode()) 209d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(":", it.getIfFalse().toCode()) 210d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 211c752a5f795baf6df435ef60881316cb748df407cGeorge Mount is ResourceExpr -> kcode("") { 212c752a5f795baf6df435ef60881316cb748df407cGeorge Mount app("", it.toJava()) 213c752a5f795baf6df435ef60881316cb748df407cGeorge Mount } 2145cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount is BracketExpr -> kcode("") { 2155cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("", it.getTarget().toCode()) 2165cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount val bracketType = it.getAccessor(); 2175cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount when (bracketType) { 2185cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount BracketExpr.BracketAccessor.ARRAY -> { 2195cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("[", it.getArg().toCode()) 2205cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("]") 2215cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2225cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount BracketExpr.BracketAccessor.LIST -> { 2235cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(".get(") 2245cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount if (it.argCastsInteger()) { 2255cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("(Integer)") 2265cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2275cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("", it.getArg().toCode()) 2285cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(")") 2295cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2305cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount BracketExpr.BracketAccessor.MAP -> { 2315cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(".get(", it.getArg().toCode()) 2325cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(")") 2335cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2345cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2355cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 236e4b93061ac703e48fc2c9994c9059ed016f05559George Mount is CastExpr -> kcode("") { 237e4b93061ac703e48fc2c9994c9059ed016f05559George Mount app("(", it.getCastType()) 238e4b93061ac703e48fc2c9994c9059ed016f05559George Mount app(") ", it.getCastExpr().toCode()) 239e4b93061ac703e48fc2c9994c9059ed016f05559George Mount } 240d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar else -> kcode("//NOT IMPLEMENTED YET") 241d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 242d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 243d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 244d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 245d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.isVariable() = this is IdentifierExpr && this.isDynamic() 246d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 247d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.conditionalFlagName(output : Boolean, suffix : String) = "${dirtyFlagName}_${output}$suffix" 248d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 249d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 250de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.dirtyFlagSet by Delegates.lazy { expr : Expr -> 251d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getInvalidFlags(), expr.getModel().getFlagBucketCount()) 252d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 253d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 254de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.invalidateFlagSet by Delegates.lazy { expr : Expr -> 255d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getId()) 256d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 257d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 258de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.shouldReadFlagSet by Delegates.lazy { expr : Expr -> 259d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getShouldReadFlags(), expr.getModel().getFlagBucketCount()) 260d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 261d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 262de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.conditionalFlags by Delegates.lazy { expr : Expr -> 263d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar arrayListOf(FlagSet(expr.getRequirementFlagIndex(false)), 264d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getRequirementFlagIndex(true))) 265d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 266d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 267d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.getRequirementFlagSet(expected : Boolean) : FlagSet = conditionalFlags[if(expected) 1 else 0] 268d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 269d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.notEmpty(cb : (suffix : String, value : Long) -> Unit) { 270d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar buckets.withIndex().forEach { 271d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (it.value != 0L) { 272d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar cb(getWordSuffix(it.index), buckets[it.index]) 273d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 274d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 275d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 276d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 277d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.getWordSuffix(wordIndex : Int) : String { 278d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return if(wordIndex == 0) "" else "_${wordIndex}" 279d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 280d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 281d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.localValue(bucketIndex : Int) = 282d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar if (getLocalName() == null) binaryCode(bucketIndex) 283d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar else "${getLocalName()}${getWordSuffix(bucketIndex)}" 284d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 285d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyarfun FlagSet.binaryCode(bucketIndex : Int) = longToBinary(buckets[bucketIndex]) 286d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 287d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 288d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyarfun longToBinary(l : Long) = 289d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar "0b${java.lang.Long.toBinaryString(l)}L" 290d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 291d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun <T> FlagSet.mapOr(other : FlagSet, cb : (suffix : String, index : Int) -> T) : List<T> { 292d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val min = Math.min(buckets.size(), other.buckets.size()) 293d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val result = arrayListOf<T>() 294d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in 0..(min - 1)) { 295d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // if these two can match by any chance, call the callback 296d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (intersect(other, i)) { 297d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar result.add(cb(getWordSuffix(i), i)) 298d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 299d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 300d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return result 301d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 302d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 30396e1c821dd446d1ed78f8ae61131550588f60a24George Mountfun indexFromTag(tag : String) : kotlin.Int { 30496e1c821dd446d1ed78f8ae61131550588f60a24George Mount val startIndex : kotlin.Int 3057ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount if (tag.startsWith("binding_")) { 3067ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount startIndex = "binding_".length(); 30796e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 30896e1c821dd446d1ed78f8ae61131550588f60a24George Mount startIndex = tag.lastIndexOf('_') + 1 30996e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 31096e1c821dd446d1ed78f8ae61131550588f60a24George Mount return Integer.parseInt(tag.substring(startIndex)) 31196e1c821dd446d1ed78f8ae61131550588f60a24George Mount} 31296e1c821dd446d1ed78f8ae61131550588f60a24George Mount 31343596c2b2997e40b709627419732100d78a62ff0Yigit Boyarclass LayoutBinderWriter(val layoutBinder : LayoutBinder) { 314d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val model = layoutBinder.getModel() 31534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val indices = HashMap<BindingTarget, kotlin.Int>() 31643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val mDirtyFlags by Delegates.lazy { 31743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val fs = FlagSet(BitSet(), model.getFlagBucketCount()); 31843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Arrays.fill(fs.buckets, -1) 31943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs.setDynamic(true) 32043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.localizeFlag(fs, "mDirtyFlags") 32143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs 322d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 323d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 32443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val dynamics by Delegates.lazy { model.getExprMap().values().filter { it.isDynamic() } } 325dea555cf42dc3583604699c8c018d22681f56166George Mount val className = layoutBinder.getImplementationName() 326d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 327dea555cf42dc3583604699c8c018d22681f56166George Mount val baseClassName = "${layoutBinder.getClassName()}" 328d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 3297551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar val includedBinders by Delegates.lazy { 3307551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar layoutBinder.getBindingTargets().filter { it.isBinder() } 3317551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 3327551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 33343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val variables by Delegates.lazy { 33443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.getExprMap().values().filterIsInstance(javaClass<IdentifierExpr>()).filter { it.isVariable() } 33543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 336d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 3375bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar val usedVariables by Delegates.lazy { 3385bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar variables.filter {it.isUsed()} 3395bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 340d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 34196e1c821dd446d1ed78f8ae61131550588f60a24George Mount public fun write(minSdk : kotlin.Int) : String { 3425bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar layoutBinder.resolveWhichExpressionsAreUsed() 34334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount calculateIndices(); 3445bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar return kcode("package ${layoutBinder.getPackage()};") { 345a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar nl("import ${layoutBinder.getModulePackage()}.R;") 346a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar nl("import ${layoutBinder.getModulePackage()}.BR;") 3475bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("import android.view.View;") 348dea555cf42dc3583604699c8c018d22681f56166George Mount val classDeclaration : String 349dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 350dea555cf42dc3583604699c8c018d22681f56166George Mount classDeclaration = "${className} extends ${baseClassName}" 351dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 352dea555cf42dc3583604699c8c018d22681f56166George Mount classDeclaration = "${className} extends android.databinding.ViewDataBinding" 353dea555cf42dc3583604699c8c018d22681f56166George Mount } 354dea555cf42dc3583604699c8c018d22681f56166George Mount nl("public class ${classDeclaration} {") { 3554c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(declareIncludeViews()) 3565bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareViews()) 3575bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareVariables()) 35896e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab(declareConstructor(minSdk)) 3595bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareInvalidateAll()) 3605bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareLog()) 3615bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareSetVariable()) 3625bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(variableSettersAndGetters()) 3635bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(onFieldChange()) 3645bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 3654c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(executePendingBindings()) 3665bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 3675bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareDirtyFlags()) 368dea555cf42dc3583604699c8c018d22681f56166George Mount if (!layoutBinder.hasVariations()) { 369dea555cf42dc3583604699c8c018d22681f56166George Mount tab(declareFactories()) 370dea555cf42dc3583604699c8c018d22681f56166George Mount } 3715bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 3725bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 3735bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(flagMapping()) 3745bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("//end") 3755bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar }.generate() 3765bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 37734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fun calculateIndices() : Unit { 37896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val taggedViews = layoutBinder.getBindingTargets().filter{ 37996e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && it.getTag() != null && !it.isBinder() 38034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 38196e1c821dd446d1ed78f8ae61131550588f60a24George Mount taggedViews.forEach { 38296e1c821dd446d1ed78f8ae61131550588f60a24George Mount indices.put(it, indexFromTag(it.getTag())) 38396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 38496e1c821dd446d1ed78f8ae61131550588f60a24George Mount val indexStart = maxIndex() + 1 38596e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getBindingTargets().filter{ 38696e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !taggedViews.contains(it) 38796e1c821dd446d1ed78f8ae61131550588f60a24George Mount }.withIndex().forEach { 38896e1c821dd446d1ed78f8ae61131550588f60a24George Mount indices.put(it.value, it.index + indexStart) 38934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 39034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 3914c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun declareIncludeViews() = kcode("") { 39296e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("private static final android.databinding.ViewDataBinding.IncludedLayoutIndex[][] sIncludes;") 3934c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("private static final android.util.SparseIntArray sViewsWithIds;") 3944c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("static {") { 3954c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount val hasBinders = layoutBinder.getBindingTargets().firstOrNull{ it.isUsed() && it.isBinder()} != null 3964c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount if (!hasBinders) { 3974c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sIncludes = null;") 39800da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 39996e1c821dd446d1ed78f8ae61131550588f60a24George Mount val numBindings = layoutBinder.getBindingTargets().filter{ it.isUsed() }.count() 40096e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("sIncludes = new android.databinding.ViewDataBinding.IncludedLayoutIndex[${numBindings}][];") 40196e1c821dd446d1ed78f8ae61131550588f60a24George Mount val includeMap = HashMap<BindingTarget, ArrayList<BindingTarget>>() 40296e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getBindingTargets().filter{ it.isUsed() && it.isBinder() }.forEach { 40396e1c821dd446d1ed78f8ae61131550588f60a24George Mount val includeTag = it.getTag(); 40496e1c821dd446d1ed78f8ae61131550588f60a24George Mount val parent = layoutBinder.getBindingTargets().firstOrNull { 40596e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !it.isBinder() && includeTag.equals(it.getTag()) 40696e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 40796e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (parent == null) { 40896e1c821dd446d1ed78f8ae61131550588f60a24George Mount throw IllegalStateException("Could not find parent of include file") 40996e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 41096e1c821dd446d1ed78f8ae61131550588f60a24George Mount var list = includeMap.get(parent) 41196e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (list == null) { 41296e1c821dd446d1ed78f8ae61131550588f60a24George Mount list = ArrayList<BindingTarget>() 41396e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.put(parent, list) 41496e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 41596e1c821dd446d1ed78f8ae61131550588f60a24George Mount list.add(it) 4164c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 41796e1c821dd446d1ed78f8ae61131550588f60a24George Mount 41896e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.keySet().forEach { 41996e1c821dd446d1ed78f8ae61131550588f60a24George Mount val index = indices.get(it) 42096e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("sIncludes[${index}] = new android.databinding.ViewDataBinding.IncludedLayoutIndex[] {") { 42196e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.get(it).forEach { 42296e1c821dd446d1ed78f8ae61131550588f60a24George Mount val bindingIndex = indices.get(it) 42396e1c821dd446d1ed78f8ae61131550588f60a24George Mount val layoutName = it.getIncludedLayout() 42496e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("new android.databinding.ViewDataBinding.IncludedLayoutIndex(\"${layoutName}\", ${bindingIndex}, R.layout.${layoutName}),") 42596e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 42696e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 42796e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("};") 42896e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 42996e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 43096e1c821dd446d1ed78f8ae61131550588f60a24George Mount val viewsWithIds = layoutBinder.getBindingTargets().filter { 43196e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !it.isBinder() && (!it.supportsTag() || (it.getId() != null && it.getTag() == null)) 43200da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 43396e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (viewsWithIds.isEmpty()) { 4344c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = null;") 43500da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 4364c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = new android.util.SparseIntArray();") 43796e1c821dd446d1ed78f8ae61131550588f60a24George Mount viewsWithIds.forEach { 43834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("sViewsWithIds.put(${it.androidId}, ${indices.get(it)});") 4394c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 44000da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 4414c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 4424c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("}") 4434c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 44496e1c821dd446d1ed78f8ae61131550588f60a24George Mount 44596e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun maxIndex() : kotlin.Int { 44696e1c821dd446d1ed78f8ae61131550588f60a24George Mount val maxIndex = indices.values().max() 44796e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (maxIndex == null) { 44896e1c821dd446d1ed78f8ae61131550588f60a24George Mount return -1 44996e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 45096e1c821dd446d1ed78f8ae61131550588f60a24George Mount return maxIndex 45196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 45296e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 45396e1c821dd446d1ed78f8ae61131550588f60a24George Mount 45496e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun declareConstructor(minSdk : kotlin.Int) = kcode("") { 45596e1c821dd446d1ed78f8ae61131550588f60a24George Mount val bindingCount = maxIndex() + 1 45696e1c821dd446d1ed78f8ae61131550588f60a24George Mount val parameterType : String 45796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val superParam : String 45896e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (layoutBinder.isMerge()) { 45996e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View[]" 46096e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root[0]" 46196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 46296e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View" 46396e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root" 46496e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 46596e1c821dd446d1ed78f8ae61131550588f60a24George Mount val rootTagsSupported = minSdk >= 14 466dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 467dea555cf42dc3583604699c8c018d22681f56166George Mount nl("") 46896e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public ${className}(${parameterType} root) {") { 46996e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("this(${superParam}, mapBindings(root, ${bindingCount}, sIncludes, sViewsWithIds));") 470dea555cf42dc3583604699c8c018d22681f56166George Mount } 471dea555cf42dc3583604699c8c018d22681f56166George Mount nl("}") 47296e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("private ${className}(${parameterType} root, Object[] bindings) {") { 47396e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("super(${superParam}, ${model.getObservables().size()}") { 47496e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter { it.getId() != null }.forEach { 475dea555cf42dc3583604699c8c018d22681f56166George Mount tab(", ${fieldConversion(it)}") 47634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 477dea555cf42dc3583604699c8c018d22681f56166George Mount tab(");") 47834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 47934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 480dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 48196e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public ${baseClassName}(${parameterType} root) {") { 48296e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("super(${superParam}, ${model.getObservables().size()});") 48396e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("final Object[] bindings = mapBindings(root, ${bindingCount}, sIncludes, sViewsWithIds);") 484dea555cf42dc3583604699c8c018d22681f56166George Mount } 485dea555cf42dc3583604699c8c018d22681f56166George Mount } 48696e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("setRootTag(root);") 48796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val taggedViews = layoutBinder.getSortedTargets().filter{it.isUsed()} 488dea555cf42dc3583604699c8c018d22681f56166George Mount taggedViews.forEach { 489dea555cf42dc3583604699c8c018d22681f56166George Mount if (!layoutBinder.hasVariations() || it.getId() == null) { 490dea555cf42dc3583604699c8c018d22681f56166George Mount tab("this.${it.fieldName} = ${fieldConversion(it)};") 491dea555cf42dc3583604699c8c018d22681f56166George Mount } 492dea555cf42dc3583604699c8c018d22681f56166George Mount if (!it.isBinder()) { 493de38dd3ef0577d25b2d59863603abe5750d0c231George Mount if (it.getResolvedType() != null && it.getResolvedType().extendsViewStub()) { 494de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("this.${it.fieldName}.setContainingBinding(this);") 495de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 49696e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (it.supportsTag() && it.getTag() != null && 4977ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount (rootTagsSupported || it.getTag().startsWith("binding_"))) { 498dea555cf42dc3583604699c8c018d22681f56166George Mount val originalTag = it.getOriginalTag(); 499dea555cf42dc3583604699c8c018d22681f56166George Mount var tagValue = "null" 500dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag != null) { 501dea555cf42dc3583604699c8c018d22681f56166George Mount tagValue = "\"${originalTag}\"" 502dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@")) { 503dea555cf42dc3583604699c8c018d22681f56166George Mount var packageName = layoutBinder.getModulePackage() 504dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@android:")) { 505dea555cf42dc3583604699c8c018d22681f56166George Mount packageName = "android" 50600da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 507dea555cf42dc3583604699c8c018d22681f56166George Mount val slashIndex = originalTag.indexOf('/') 508dea555cf42dc3583604699c8c018d22681f56166George Mount val resourceId = originalTag.substring(slashIndex + 1) 509dea555cf42dc3583604699c8c018d22681f56166George Mount tagValue = "root.getResources().getString(${packageName}.R.string.${resourceId})" 51000da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 51100da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 512dea555cf42dc3583604699c8c018d22681f56166George Mount tab("this.${it.fieldName}.setTag(${tagValue});") 5137551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 514d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 515d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 516dea555cf42dc3583604699c8c018d22681f56166George Mount tab("invalidateAll();"); 5170fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 518d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 519d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 520dea555cf42dc3583604699c8c018d22681f56166George Mount fun fieldConversion(target : BindingTarget) : String { 521dea555cf42dc3583604699c8c018d22681f56166George Mount if (!target.isUsed()) { 522dea555cf42dc3583604699c8c018d22681f56166George Mount return "null" 523dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 52496e1c821dd446d1ed78f8ae61131550588f60a24George Mount val index = indices.get(target) 525dea555cf42dc3583604699c8c018d22681f56166George Mount if (index == null) { 52696e1c821dd446d1ed78f8ae61131550588f60a24George Mount throw IllegalStateException("Unknown binding target") 527dea555cf42dc3583604699c8c018d22681f56166George Mount } 52896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val variableName = "bindings[${index}]" 529dea555cf42dc3583604699c8c018d22681f56166George Mount return target.superConversion(variableName) 530dea555cf42dc3583604699c8c018d22681f56166George Mount } 531dea555cf42dc3583604699c8c018d22681f56166George Mount } 532dea555cf42dc3583604699c8c018d22681f56166George Mount 533d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareInvalidateAll() = kcode("") { 5347551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("@Override") 5357551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("public void invalidateAll() {") { 536019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val fs = FlagSet(layoutBinder.getModel().getInvalidateAnyBitSet(), 537019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar layoutBinder.getModel().getFlagBucketCount()); 538d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in (0..(mDirtyFlags.buckets.size() - 1))) { 539d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${mDirtyFlags.localValue(i)} = ${fs.localValue(i)};") 540d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 5415bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar includedBinders.filter{it.isUsed()}.forEach { binder -> 5427551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar tab("${binder.fieldName}.invalidateAll();") 5437551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 544d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 5450fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 546d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 547d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 548d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareSetVariable() = kcode("") { 5490fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("public boolean setVariable(int variableId, Object variable) {") { 550d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch(variableId) {") { 5515bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 55243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab ("case ${it.getName().br()} :") { 553d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${it.setterName}((${it.getResolvedType().toJavaCode()}) variable);") 554d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 555d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 556d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 557d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 558d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 559d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 560d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 5610fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 562d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 563d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 564d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareLog() = kcode("") { 5650fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private void log(String msg, long i) {") { 566d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("""android.util.Log.d("BINDER", msg + ":" + Long.toHexString(i));""") 5670fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 5680fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 569d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 570d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 571d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun variableSettersAndGetters() = kcode("") { 5725bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar variables.filterNot{it.isUsed()}.forEach { 573019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar nl("public void ${it.setterName}(${it.getResolvedType().toJavaCode()} ${it.readableName}) {") { 5745bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("// not used, ignore") 5755bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5765bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 5775bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("") 5785bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("public ${it.getResolvedType().toJavaCode()} ${it.getterName}() {") { 5795bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("return ${it.getDefaultValue()};") 5805bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5815bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 5825bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5835bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 58418243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.getUserDefinedType() != null) { 585019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar nl("public void ${it.setterName}(${it.getResolvedType().toJavaCode()} ${it.readableName}) {") { 58618243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.isObservable()) { 587019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("updateRegistration(${it.getId()}, ${it.readableName});"); 58818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 589019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("this.${it.fieldName} = ${it.readableName};") 59018243f6f1b7527272ef4feccdf4327d80d9f2241George Mount // set dirty flags! 59118243f6f1b7527272ef4feccdf4327d80d9f2241George Mount val flagSet = it.invalidateFlagSet 59218243f6f1b7527272ef4feccdf4327d80d9f2241George Mount mDirtyFlags.mapOr(flagSet) { suffix, index -> 59318243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("${mDirtyFlags.getLocalName()}$suffix |= ${flagSet.localValue(index)};") 59418243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 59518243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("super.requestRebind();") 596d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 59718243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 59818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("") 59918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("public ${it.getResolvedType().toJavaCode()} ${it.getterName}() {") { 60018243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("return ${it.fieldName};") 601d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 60218243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 603d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 604d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 605d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 606d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 607d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun onFieldChange() = kcode("") { 60834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("@Override") 60934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {") { 6104c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("switch (localFieldId) {") { 611d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getObservables().forEach { 612d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("case ${it.getId()} :") { 613d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return ${it.onChangeName}((${it.getResolvedType().toJavaCode()}) object, fieldId);") 614d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 615d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 616d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 617d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 618d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 619d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 62034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 62134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 622d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 623d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getObservables().forEach { 624019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar nl("private boolean ${it.onChangeName}(${it.getResolvedType().toJavaCode()} ${it.readableName}, int fieldId) {") { 625d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch (fieldId) {", { 626d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val accessedFields: List<FieldAccessExpr> = it.getParents().filterIsInstance(javaClass<FieldAccessExpr>()) 627d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar accessedFields.filter { it.canBeInvalidated() } 628d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .groupBy { it.getName() } 629d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 63043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${it.key.br()}:") { 631d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val field = it.value.first() 632d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mDirtyFlags.mapOr(field.invalidateFlagSet) { suffix, index -> 633d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${mDirtyFlags.localValue(index)} |= ${field.invalidateFlagSet.localValue(index)};") 634d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 635d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 636d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 637d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 638d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 63943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${"".br()}:") { 640d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.invalidateFlagSet 641d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 642d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${mDirtyFlags.getLocalName()}$suffix |= ${flagSet.localValue(index)};") 643d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 644d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 645d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 646d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 647d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) 648d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 649d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 650d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 65134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 65234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 653d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 654d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 655d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 656d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareViews() = kcode("// views") { 657dea555cf42dc3583604699c8c018d22681f56166George Mount val oneLayout = !layoutBinder.hasVariations(); 65896e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter {it.isUsed() && (oneLayout || it.getId() == null)}.forEach { 659dea555cf42dc3583604699c8c018d22681f56166George Mount val access : String 660dea555cf42dc3583604699c8c018d22681f56166George Mount if (oneLayout && it.getId() != null) { 661dea555cf42dc3583604699c8c018d22681f56166George Mount access = "public" 662dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 663dea555cf42dc3583604699c8c018d22681f56166George Mount access = "private" 664dea555cf42dc3583604699c8c018d22681f56166George Mount } 665dea555cf42dc3583604699c8c018d22681f56166George Mount nl("${access} final ${it.interfaceType} ${it.fieldName};") 666d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 667d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 668d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 669d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareVariables() = kcode("// variables") { 6705bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 6710fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private ${it.getResolvedType().toJavaCode()} ${it.fieldName};") 672d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 673d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 674d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 675d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareDirtyFlags() = kcode("// dirty flag") { 676d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.ext.localizedFlags.forEach { flag -> 677de38dd3ef0577d25b2d59863603abe5750d0c231George Mount flag.notEmpty { suffix, value -> 6780fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private") 679d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(" ", if(flag.isDynamic()) null else "static final"); 680d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar app(" ", " ${flag.type} ${flag.getLocalName()}$suffix = ${longToBinary(value)};") 681d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 682d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 683d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 684d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 685d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun flagMapping() = kcode("/* flag mapping") { 686d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (model.getFlagMapping() != null) { 687d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val mapping = model.getFlagMapping() 688d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in mapping.indices) { 689d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("flag $i: ${mapping[i]}") 690d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 691d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 692d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nl("flag mapping end*/") 693d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 694d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 6954c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun executePendingBindings() = kcode("") { 6960fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("@Override") 6974c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("public void executePendingBindings() {") { 698d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val tmpDirtyFlags = FlagSet(mDirtyFlags.buckets) 699d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tmpDirtyFlags.setLocalName("dirtyFlags"); 700d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in (0..mDirtyFlags.buckets.size() - 1)) { 701d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${tmpDirtyFlags.type} ${tmpDirtyFlags.localValue(i)} = ${mDirtyFlags.localValue(i)};") 702d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${mDirtyFlags.localValue(i)} = 0;") 703d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 704d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getPendingExpressions().filterNot {it.isVariable()}.forEach { 705019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("${it.getResolvedType().toJavaCode()} ${it.executePendingLocalName} = ${it.getDefaultValue()};") 706d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 707019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Log.d {"writing executePendingBindings for $className"} 708d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar do { 70974f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyar val batch = ExprModel.filterShouldRead(model.getPendingExpressions()).toArrayList() 710019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Log.d {"batch: $batch"} 711d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val mJustRead = arrayListOf<Expr>() 712d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar while (!batch.none()) { 7130fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val readNow = batch.filter { it.shouldReadNow(mJustRead) } 714d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (readNow.isEmpty()) { 715d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar throw IllegalStateException("do not know what I can read. bailing out ${batch.joinToString("\n")}") 716d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 71743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Log.d { "new read now. batch size: ${batch.size()}, readNow size: ${readNow.size()}" } 718d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 719d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar readNow.forEach { 7200fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl(readWithDependants(it, mJustRead, batch, tmpDirtyFlags)) 721d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 722d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar batch.removeAll(mJustRead) 723d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7240fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// batch finished") 725d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } while(model.markBitsRead()) 726d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 727d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // 72896e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter { it.isUsed() } 729d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .flatMap { it.getBindings() } 730d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .groupBy { it.getExpr() } 731d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 732d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.key.dirtyFlagSet 733d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 734d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 735d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }.joinToString(" || ") 736d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) {") { 737d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.value.forEach { binding -> 73897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("// api target ${binding.getMinApi()}") 73934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val fieldName : String 74034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount if (binding.getTarget().getViewClass(). 74134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount equals(binding.getTarget().getInterfaceType())) { 74234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fieldName = "this.${binding.getTarget().fieldName}" 74334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } else { 74434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fieldName = "((${binding.getTarget().getViewClass()}) this.${binding.getTarget().fieldName})" 74534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 74634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val bindingCode = binding.toJavaCode(fieldName, binding.getExpr().toCode().generate()) 74797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar if (binding.getMinApi() > 1) { 7484c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("if(getBuildSdkInt() >= ${binding.getMinApi()}) {") { 74997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("$bindingCode;") 75097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 75197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("}") 75297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } else { 75397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("$bindingCode;") 75497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 755d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 756d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 757d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 758d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7595bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar includedBinders.filter{it.isUsed()}.forEach { binder -> 7604c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("${binder.fieldName}.executePendingBindings();") 7617551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 76296e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{ 763de38dd3ef0577d25b2d59863603abe5750d0c231George Mount it.isUsed() && it.getResolvedType() != null && it.getResolvedType().extendsViewStub() 764de38dd3ef0577d25b2d59863603abe5750d0c231George Mount }.forEach { 765de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("if (${it.fieldName}.getBinding() != null) {") { 766de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("${it.fieldName}.getBinding().executePendingBindings();") 767de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 768de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("}") 769de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 770d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7710fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 772d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 773d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 774d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar fun readWithDependants(expr : Expr, mJustRead : MutableList<Expr>, batch : MutableList<Expr>, 775d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tmpDirtyFlags : FlagSet, inheritedFlags : FlagSet? = null) : KCode = kcode("") { 776d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mJustRead.add(expr) 777019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Log.d { "$className / readWithDependants: ${expr.getUniqueKey()}" } 778d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = expr.shouldReadFlagSet 779d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val needsIfWrapper = inheritedFlags == null || !flagSet.bitsEqual(inheritedFlags) 780019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar Log.d { "flag set:$flagSet . inherited flags: $inheritedFlags. need another if: $needsIfWrapper"} 781d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val ifClause = "if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 78243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 78343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.joinToString(" || ") 784d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar })" 785d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 786d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val readCode = kcode("") { 787d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (!expr.isVariable()) { 788d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // it is not a variable read it. 789d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("// read ${expr.getUniqueKey()}") 790d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // create an if case for all dependencies that might be null 791d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val nullables = expr.getDependencies().filter { 792e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount it.isMandatory() && it.getOther().getResolvedType().isNullable() 79374f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyar }.map { it.getOther() } 794d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (!expr.isEqualityCheck() && nullables.isNotEmpty()) { 795019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab ("if ( ${nullables.map { "${it.executePendingLocalName} != null" }.joinToString(" && ")}) {") { 796019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("${expr.executePendingLocalName}").app(" = ", expr.toCode(true)).app(";") 797d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 798d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 799d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } else { 800019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("${expr.executePendingLocalName}").app(" = ", expr.toCode(true)).app(";") 801d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8027920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount if (expr.isObservable()) { 803019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("updateRegistration(${expr.getId()}, ${expr.executePendingLocalName});") 804d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8050fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 806d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 8070fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar // if I am the condition for an expression, set its flag 8080fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val conditionals = expr.getDependants().filter { !it.isConditional() 8090fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar && it.getDependant() is TernaryExpr && (it.getDependant() as TernaryExpr).getPred() == expr } 8100fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar .map { it.getDependant() } 8110fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar if (conditionals.isNotEmpty()) { 8120fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// setting conditional flags") 813019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("if (${expr.executePendingLocalName}) {") { 8140fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar conditionals.forEach { 8150fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val set = it.getRequirementFlagSet(true) 8160fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar mDirtyFlags.mapOr(set) { suffix , index -> 8170fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 818d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 819d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 820d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8210fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("} else {") { 8220fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar conditionals.forEach { 8230fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val set = it.getRequirementFlagSet(false) 8240fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar mDirtyFlags.mapOr(set) { suffix , index -> 8250fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 8260fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 8270fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 8280fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } tab("}") 829d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8300fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar 831d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val chosen = expr.getDependants().filter { 832d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val dependant = it.getDependant() 833d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar batch.contains(dependant) && 834d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar dependant.shouldReadFlagSet.andNot(flagSet).isEmpty() && 835d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar dependant.shouldReadNow(mJustRead) 836d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 837d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (chosen.isNotEmpty()) { 838d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val nextInheritedFlags = if (needsIfWrapper) flagSet else inheritedFlags 839d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar chosen.forEach { 840d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readWithDependants(it.getDependant(), mJustRead, batch, tmpDirtyFlags, nextInheritedFlags)) 841d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 842d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 843d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 844d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar if (needsIfWrapper) { 845d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tab(ifClause) { 846d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar app(" {") 847d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readCode) 848d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 849d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tab("}") 850d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } else { 851d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readCode) 852d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 853d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 85443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 855dea555cf42dc3583604699c8c018d22681f56166George Mount fun declareFactories() = kcode("") { 85696e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (!layoutBinder.isMerge()) { 85796e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public static ${baseClassName} inflate(android.view.ViewGroup root) {") { 85896e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("return bind(android.view.LayoutInflater.from(root.getContext()).inflate(${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, root, true));") 859dea555cf42dc3583604699c8c018d22681f56166George Mount } 86096e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 86196e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public static ${baseClassName} inflate(android.content.Context context) {") { 86296e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("return bind(android.view.LayoutInflater.from(context).inflate(${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, null, false));") 86396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 86496e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 86596e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public static ${baseClassName} bind(android.view.View view) {") { 86696e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("if (!\"${layoutBinder.getTag()}_0\".equals(view.getTag())) {") { 86796e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("throw new RuntimeException(\"view tag isn't correct on view\");") 86896e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 86996e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("}") 87096e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("return new ${baseClassName}(view);") 87196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 87296e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 873dea555cf42dc3583604699c8c018d22681f56166George Mount } 874dea555cf42dc3583604699c8c018d22681f56166George Mount } 875dea555cf42dc3583604699c8c018d22681f56166George Mount 8764c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount public fun writeBaseClass() : String = 87743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar kcode("package ${layoutBinder.getPackage()};") { 878fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.Bindable;") 879fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.DataBindingUtil;") 880fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.ViewDataBinding;") 8814c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("public abstract class ${baseClassName} extends ViewDataBinding {") 88296e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 883de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("public final ${it.interfaceType} ${it.fieldName};") 88434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 88534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 88634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("protected ${baseClassName}(android.view.View root_, int localFieldCount") { 88796e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 888019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab(", ${it.interfaceType} ${it.constructorParamName}") 88934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 89034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 89134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab(") {") { 89234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("super(root_, localFieldCount);") 89396e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 894019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("this.${it.fieldName} = ${it.constructorParamName};") 89534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 8964c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 8974c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 8984c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("") 89943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar variables.forEach { 90018243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.getUserDefinedType() != null) { 901895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar //it.getExpandedUserDefinedType(ModelAnalyzer.getInstance()); 902895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar val type = ModelAnalyzer.getInstance().applyImports(it.getUserDefinedType(), model.getImports()) 903019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("public abstract void ${it.setterName}(${type} ${it.readableName});") 90418243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 90543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 9064c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public static ${baseClassName} inflate(android.view.ViewGroup root) {") { 907a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar tab("return DataBindingUtil.<${baseClassName}>inflate(root.getContext(), ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, root, true);") 90843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 9094c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 9104c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public static ${baseClassName} inflate(android.content.Context context) {") { 911a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar tab("return DataBindingUtil.<${baseClassName}>inflate(context, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, null, false);") 9124c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 9134c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 9144c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public static ${baseClassName} bind(android.view.View view) {") { 915a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar tab("return (${baseClassName})DataBindingUtil.bindTo(view, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()});") 9164c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 9174c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 91843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar nl("}") 91943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.generate() 920dea555cf42dc3583604699c8c018d22681f56166George Mount} 921