LayoutBinderWriter.kt revision 7ff60c24c6de7ba0c674fe65a82ad4a88dab2e5d
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 47d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarclass ExprModelExt { 48d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val usedFieldNames = hashSetOf<String>() 49d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val localizedFlags = arrayListOf<FlagSet>() 50d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 51d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun localizeFlag(set : FlagSet, name:String) : FlagSet { 52d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar localizedFlags.add(set) 53d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val result = getUniqueFieldName(name) 54d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar set.setLocalName(result) 55d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return set 56d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 57d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 58d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun getUniqueFieldName(base : String) : String { 59d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var candidate = base 60d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var i = 0 61d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar while (usedFieldNames.contains(candidate)) { 62d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar i ++ 63d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar candidate = base + i 64d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 65d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar usedFieldNames.add(candidate) 66d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return candidate 67d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 68d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 69d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 70de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval ExprModel.ext by Delegates.lazy { target : ExprModel -> 71d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar ExprModelExt() 72d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 73d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 74d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun ExprModel.getUniqueFieldName(base : String) : String = ext.getUniqueFieldName(base) 75d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 76d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun ExprModel.localizeFlag(set : FlagSet, base : String) : FlagSet = ext.localizeFlag(set, base) 77d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 78de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.readableUniqueName by Delegates.lazy { target: BindingTarget -> 7900da715547ee7d5d38a3b8576090ca427a94daa5George Mount val variableName : String 8000da715547ee7d5d38a3b8576090ca427a94daa5George Mount if (target.getId() == null) { 8196e1c821dd446d1ed78f8ae61131550588f60a24George Mount variableName = "boundView" + indexFromTag(target.getTag()) 8200da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 8300da715547ee7d5d38a3b8576090ca427a94daa5George Mount variableName = target.getId().androidId().stripNonJava() 8400da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 8500da715547ee7d5d38a3b8576090ca427a94daa5George Mount target.getModel().ext.getUniqueFieldName(variableName) 86d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 877551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 88de38dd3ef0577d25b2d59863603abe5750d0c231George Mountfun BindingTarget.superConversion(variable : String) : String { 8996e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (getResolvedType() != null && getResolvedType().extendsViewStub()) { 90de38dd3ef0577d25b2d59863603abe5750d0c231George Mount return "new android.databinding.ViewStubProxy((android.view.ViewStub) ${variable})" 91de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } else { 92de38dd3ef0577d25b2d59863603abe5750d0c231George Mount return "(${interfaceType}) ${variable}" 93de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 94de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 95de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 96de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.fieldName by Delegates.lazy { target : BindingTarget -> 9734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount if (target.getFieldName() == null) { 9834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount if (target.getId() == null) { 9934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount target.setFieldName("m${target.readableUniqueName.capitalize()}") 10034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } else { 10134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount target.androidId.stripNonJava(); 10234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount target.setFieldName(target.readableUniqueName); 10334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 10434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 10534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount target.getFieldName(); 106d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 107d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 108de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.getterName by Delegates.lazy { target : BindingTarget -> 109d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "get${target.readableUniqueName.capitalize()}" 110d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 111d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 112de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.androidId by Delegates.lazy { target : BindingTarget -> 11343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar "R.id.${target.getId().androidId()}" 114d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 115d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 116de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.interfaceType by Delegates.lazy { target : BindingTarget -> 117de38dd3ef0577d25b2d59863603abe5750d0c231George Mount if (target.getResolvedType() != null && target.getResolvedType().extendsViewStub()) { 118de38dd3ef0577d25b2d59863603abe5750d0c231George Mount "android.databinding.ViewStubProxy" 119de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } else { 120de38dd3ef0577d25b2d59863603abe5750d0c231George Mount target.getInterfaceType() 121de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 122de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 123de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 124de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.readableUniqueName by Delegates.lazy { expr : Expr -> 12543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Log.d { "readableUniqueName for ${expr.getUniqueKey()}" } 126d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val stripped = "${expr.getUniqueKey().stripNonJava()}" 127d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar expr.getModel().ext.getUniqueFieldName(stripped) 128d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 129d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 130de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.readableName by Delegates.lazy { expr : Expr -> 131de38dd3ef0577d25b2d59863603abe5750d0c231George Mount Log.d { "readableUniqueName for ${expr.getUniqueKey()}" } 132de38dd3ef0577d25b2d59863603abe5750d0c231George Mount "${expr.getUniqueKey().stripNonJava()}" 133de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 134de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 135de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.fieldName by Delegates.lazy { expr : Expr -> 136de38dd3ef0577d25b2d59863603abe5750d0c231George Mount "m${expr.readableName.capitalize()}" 137d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 138d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 139de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.hasFlag by Delegates.lazy { expr : Expr -> 140d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar expr.getId() < expr.getModel().getInvalidateableFieldLimit() 141d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 142d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 143de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.localName by Delegates.lazy { expr : Expr -> 144d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if(expr.isVariable()) expr.fieldName else "${expr.readableUniqueName}" 145d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 146d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 147de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.setterName by Delegates.lazy { expr : Expr -> 148de38dd3ef0577d25b2d59863603abe5750d0c231George Mount "set${expr.readableName.capitalize()}" 149d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 150d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 151de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.onChangeName by Delegates.lazy { expr : Expr -> 152d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "onChange${expr.readableUniqueName.capitalize()}" 153d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 154d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 155de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.getterName by Delegates.lazy { expr : Expr -> 156de38dd3ef0577d25b2d59863603abe5750d0c231George Mount "get${expr.readableName.capitalize()}" 157d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 158d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 159de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.dirtyFlagName by Delegates.lazy { expr : Expr -> 160d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "sFlag${expr.readableUniqueName.capitalize()}" 161d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 162d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 163de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.shouldReadFlagName by Delegates.lazy { expr : Expr -> 164d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "sFlagRead${expr.readableUniqueName.capitalize()}" 165d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 166d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 167de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.invalidateFlagName by Delegates.lazy { expr : Expr -> 168d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "sFlag${expr.readableUniqueName.capitalize()}Invalid" 169d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 170d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 171de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.conditionalFlagPrefix by Delegates.lazy { expr : Expr -> 172d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "sFlag${expr.readableUniqueName.capitalize()}Is" 173d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 174d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 175d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 176d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.toCode(full : Boolean = false) : KCode { 177d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val it = this 178d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (isDynamic() && !full) { 179d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return kcode(localName) 180d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 181d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return when (it) { 182d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is ComparisonExpr -> kcode("") { 183d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getLeft().toCode()) 184d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(it.getOp()) 185d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getRight().toCode()) 186d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 187d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is FieldAccessExpr -> kcode("") { 188a70fed6415aa1e8bbbe929aee776402ac3b81c86George Mount app("", it.getChild().toCode()) 189e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount if (it.getGetter().type == Callable.Type.FIELD) { 190d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(".", it.getGetter().name) 191d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } else { 192d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(".", it.getGetter().name).app("()") 193d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 194d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 195d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is GroupExpr -> kcode("(").app("", it.getWrapped().toCode()).app(")") 196d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is StaticIdentifierExpr -> kcode(it.getResolvedType().toJavaCode()) 197d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is IdentifierExpr -> kcode(it.localName) 198d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is MathExpr -> kcode("") { 199d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getLeft().toCode()) 200d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(it.getOp()) 201d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getRight().toCode()) 202d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 203d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is MethodCallExpr -> kcode("") { 204d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getTarget().toCode()) 205d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(".", it.getGetter().name) 206d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("(") 207d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var first = true 208d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.getArgs().forEach { 209d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar apps(if (first) "" else ",", it.toCode()) 210d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar first = false 211d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 212d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(")") 213d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 214d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is SymbolExpr -> kcode(it.getText()) // TODO 215d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is TernaryExpr -> kcode("") { 216d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getPred().toCode()) 217d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("?", it.getIfTrue().toCode()) 218d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(":", it.getIfFalse().toCode()) 219d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 220c752a5f795baf6df435ef60881316cb748df407cGeorge Mount is ResourceExpr -> kcode("") { 221c752a5f795baf6df435ef60881316cb748df407cGeorge Mount app("", it.toJava()) 222c752a5f795baf6df435ef60881316cb748df407cGeorge Mount } 2235cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount is BracketExpr -> kcode("") { 2245cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("", it.getTarget().toCode()) 2255cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount val bracketType = it.getAccessor(); 2265cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount when (bracketType) { 2275cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount BracketExpr.BracketAccessor.ARRAY -> { 2285cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("[", it.getArg().toCode()) 2295cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("]") 2305cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2315cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount BracketExpr.BracketAccessor.LIST -> { 2325cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(".get(") 2335cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount if (it.argCastsInteger()) { 2345cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("(Integer)") 2355cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2365cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("", it.getArg().toCode()) 2375cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(")") 2385cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2395cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount BracketExpr.BracketAccessor.MAP -> { 2405cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(".get(", it.getArg().toCode()) 2415cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(")") 2425cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2435cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2445cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 245e4b93061ac703e48fc2c9994c9059ed016f05559George Mount is CastExpr -> kcode("") { 246e4b93061ac703e48fc2c9994c9059ed016f05559George Mount app("(", it.getCastType()) 247e4b93061ac703e48fc2c9994c9059ed016f05559George Mount app(") ", it.getCastExpr().toCode()) 248e4b93061ac703e48fc2c9994c9059ed016f05559George Mount } 249d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar else -> kcode("//NOT IMPLEMENTED YET") 250d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 251d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 252d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 253d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 254d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.isVariable() = this is IdentifierExpr && this.isDynamic() 255d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 256d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.conditionalFlagName(output : Boolean, suffix : String) = "${dirtyFlagName}_${output}$suffix" 257d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 258d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 259de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.dirtyFlagSet by Delegates.lazy { expr : Expr -> 260d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getInvalidFlags(), expr.getModel().getFlagBucketCount()) 261d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 262d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 263de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.invalidateFlagSet by Delegates.lazy { expr : Expr -> 264d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getId()) 265d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 266d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 267de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.shouldReadFlagSet by Delegates.lazy { expr : Expr -> 268d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getShouldReadFlags(), expr.getModel().getFlagBucketCount()) 269d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 270d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 271de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.conditionalFlags by Delegates.lazy { expr : Expr -> 272d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar arrayListOf(FlagSet(expr.getRequirementFlagIndex(false)), 273d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getRequirementFlagIndex(true))) 274d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 275d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 276d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.getRequirementFlagSet(expected : Boolean) : FlagSet = conditionalFlags[if(expected) 1 else 0] 277d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 278d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.notEmpty(cb : (suffix : String, value : Long) -> Unit) { 279d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar buckets.withIndex().forEach { 280d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (it.value != 0L) { 281d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar cb(getWordSuffix(it.index), buckets[it.index]) 282d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 283d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 284d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 285d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 286d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.getBitSuffix(bitIndex : Int) : String { 287d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val word = bitIndex / FlagSet.sBucketSize 288d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return getWordSuffix(word) 289d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 290d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 291d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.getWordSuffix(wordIndex : Int) : String { 292d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return if(wordIndex == 0) "" else "_${wordIndex}" 293d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 294d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 295d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.localValue(bucketIndex : Int) = 296d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar if (getLocalName() == null) binaryCode(bucketIndex) 297d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar else "${getLocalName()}${getWordSuffix(bucketIndex)}" 298d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 299d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyarfun FlagSet.binaryCode(bucketIndex : Int) = longToBinary(buckets[bucketIndex]) 300d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 301d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 302d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyarfun longToBinary(l : Long) = 303d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar "0b${java.lang.Long.toBinaryString(l)}L" 304d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 305d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun <T> FlagSet.mapOr(other : FlagSet, cb : (suffix : String, index : Int) -> T) : List<T> { 306d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val min = Math.min(buckets.size(), other.buckets.size()) 307d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val result = arrayListOf<T>() 308d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in 0..(min - 1)) { 309d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // if these two can match by any chance, call the callback 310d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (intersect(other, i)) { 311d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar result.add(cb(getWordSuffix(i), i)) 312d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 313d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 314d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return result 315d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 316d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 31796e1c821dd446d1ed78f8ae61131550588f60a24George Mountfun indexFromTag(tag : String) : kotlin.Int { 31896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val startIndex : kotlin.Int 3197ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount if (tag.startsWith("binding_")) { 3207ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount startIndex = "binding_".length(); 32196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 32296e1c821dd446d1ed78f8ae61131550588f60a24George Mount startIndex = tag.lastIndexOf('_') + 1 32396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 32496e1c821dd446d1ed78f8ae61131550588f60a24George Mount return Integer.parseInt(tag.substring(startIndex)) 32596e1c821dd446d1ed78f8ae61131550588f60a24George Mount} 32696e1c821dd446d1ed78f8ae61131550588f60a24George Mount 32743596c2b2997e40b709627419732100d78a62ff0Yigit Boyarclass LayoutBinderWriter(val layoutBinder : LayoutBinder) { 328d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val model = layoutBinder.getModel() 32934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val indices = HashMap<BindingTarget, kotlin.Int>() 33043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val mDirtyFlags by Delegates.lazy { 33143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val fs = FlagSet(BitSet(), model.getFlagBucketCount()); 33243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Arrays.fill(fs.buckets, -1) 33343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs.setDynamic(true) 33443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.localizeFlag(fs, "mDirtyFlags") 33543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs 336d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 337d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 33843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val dynamics by Delegates.lazy { model.getExprMap().values().filter { it.isDynamic() } } 339dea555cf42dc3583604699c8c018d22681f56166George Mount val className = layoutBinder.getImplementationName() 340d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 34143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val identifiers by Delegates.lazy { 34243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar dynamics.filter { it is IdentifierExpr } 34343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 344d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 345dea555cf42dc3583604699c8c018d22681f56166George Mount val baseClassName = "${layoutBinder.getClassName()}" 346d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 3477551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar val includedBinders by Delegates.lazy { 3487551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar layoutBinder.getBindingTargets().filter { it.isBinder() } 3497551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 3507551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 35143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val variables by Delegates.lazy { 35243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.getExprMap().values().filterIsInstance(javaClass<IdentifierExpr>()).filter { it.isVariable() } 35343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 354d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 3555bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar val usedVariables by Delegates.lazy { 3565bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar variables.filter {it.isUsed()} 3575bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 358d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 35996e1c821dd446d1ed78f8ae61131550588f60a24George Mount public fun write(minSdk : kotlin.Int) : String { 3605bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar layoutBinder.resolveWhichExpressionsAreUsed() 36134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount calculateIndices(); 3625bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar return kcode("package ${layoutBinder.getPackage()};") { 363a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar nl("import ${layoutBinder.getModulePackage()}.R;") 364a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar nl("import ${layoutBinder.getModulePackage()}.BR;") 3655bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("import android.view.View;") 366dea555cf42dc3583604699c8c018d22681f56166George Mount val classDeclaration : String 367dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 368dea555cf42dc3583604699c8c018d22681f56166George Mount classDeclaration = "${className} extends ${baseClassName}" 369dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 370dea555cf42dc3583604699c8c018d22681f56166George Mount classDeclaration = "${className} extends android.databinding.ViewDataBinding" 371dea555cf42dc3583604699c8c018d22681f56166George Mount } 372dea555cf42dc3583604699c8c018d22681f56166George Mount nl("public class ${classDeclaration} {") { 3734c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(declareIncludeViews()) 3745bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareViews()) 3755bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareVariables()) 37696e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab(declareConstructor(minSdk)) 3775bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareInvalidateAll()) 3785bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareLog()) 3795bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareSetVariable()) 3805bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(variableSettersAndGetters()) 3815bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(onFieldChange()) 3825bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 3834c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(executePendingBindings()) 3845bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 3855bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareDirtyFlags()) 386dea555cf42dc3583604699c8c018d22681f56166George Mount if (!layoutBinder.hasVariations()) { 387dea555cf42dc3583604699c8c018d22681f56166George Mount tab(declareFactories()) 388dea555cf42dc3583604699c8c018d22681f56166George Mount } 3895bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 3905bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 3915bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(flagMapping()) 3925bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("//end") 3935bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar }.generate() 3945bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 39534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fun calculateIndices() : Unit { 39696e1c821dd446d1ed78f8ae61131550588f60a24George Mount val taggedViews = layoutBinder.getBindingTargets().filter{ 39796e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && it.getTag() != null && !it.isBinder() 39834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 39996e1c821dd446d1ed78f8ae61131550588f60a24George Mount taggedViews.forEach { 40096e1c821dd446d1ed78f8ae61131550588f60a24George Mount indices.put(it, indexFromTag(it.getTag())) 40196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 40296e1c821dd446d1ed78f8ae61131550588f60a24George Mount val indexStart = maxIndex() + 1 40396e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getBindingTargets().filter{ 40496e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !taggedViews.contains(it) 40596e1c821dd446d1ed78f8ae61131550588f60a24George Mount }.withIndex().forEach { 40696e1c821dd446d1ed78f8ae61131550588f60a24George Mount indices.put(it.value, it.index + indexStart) 40734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 40834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 4094c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun declareIncludeViews() = kcode("") { 41096e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("private static final android.databinding.ViewDataBinding.IncludedLayoutIndex[][] sIncludes;") 4114c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("private static final android.util.SparseIntArray sViewsWithIds;") 4124c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("static {") { 4134c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount val hasBinders = layoutBinder.getBindingTargets().firstOrNull{ it.isUsed() && it.isBinder()} != null 4144c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount if (!hasBinders) { 4154c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sIncludes = null;") 41600da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 41796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val numBindings = layoutBinder.getBindingTargets().filter{ it.isUsed() }.count() 41896e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("sIncludes = new android.databinding.ViewDataBinding.IncludedLayoutIndex[${numBindings}][];") 41996e1c821dd446d1ed78f8ae61131550588f60a24George Mount val includeMap = HashMap<BindingTarget, ArrayList<BindingTarget>>() 42096e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getBindingTargets().filter{ it.isUsed() && it.isBinder() }.forEach { 42196e1c821dd446d1ed78f8ae61131550588f60a24George Mount val includeTag = it.getTag(); 42296e1c821dd446d1ed78f8ae61131550588f60a24George Mount val parent = layoutBinder.getBindingTargets().firstOrNull { 42396e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !it.isBinder() && includeTag.equals(it.getTag()) 42496e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 42596e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (parent == null) { 42696e1c821dd446d1ed78f8ae61131550588f60a24George Mount throw IllegalStateException("Could not find parent of include file") 42796e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 42896e1c821dd446d1ed78f8ae61131550588f60a24George Mount var list = includeMap.get(parent) 42996e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (list == null) { 43096e1c821dd446d1ed78f8ae61131550588f60a24George Mount list = ArrayList<BindingTarget>() 43196e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.put(parent, list) 43296e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 43396e1c821dd446d1ed78f8ae61131550588f60a24George Mount list.add(it) 4344c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 43596e1c821dd446d1ed78f8ae61131550588f60a24George Mount 43696e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.keySet().forEach { 43796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val index = indices.get(it) 43896e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("sIncludes[${index}] = new android.databinding.ViewDataBinding.IncludedLayoutIndex[] {") { 43996e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.get(it).forEach { 44096e1c821dd446d1ed78f8ae61131550588f60a24George Mount val bindingIndex = indices.get(it) 44196e1c821dd446d1ed78f8ae61131550588f60a24George Mount val layoutName = it.getIncludedLayout() 44296e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("new android.databinding.ViewDataBinding.IncludedLayoutIndex(\"${layoutName}\", ${bindingIndex}, R.layout.${layoutName}),") 44396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 44496e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 44596e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("};") 44696e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 44796e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 44896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val viewsWithIds = layoutBinder.getBindingTargets().filter { 44996e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !it.isBinder() && (!it.supportsTag() || (it.getId() != null && it.getTag() == null)) 45000da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 45196e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (viewsWithIds.isEmpty()) { 4524c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = null;") 45300da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 4544c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = new android.util.SparseIntArray();") 45596e1c821dd446d1ed78f8ae61131550588f60a24George Mount viewsWithIds.forEach { 45634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("sViewsWithIds.put(${it.androidId}, ${indices.get(it)});") 4574c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 45800da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 4594c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 4604c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("}") 4614c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 46296e1c821dd446d1ed78f8ae61131550588f60a24George Mount 46396e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun maxIndex() : kotlin.Int { 46496e1c821dd446d1ed78f8ae61131550588f60a24George Mount val maxIndex = indices.values().max() 46596e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (maxIndex == null) { 46696e1c821dd446d1ed78f8ae61131550588f60a24George Mount return -1 46796e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 46896e1c821dd446d1ed78f8ae61131550588f60a24George Mount return maxIndex 46996e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 47096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 47196e1c821dd446d1ed78f8ae61131550588f60a24George Mount 47296e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun declareConstructor(minSdk : kotlin.Int) = kcode("") { 47396e1c821dd446d1ed78f8ae61131550588f60a24George Mount val bindingCount = maxIndex() + 1 47496e1c821dd446d1ed78f8ae61131550588f60a24George Mount val parameterType : String 47596e1c821dd446d1ed78f8ae61131550588f60a24George Mount val superParam : String 47696e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (layoutBinder.isMerge()) { 47796e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View[]" 47896e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root[0]" 47996e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 48096e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View" 48196e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root" 48296e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 48396e1c821dd446d1ed78f8ae61131550588f60a24George Mount val rootTagsSupported = minSdk >= 14 484dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 485dea555cf42dc3583604699c8c018d22681f56166George Mount nl("") 48696e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public ${className}(${parameterType} root) {") { 48796e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("this(${superParam}, mapBindings(root, ${bindingCount}, sIncludes, sViewsWithIds));") 488dea555cf42dc3583604699c8c018d22681f56166George Mount } 489dea555cf42dc3583604699c8c018d22681f56166George Mount nl("}") 49096e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("private ${className}(${parameterType} root, Object[] bindings) {") { 49196e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("super(${superParam}, ${model.getObservables().size()}") { 49296e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter { it.getId() != null }.forEach { 493dea555cf42dc3583604699c8c018d22681f56166George Mount tab(", ${fieldConversion(it)}") 49434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 495dea555cf42dc3583604699c8c018d22681f56166George Mount tab(");") 49634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 49734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 498dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 49996e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public ${baseClassName}(${parameterType} root) {") { 50096e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("super(${superParam}, ${model.getObservables().size()});") 50196e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("final Object[] bindings = mapBindings(root, ${bindingCount}, sIncludes, sViewsWithIds);") 502dea555cf42dc3583604699c8c018d22681f56166George Mount } 503dea555cf42dc3583604699c8c018d22681f56166George Mount } 50496e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("setRootTag(root);") 50596e1c821dd446d1ed78f8ae61131550588f60a24George Mount val taggedViews = layoutBinder.getSortedTargets().filter{it.isUsed()} 506dea555cf42dc3583604699c8c018d22681f56166George Mount taggedViews.forEach { 507dea555cf42dc3583604699c8c018d22681f56166George Mount if (!layoutBinder.hasVariations() || it.getId() == null) { 508dea555cf42dc3583604699c8c018d22681f56166George Mount tab("this.${it.fieldName} = ${fieldConversion(it)};") 509dea555cf42dc3583604699c8c018d22681f56166George Mount } 510dea555cf42dc3583604699c8c018d22681f56166George Mount if (!it.isBinder()) { 511de38dd3ef0577d25b2d59863603abe5750d0c231George Mount if (it.getResolvedType() != null && it.getResolvedType().extendsViewStub()) { 512de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("this.${it.fieldName}.setContainingBinding(this);") 513de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 51496e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (it.supportsTag() && it.getTag() != null && 5157ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount (rootTagsSupported || it.getTag().startsWith("binding_"))) { 516dea555cf42dc3583604699c8c018d22681f56166George Mount val originalTag = it.getOriginalTag(); 517dea555cf42dc3583604699c8c018d22681f56166George Mount var tagValue = "null" 518dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag != null) { 519dea555cf42dc3583604699c8c018d22681f56166George Mount tagValue = "\"${originalTag}\"" 520dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@")) { 521dea555cf42dc3583604699c8c018d22681f56166George Mount var packageName = layoutBinder.getModulePackage() 522dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@android:")) { 523dea555cf42dc3583604699c8c018d22681f56166George Mount packageName = "android" 52400da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 525dea555cf42dc3583604699c8c018d22681f56166George Mount val slashIndex = originalTag.indexOf('/') 526dea555cf42dc3583604699c8c018d22681f56166George Mount val resourceId = originalTag.substring(slashIndex + 1) 527dea555cf42dc3583604699c8c018d22681f56166George Mount tagValue = "root.getResources().getString(${packageName}.R.string.${resourceId})" 52800da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 52900da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 530dea555cf42dc3583604699c8c018d22681f56166George Mount tab("this.${it.fieldName}.setTag(${tagValue});") 5317551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 532d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 533d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 534dea555cf42dc3583604699c8c018d22681f56166George Mount tab("invalidateAll();"); 5350fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 536d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 537d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 538dea555cf42dc3583604699c8c018d22681f56166George Mount fun fieldConversion(target : BindingTarget) : String { 539dea555cf42dc3583604699c8c018d22681f56166George Mount if (!target.isUsed()) { 540dea555cf42dc3583604699c8c018d22681f56166George Mount return "null" 541dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 54296e1c821dd446d1ed78f8ae61131550588f60a24George Mount val index = indices.get(target) 543dea555cf42dc3583604699c8c018d22681f56166George Mount if (index == null) { 54496e1c821dd446d1ed78f8ae61131550588f60a24George Mount throw IllegalStateException("Unknown binding target") 545dea555cf42dc3583604699c8c018d22681f56166George Mount } 54696e1c821dd446d1ed78f8ae61131550588f60a24George Mount val variableName = "bindings[${index}]" 547dea555cf42dc3583604699c8c018d22681f56166George Mount return target.superConversion(variableName) 548dea555cf42dc3583604699c8c018d22681f56166George Mount } 549dea555cf42dc3583604699c8c018d22681f56166George Mount } 550dea555cf42dc3583604699c8c018d22681f56166George Mount 551d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareInvalidateAll() = kcode("") { 5527551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("@Override") 5537551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("public void invalidateAll() {") { 554d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val bs = BitSet() 555d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar bs.set(0, model.getInvalidateableFieldLimit()) 556d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val fs = FlagSet(bs, mDirtyFlags.buckets.size()) 557d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in (0..(mDirtyFlags.buckets.size() - 1))) { 558d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${mDirtyFlags.localValue(i)} = ${fs.localValue(i)};") 559d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 5605bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar includedBinders.filter{it.isUsed()}.forEach { binder -> 5617551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar tab("${binder.fieldName}.invalidateAll();") 5627551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 563d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 5640fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 565d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 566d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 567d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareSetVariable() = kcode("") { 5680fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("public boolean setVariable(int variableId, Object variable) {") { 569d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch(variableId) {") { 5705bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 57143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab ("case ${it.getName().br()} :") { 572d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${it.setterName}((${it.getResolvedType().toJavaCode()}) variable);") 573d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 574d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 575d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 576d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 577d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 578d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 579d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 5800fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 581d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 582d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 583d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareLog() = kcode("") { 5840fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private void log(String msg, long i) {") { 585d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("""android.util.Log.d("BINDER", msg + ":" + Long.toHexString(i));""") 5860fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 5870fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 588d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 589d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 590d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun variableSettersAndGetters() = kcode("") { 5915bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar variables.filterNot{it.isUsed()}.forEach { 5925bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("public void ${it.setterName}(${it.getResolvedType().toJavaCode()} ${it.readableUniqueName}) {") { 5935bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("// not used, ignore") 5945bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5955bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 5965bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("") 5975bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("public ${it.getResolvedType().toJavaCode()} ${it.getterName}() {") { 5985bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("return ${it.getDefaultValue()};") 5995bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 6005bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 6015bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 6025bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 60318243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.getUserDefinedType() != null) { 60418243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("public void ${it.setterName}(${it.getResolvedType().toJavaCode()} ${it.readableUniqueName}) {") { 60518243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.isObservable()) { 60618243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("updateRegistration(${it.getId()}, ${it.readableUniqueName});"); 60718243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 60818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("this.${it.fieldName} = ${it.readableUniqueName};") 60918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount // set dirty flags! 61018243f6f1b7527272ef4feccdf4327d80d9f2241George Mount val flagSet = it.invalidateFlagSet 61118243f6f1b7527272ef4feccdf4327d80d9f2241George Mount mDirtyFlags.mapOr(flagSet) { suffix, index -> 61218243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("${mDirtyFlags.getLocalName()}$suffix |= ${flagSet.localValue(index)};") 61318243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 61418243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("super.requestRebind();") 615d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 61618243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 61718243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("") 61818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("public ${it.getResolvedType().toJavaCode()} ${it.getterName}() {") { 61918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("return ${it.fieldName};") 620d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 62118243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 622d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 623d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 624d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 625d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 626d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun onFieldChange() = kcode("") { 62734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("@Override") 62834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {") { 6294c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("switch (localFieldId) {") { 630d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getObservables().forEach { 631d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("case ${it.getId()} :") { 632d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return ${it.onChangeName}((${it.getResolvedType().toJavaCode()}) object, fieldId);") 633d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 634d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 635d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 636d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 637d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 638d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 63934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 64034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 641d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 642d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getObservables().forEach { 64334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("private boolean ${it.onChangeName}(${it.getResolvedType().toJavaCode()} ${it.readableUniqueName}, int fieldId) {") { 644d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch (fieldId) {", { 645d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val accessedFields: List<FieldAccessExpr> = it.getParents().filterIsInstance(javaClass<FieldAccessExpr>()) 646d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar accessedFields.filter { it.canBeInvalidated() } 647d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .groupBy { it.getName() } 648d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 64943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${it.key.br()}:") { 650d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val field = it.value.first() 651d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mDirtyFlags.mapOr(field.invalidateFlagSet) { suffix, index -> 652d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${mDirtyFlags.localValue(index)} |= ${field.invalidateFlagSet.localValue(index)};") 653d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 654d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 655d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 656d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 657d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 65843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${"".br()}:") { 659d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.invalidateFlagSet 660d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 661d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${mDirtyFlags.getLocalName()}$suffix |= ${flagSet.localValue(index)};") 662d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 663d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 664d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 665d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 666d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) 667d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 668d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 669d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 67034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 67134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 672d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 673d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 674d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 675d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareViews() = kcode("// views") { 676dea555cf42dc3583604699c8c018d22681f56166George Mount val oneLayout = !layoutBinder.hasVariations(); 67796e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter {it.isUsed() && (oneLayout || it.getId() == null)}.forEach { 678dea555cf42dc3583604699c8c018d22681f56166George Mount val access : String 679dea555cf42dc3583604699c8c018d22681f56166George Mount if (oneLayout && it.getId() != null) { 680dea555cf42dc3583604699c8c018d22681f56166George Mount access = "public" 681dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 682dea555cf42dc3583604699c8c018d22681f56166George Mount access = "private" 683dea555cf42dc3583604699c8c018d22681f56166George Mount } 684dea555cf42dc3583604699c8c018d22681f56166George Mount nl("${access} final ${it.interfaceType} ${it.fieldName};") 685d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 686d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 687d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 688d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareVariables() = kcode("// variables") { 6895bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 6900fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private ${it.getResolvedType().toJavaCode()} ${it.fieldName};") 691d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 692d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 693d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 694d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareDirtyFlags() = kcode("// dirty flag") { 695d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.ext.localizedFlags.forEach { flag -> 696de38dd3ef0577d25b2d59863603abe5750d0c231George Mount flag.notEmpty { suffix, value -> 6970fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private") 698d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(" ", if(flag.isDynamic()) null else "static final"); 699d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar app(" ", " ${flag.type} ${flag.getLocalName()}$suffix = ${longToBinary(value)};") 700d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 701d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 702d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 703d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 704d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun flagMapping() = kcode("/* flag mapping") { 705d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (model.getFlagMapping() != null) { 706d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val mapping = model.getFlagMapping() 707d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in mapping.indices) { 708d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("flag $i: ${mapping[i]}") 709d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 710d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 711d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nl("flag mapping end*/") 712d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 713d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 7144c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun executePendingBindings() = kcode("") { 7150fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("@Override") 7164c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("public void executePendingBindings() {") { 717d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val tmpDirtyFlags = FlagSet(mDirtyFlags.buckets) 718d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tmpDirtyFlags.setLocalName("dirtyFlags"); 719d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in (0..mDirtyFlags.buckets.size() - 1)) { 720d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${tmpDirtyFlags.type} ${tmpDirtyFlags.localValue(i)} = ${mDirtyFlags.localValue(i)};") 721d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${mDirtyFlags.localValue(i)} = 0;") 722d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 723d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getPendingExpressions().filterNot {it.isVariable()}.forEach { 724d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${it.getResolvedType().toJavaCode()} ${it.localName} = ${it.getDefaultValue()};") 725d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 726d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 727d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar do { 72874f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyar val batch = ExprModel.filterShouldRead(model.getPendingExpressions()).toArrayList() 729d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val mJustRead = arrayListOf<Expr>() 730d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar while (!batch.none()) { 7310fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val readNow = batch.filter { it.shouldReadNow(mJustRead) } 732d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (readNow.isEmpty()) { 733d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar throw IllegalStateException("do not know what I can read. bailing out ${batch.joinToString("\n")}") 734d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 73543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Log.d { "new read now. batch size: ${batch.size()}, readNow size: ${readNow.size()}" } 736d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 737d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar readNow.forEach { 7380fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl(readWithDependants(it, mJustRead, batch, tmpDirtyFlags)) 739d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 740d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar batch.removeAll(mJustRead) 741d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7420fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// batch finished") 743d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } while(model.markBitsRead()) 744d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 745d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // 74696e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter { it.isUsed() } 747d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .flatMap { it.getBindings() } 748d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .groupBy { it.getExpr() } 749d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 750d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.key.dirtyFlagSet 751d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 752d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 753d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }.joinToString(" || ") 754d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) {") { 755d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.value.forEach { binding -> 75697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("// api target ${binding.getMinApi()}") 75734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val fieldName : String 75834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount if (binding.getTarget().getViewClass(). 75934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount equals(binding.getTarget().getInterfaceType())) { 76034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fieldName = "this.${binding.getTarget().fieldName}" 76134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } else { 76234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fieldName = "((${binding.getTarget().getViewClass()}) this.${binding.getTarget().fieldName})" 76334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 76434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val bindingCode = binding.toJavaCode(fieldName, binding.getExpr().toCode().generate()) 76597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar if (binding.getMinApi() > 1) { 7664c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("if(getBuildSdkInt() >= ${binding.getMinApi()}) {") { 76797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("$bindingCode;") 76897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 76997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("}") 77097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } else { 77197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("$bindingCode;") 77297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 773d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 774d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 775d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 776d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7775bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar includedBinders.filter{it.isUsed()}.forEach { binder -> 7784c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("${binder.fieldName}.executePendingBindings();") 7797551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 78096e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{ 781de38dd3ef0577d25b2d59863603abe5750d0c231George Mount it.isUsed() && it.getResolvedType() != null && it.getResolvedType().extendsViewStub() 782de38dd3ef0577d25b2d59863603abe5750d0c231George Mount }.forEach { 783de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("if (${it.fieldName}.getBinding() != null) {") { 784de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("${it.fieldName}.getBinding().executePendingBindings();") 785de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 786de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("}") 787de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 788d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7890fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 790d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 791d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 792d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar fun readWithDependants(expr : Expr, mJustRead : MutableList<Expr>, batch : MutableList<Expr>, 793d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tmpDirtyFlags : FlagSet, inheritedFlags : FlagSet? = null) : KCode = kcode("") { 794d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mJustRead.add(expr) 79543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Log.d { expr.getUniqueKey() } 796d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = expr.shouldReadFlagSet 797d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val needsIfWrapper = inheritedFlags == null || !flagSet.bitsEqual(inheritedFlags) 798d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val ifClause = "if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 79943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 80043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.joinToString(" || ") 801d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar })" 802d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 803d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val readCode = kcode("") { 804d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (!expr.isVariable()) { 805d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // it is not a variable read it. 806d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("// read ${expr.getUniqueKey()}") 807d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // create an if case for all dependencies that might be null 808d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val nullables = expr.getDependencies().filter { 809e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount it.isMandatory() && it.getOther().getResolvedType().isNullable() 81074f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyar }.map { it.getOther() } 811d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (!expr.isEqualityCheck() && nullables.isNotEmpty()) { 812d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab ("if ( ${nullables.map { "${it.localName} != null" }.joinToString(" && ")}) {") { 813d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${expr.localName}").app(" = ", expr.toCode(true)).app(";") 814d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 815d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 816d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } else { 817d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${expr.localName}").app(" = ", expr.toCode(true)).app(";") 818d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8197920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount if (expr.isObservable()) { 820d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("updateRegistration(${expr.getId()}, ${expr.localName});") 821d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8220fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 823d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 8240fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar // if I am the condition for an expression, set its flag 8250fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val conditionals = expr.getDependants().filter { !it.isConditional() 8260fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar && it.getDependant() is TernaryExpr && (it.getDependant() as TernaryExpr).getPred() == expr } 8270fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar .map { it.getDependant() } 8280fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar if (conditionals.isNotEmpty()) { 8290fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// setting conditional flags") 8300fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("if (${expr.localName}) {") { 8310fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar conditionals.forEach { 8320fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val set = it.getRequirementFlagSet(true) 8330fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar mDirtyFlags.mapOr(set) { suffix , index -> 8340fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 835d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 836d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 837d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8380fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("} else {") { 8390fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar conditionals.forEach { 8400fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val set = it.getRequirementFlagSet(false) 8410fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar mDirtyFlags.mapOr(set) { suffix , index -> 8420fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 8430fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 8440fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 8450fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } tab("}") 846d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8470fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar 848d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val chosen = expr.getDependants().filter { 849d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val dependant = it.getDependant() 850d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar batch.contains(dependant) && 851d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar dependant.shouldReadFlagSet.andNot(flagSet).isEmpty() && 852d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar dependant.shouldReadNow(mJustRead) 853d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 854d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (chosen.isNotEmpty()) { 855d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val nextInheritedFlags = if (needsIfWrapper) flagSet else inheritedFlags 856d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar chosen.forEach { 857d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readWithDependants(it.getDependant(), mJustRead, batch, tmpDirtyFlags, nextInheritedFlags)) 858d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 859d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 860d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 861d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar if (needsIfWrapper) { 862d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tab(ifClause) { 863d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar app(" {") 864d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readCode) 865d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 866d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tab("}") 867d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } else { 868d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readCode) 869d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 870d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 87143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 872dea555cf42dc3583604699c8c018d22681f56166George Mount fun declareFactories() = kcode("") { 87396e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (!layoutBinder.isMerge()) { 87496e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public static ${baseClassName} inflate(android.view.ViewGroup root) {") { 87596e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("return bind(android.view.LayoutInflater.from(root.getContext()).inflate(${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, root, true));") 876dea555cf42dc3583604699c8c018d22681f56166George Mount } 87796e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 87896e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public static ${baseClassName} inflate(android.content.Context context) {") { 87996e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("return bind(android.view.LayoutInflater.from(context).inflate(${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, null, false));") 88096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 88196e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 88296e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public static ${baseClassName} bind(android.view.View view) {") { 88396e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("if (!\"${layoutBinder.getTag()}_0\".equals(view.getTag())) {") { 88496e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("throw new RuntimeException(\"view tag isn't correct on view\");") 88596e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 88696e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("}") 88796e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("return new ${baseClassName}(view);") 88896e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 88996e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 890dea555cf42dc3583604699c8c018d22681f56166George Mount } 891dea555cf42dc3583604699c8c018d22681f56166George Mount } 892dea555cf42dc3583604699c8c018d22681f56166George Mount 8934c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount public fun writeBaseClass() : String = 89443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar kcode("package ${layoutBinder.getPackage()};") { 895fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.Bindable;") 896fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.DataBindingUtil;") 897fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.ViewDataBinding;") 8984c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("public abstract class ${baseClassName} extends ViewDataBinding {") 89996e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 900de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("public final ${it.interfaceType} ${it.fieldName};") 90134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 90234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 90334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("protected ${baseClassName}(android.view.View root_, int localFieldCount") { 90496e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 905de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab(", ${it.interfaceType} ${it.readableUniqueName}") 90634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 90734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 90834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab(") {") { 90934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("super(root_, localFieldCount);") 91096e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 91134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("this.${it.fieldName} = ${it.readableUniqueName};") 91234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 9134c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 9144c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 9154c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("") 91643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar variables.forEach { 91718243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.getUserDefinedType() != null) { 918895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar //it.getExpandedUserDefinedType(ModelAnalyzer.getInstance()); 919895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar val type = ModelAnalyzer.getInstance().applyImports(it.getUserDefinedType(), model.getImports()) 9204c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public abstract void ${it.setterName}(${type} ${it.readableUniqueName});") 92118243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 92243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 9234c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public static ${baseClassName} inflate(android.view.ViewGroup root) {") { 924a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar tab("return DataBindingUtil.<${baseClassName}>inflate(root.getContext(), ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, root, true);") 92543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 9264c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 9274c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public static ${baseClassName} inflate(android.content.Context context) {") { 928a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar tab("return DataBindingUtil.<${baseClassName}>inflate(context, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, null, false);") 9294c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 9304c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 9314c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public static ${baseClassName} bind(android.view.View view) {") { 932a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar tab("return (${baseClassName})DataBindingUtil.bindTo(view, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()});") 9334c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 9344c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 93543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar nl("}") 93643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.generate() 937dea555cf42dc3583604699c8c018d22681f56166George Mount} 938