LayoutBinderWriter.kt revision c6bcb7bf9cab139b3141c4644e5b3267deed5213
1d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar/* 2d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Copyright (C) 2015 The Android Open Source Project 3d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 4d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * you may not use this file except in compliance with the License. 5d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * You may obtain a copy of the License at 6d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 7d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Unless required by applicable law or agreed to in writing, software 8d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 9d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * See the License for the specific language governing permissions and 11d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * limitations under the License. 12d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar */ 13d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 14fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.tool.writer 15d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 16fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.LayoutBinder 17fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.Expr 18d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport kotlin.properties.Delegates 19fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.ext.joinToCamelCaseAsVar 20fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.BindingTarget 21fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.IdentifierExpr 22fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.util.Log 23d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.BitSet 24fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ExprModel 25d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.Arrays 26c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mountimport android.databinding.tool.expr.BitShiftExpr 27fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.TernaryExpr 28fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.FieldAccessExpr 29fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ComparisonExpr 30fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.GroupExpr 31c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mountimport android.databinding.tool.expr.InstanceOfExpr 32fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.MathExpr 33fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.MethodCallExpr 34fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.StaticIdentifierExpr 35fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.SymbolExpr 36c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mountimport android.databinding.tool.expr.UnaryExpr 37fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.ext.androidId 38fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.ext.lazy 39fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.ext.br 40fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ResourceExpr 41fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.BracketExpr 42fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.Callable 43fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.CastExpr 44fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelAnalyzer 4596e1c821dd446d1ed78f8ae61131550588f60a24George Mountimport java.util.ArrayList 4634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport java.util.HashMap 4743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 48d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun String.stripNonJava() = this.split("[^a-zA-Z0-9]").map{ it.trim() }.joinToCamelCaseAsVar() 49d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 50d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarclass ExprModelExt { 51d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val usedFieldNames = hashSetOf<String>() 52d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val localizedFlags = arrayListOf<FlagSet>() 53d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 54d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun localizeFlag(set : FlagSet, name:String) : FlagSet { 55d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar localizedFlags.add(set) 56d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val result = getUniqueFieldName(name) 57d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar set.setLocalName(result) 58d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return set 59d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 60d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 61d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun getUniqueFieldName(base : String) : String { 62d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var candidate = base 63d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var i = 0 64d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar while (usedFieldNames.contains(candidate)) { 65d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar i ++ 66d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar candidate = base + i 67d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 68d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar usedFieldNames.add(candidate) 69d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return candidate 70d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 71d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 72d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 73de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval ExprModel.ext by Delegates.lazy { target : ExprModel -> 74d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar ExprModelExt() 75d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 76d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 77d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun ExprModel.getUniqueFieldName(base : String) : String = ext.getUniqueFieldName(base) 78d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 79d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun ExprModel.localizeFlag(set : FlagSet, base : String) : FlagSet = ext.localizeFlag(set, base) 80d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 81de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.readableUniqueName by Delegates.lazy { target: BindingTarget -> 8200da715547ee7d5d38a3b8576090ca427a94daa5George Mount val variableName : String 8300da715547ee7d5d38a3b8576090ca427a94daa5George Mount if (target.getId() == null) { 8496e1c821dd446d1ed78f8ae61131550588f60a24George Mount variableName = "boundView" + indexFromTag(target.getTag()) 8500da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 8600da715547ee7d5d38a3b8576090ca427a94daa5George Mount variableName = target.getId().androidId().stripNonJava() 8700da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 8800da715547ee7d5d38a3b8576090ca427a94daa5George Mount target.getModel().ext.getUniqueFieldName(variableName) 89d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 907551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 91de38dd3ef0577d25b2d59863603abe5750d0c231George Mountfun BindingTarget.superConversion(variable : String) : String { 9296e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (getResolvedType() != null && getResolvedType().extendsViewStub()) { 93de38dd3ef0577d25b2d59863603abe5750d0c231George Mount return "new android.databinding.ViewStubProxy((android.view.ViewStub) ${variable})" 94de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } else { 95de38dd3ef0577d25b2d59863603abe5750d0c231George Mount return "(${interfaceType}) ${variable}" 96de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 97de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 98de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 99de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.fieldName by Delegates.lazy { target : BindingTarget -> 10034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount if (target.getFieldName() == null) { 10134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount if (target.getId() == null) { 10234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount target.setFieldName("m${target.readableUniqueName.capitalize()}") 10334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } else { 10434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount target.androidId.stripNonJava(); 10534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount target.setFieldName(target.readableUniqueName); 10634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 10734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 10834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount target.getFieldName(); 109d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 110d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 111de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.getterName by Delegates.lazy { target : BindingTarget -> 112d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "get${target.readableUniqueName.capitalize()}" 113d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 114d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 115de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.androidId by Delegates.lazy { target : BindingTarget -> 11643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar "R.id.${target.getId().androidId()}" 117d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 118d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 119de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval BindingTarget.interfaceType by Delegates.lazy { target : BindingTarget -> 120de38dd3ef0577d25b2d59863603abe5750d0c231George Mount if (target.getResolvedType() != null && target.getResolvedType().extendsViewStub()) { 121de38dd3ef0577d25b2d59863603abe5750d0c231George Mount "android.databinding.ViewStubProxy" 122de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } else { 123de38dd3ef0577d25b2d59863603abe5750d0c231George Mount target.getInterfaceType() 124de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 125de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 126de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 127de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.readableUniqueName by Delegates.lazy { expr : Expr -> 12843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Log.d { "readableUniqueName for ${expr.getUniqueKey()}" } 129d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val stripped = "${expr.getUniqueKey().stripNonJava()}" 130d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar expr.getModel().ext.getUniqueFieldName(stripped) 131d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 132d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 133de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.readableName by Delegates.lazy { expr : Expr -> 134de38dd3ef0577d25b2d59863603abe5750d0c231George Mount Log.d { "readableUniqueName for ${expr.getUniqueKey()}" } 135de38dd3ef0577d25b2d59863603abe5750d0c231George Mount "${expr.getUniqueKey().stripNonJava()}" 136de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 137de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 138de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.fieldName by Delegates.lazy { expr : Expr -> 139de38dd3ef0577d25b2d59863603abe5750d0c231George Mount "m${expr.readableName.capitalize()}" 140d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 141d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 142de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.hasFlag by Delegates.lazy { expr : Expr -> 143d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar expr.getId() < expr.getModel().getInvalidateableFieldLimit() 144d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 145d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 146de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.localName by Delegates.lazy { expr : Expr -> 147d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if(expr.isVariable()) expr.fieldName else "${expr.readableUniqueName}" 148d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 149d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 150de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.setterName by Delegates.lazy { expr : Expr -> 151de38dd3ef0577d25b2d59863603abe5750d0c231George Mount "set${expr.readableName.capitalize()}" 152d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 153d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 154de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.onChangeName by Delegates.lazy { expr : Expr -> 155d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "onChange${expr.readableUniqueName.capitalize()}" 156d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 157d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 158de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.getterName by Delegates.lazy { expr : Expr -> 159de38dd3ef0577d25b2d59863603abe5750d0c231George Mount "get${expr.readableName.capitalize()}" 160d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 161d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 162de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.dirtyFlagName by Delegates.lazy { expr : Expr -> 163d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "sFlag${expr.readableUniqueName.capitalize()}" 164d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 165d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 166de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.shouldReadFlagName by Delegates.lazy { expr : Expr -> 167d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "sFlagRead${expr.readableUniqueName.capitalize()}" 168d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 169d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 170de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.invalidateFlagName by Delegates.lazy { expr : Expr -> 171d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "sFlag${expr.readableUniqueName.capitalize()}Invalid" 172d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 173d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 174de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.conditionalFlagPrefix by Delegates.lazy { expr : Expr -> 175d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "sFlag${expr.readableUniqueName.capitalize()}Is" 176d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 177d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 178d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 179d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.toCode(full : Boolean = false) : KCode { 180d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val it = this 181d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (isDynamic() && !full) { 182d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return kcode(localName) 183d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 184d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return when (it) { 185d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is ComparisonExpr -> kcode("") { 186d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getLeft().toCode()) 187d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(it.getOp()) 188d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getRight().toCode()) 189d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 190c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount is InstanceOfExpr -> kcode("") { 191c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount app("", it.getExpr().toCode()) 192c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount app(" instanceof ") 193c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount app("", it.getType().toJavaCode()) 194c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount } 195d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is FieldAccessExpr -> kcode("") { 196a70fed6415aa1e8bbbe929aee776402ac3b81c86George Mount app("", it.getChild().toCode()) 197e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount if (it.getGetter().type == Callable.Type.FIELD) { 198d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(".", it.getGetter().name) 199d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } else { 200d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(".", it.getGetter().name).app("()") 201d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 202d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 203d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is GroupExpr -> kcode("(").app("", it.getWrapped().toCode()).app(")") 204d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is StaticIdentifierExpr -> kcode(it.getResolvedType().toJavaCode()) 205d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is IdentifierExpr -> kcode(it.localName) 206d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is MathExpr -> kcode("") { 207d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getLeft().toCode()) 208d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(it.getOp()) 209d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getRight().toCode()) 210d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 211c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount is UnaryExpr -> kcode("") { 212c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount app(it.getOp(), it.getExpr().toCode()) 213c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount } 214c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount is BitShiftExpr -> kcode("") { 215c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount app("", it.getLeft().toCode()) 216c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount app(it.getOp()) 217c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount app("", it.getRight().toCode()) 218c6bcb7bf9cab139b3141c4644e5b3267deed5213George Mount } 219d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is MethodCallExpr -> kcode("") { 220d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getTarget().toCode()) 221d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(".", it.getGetter().name) 222d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("(") 223d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var first = true 224d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.getArgs().forEach { 225d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar apps(if (first) "" else ",", it.toCode()) 226d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar first = false 227d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 228d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(")") 229d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 230d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is SymbolExpr -> kcode(it.getText()) // TODO 231d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is TernaryExpr -> kcode("") { 232d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getPred().toCode()) 233d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("?", it.getIfTrue().toCode()) 234d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(":", it.getIfFalse().toCode()) 235d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 236c752a5f795baf6df435ef60881316cb748df407cGeorge Mount is ResourceExpr -> kcode("") { 237c752a5f795baf6df435ef60881316cb748df407cGeorge Mount app("", it.toJava()) 238c752a5f795baf6df435ef60881316cb748df407cGeorge Mount } 2395cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount is BracketExpr -> kcode("") { 2405cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("", it.getTarget().toCode()) 2415cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount val bracketType = it.getAccessor(); 2425cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount when (bracketType) { 2435cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount BracketExpr.BracketAccessor.ARRAY -> { 2445cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("[", it.getArg().toCode()) 2455cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("]") 2465cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2475cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount BracketExpr.BracketAccessor.LIST -> { 2485cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(".get(") 2495cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount if (it.argCastsInteger()) { 2505cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("(Integer)") 2515cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2525cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("", it.getArg().toCode()) 2535cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(")") 2545cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2555cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount BracketExpr.BracketAccessor.MAP -> { 2565cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(".get(", it.getArg().toCode()) 2575cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(")") 2585cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2595cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2605cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 261e4b93061ac703e48fc2c9994c9059ed016f05559George Mount is CastExpr -> kcode("") { 262e4b93061ac703e48fc2c9994c9059ed016f05559George Mount app("(", it.getCastType()) 263e4b93061ac703e48fc2c9994c9059ed016f05559George Mount app(") ", it.getCastExpr().toCode()) 264e4b93061ac703e48fc2c9994c9059ed016f05559George Mount } 265d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar else -> kcode("//NOT IMPLEMENTED YET") 266d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 267d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 268d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 269d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 270d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.isVariable() = this is IdentifierExpr && this.isDynamic() 271d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 272d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.conditionalFlagName(output : Boolean, suffix : String) = "${dirtyFlagName}_${output}$suffix" 273d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 274d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 275de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.dirtyFlagSet by Delegates.lazy { expr : Expr -> 276d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getInvalidFlags(), expr.getModel().getFlagBucketCount()) 277d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 278d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 279de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.invalidateFlagSet by Delegates.lazy { expr : Expr -> 280d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getId()) 281d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 282d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 283de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.shouldReadFlagSet by Delegates.lazy { expr : Expr -> 284d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getShouldReadFlags(), expr.getModel().getFlagBucketCount()) 285d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 286d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 287de38dd3ef0577d25b2d59863603abe5750d0c231George Mountval Expr.conditionalFlags by Delegates.lazy { expr : Expr -> 288d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar arrayListOf(FlagSet(expr.getRequirementFlagIndex(false)), 289d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getRequirementFlagIndex(true))) 290d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 291d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 292d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.getRequirementFlagSet(expected : Boolean) : FlagSet = conditionalFlags[if(expected) 1 else 0] 293d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 294d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.notEmpty(cb : (suffix : String, value : Long) -> Unit) { 295d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar buckets.withIndex().forEach { 296d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (it.value != 0L) { 297d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar cb(getWordSuffix(it.index), buckets[it.index]) 298d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 299d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 300d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 301d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 302d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.getBitSuffix(bitIndex : Int) : String { 303d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val word = bitIndex / FlagSet.sBucketSize 304d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return getWordSuffix(word) 305d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 306d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 307d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.getWordSuffix(wordIndex : Int) : String { 308d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return if(wordIndex == 0) "" else "_${wordIndex}" 309d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 310d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 311d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.localValue(bucketIndex : Int) = 312d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar if (getLocalName() == null) binaryCode(bucketIndex) 313d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar else "${getLocalName()}${getWordSuffix(bucketIndex)}" 314d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 315d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyarfun FlagSet.binaryCode(bucketIndex : Int) = longToBinary(buckets[bucketIndex]) 316d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 317d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 318d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyarfun longToBinary(l : Long) = 319d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar "0b${java.lang.Long.toBinaryString(l)}L" 320d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 321d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun <T> FlagSet.mapOr(other : FlagSet, cb : (suffix : String, index : Int) -> T) : List<T> { 322d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val min = Math.min(buckets.size(), other.buckets.size()) 323d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val result = arrayListOf<T>() 324d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in 0..(min - 1)) { 325d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // if these two can match by any chance, call the callback 326d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (intersect(other, i)) { 327d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar result.add(cb(getWordSuffix(i), i)) 328d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 329d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 330d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return result 331d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 332d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 33396e1c821dd446d1ed78f8ae61131550588f60a24George Mountfun indexFromTag(tag : String) : kotlin.Int { 33496e1c821dd446d1ed78f8ae61131550588f60a24George Mount val startIndex : kotlin.Int 3357ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount if (tag.startsWith("binding_")) { 3367ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount startIndex = "binding_".length(); 33796e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 33896e1c821dd446d1ed78f8ae61131550588f60a24George Mount startIndex = tag.lastIndexOf('_') + 1 33996e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 34096e1c821dd446d1ed78f8ae61131550588f60a24George Mount return Integer.parseInt(tag.substring(startIndex)) 34196e1c821dd446d1ed78f8ae61131550588f60a24George Mount} 34296e1c821dd446d1ed78f8ae61131550588f60a24George Mount 34343596c2b2997e40b709627419732100d78a62ff0Yigit Boyarclass LayoutBinderWriter(val layoutBinder : LayoutBinder) { 344d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val model = layoutBinder.getModel() 34534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val indices = HashMap<BindingTarget, kotlin.Int>() 34643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val mDirtyFlags by Delegates.lazy { 34743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val fs = FlagSet(BitSet(), model.getFlagBucketCount()); 34843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Arrays.fill(fs.buckets, -1) 34943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs.setDynamic(true) 35043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.localizeFlag(fs, "mDirtyFlags") 35143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs 352d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 353d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 35443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val dynamics by Delegates.lazy { model.getExprMap().values().filter { it.isDynamic() } } 355dea555cf42dc3583604699c8c018d22681f56166George Mount val className = layoutBinder.getImplementationName() 356d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 35743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val identifiers by Delegates.lazy { 35843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar dynamics.filter { it is IdentifierExpr } 35943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 360d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 361dea555cf42dc3583604699c8c018d22681f56166George Mount val baseClassName = "${layoutBinder.getClassName()}" 362d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 3637551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar val includedBinders by Delegates.lazy { 3647551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar layoutBinder.getBindingTargets().filter { it.isBinder() } 3657551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 3667551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 36743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val variables by Delegates.lazy { 36843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.getExprMap().values().filterIsInstance(javaClass<IdentifierExpr>()).filter { it.isVariable() } 36943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 370d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 3715bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar val usedVariables by Delegates.lazy { 3725bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar variables.filter {it.isUsed()} 3735bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 374d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 37596e1c821dd446d1ed78f8ae61131550588f60a24George Mount public fun write(minSdk : kotlin.Int) : String { 3765bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar layoutBinder.resolveWhichExpressionsAreUsed() 37734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount calculateIndices(); 3785bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar return kcode("package ${layoutBinder.getPackage()};") { 379a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar nl("import ${layoutBinder.getModulePackage()}.R;") 380a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar nl("import ${layoutBinder.getModulePackage()}.BR;") 3815bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("import android.view.View;") 382dea555cf42dc3583604699c8c018d22681f56166George Mount val classDeclaration : String 383dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 384dea555cf42dc3583604699c8c018d22681f56166George Mount classDeclaration = "${className} extends ${baseClassName}" 385dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 386dea555cf42dc3583604699c8c018d22681f56166George Mount classDeclaration = "${className} extends android.databinding.ViewDataBinding" 387dea555cf42dc3583604699c8c018d22681f56166George Mount } 388dea555cf42dc3583604699c8c018d22681f56166George Mount nl("public class ${classDeclaration} {") { 3894c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(declareIncludeViews()) 3905bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareViews()) 3915bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareVariables()) 39296e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab(declareConstructor(minSdk)) 3935bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareInvalidateAll()) 3945bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareLog()) 3955bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareSetVariable()) 3965bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(variableSettersAndGetters()) 3975bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(onFieldChange()) 3985bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 3994c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(executePendingBindings()) 4005bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 4015bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareDirtyFlags()) 402dea555cf42dc3583604699c8c018d22681f56166George Mount if (!layoutBinder.hasVariations()) { 403dea555cf42dc3583604699c8c018d22681f56166George Mount tab(declareFactories()) 404dea555cf42dc3583604699c8c018d22681f56166George Mount } 4055bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 4065bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 4075bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(flagMapping()) 4085bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("//end") 4095bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar }.generate() 4105bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 41134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fun calculateIndices() : Unit { 41296e1c821dd446d1ed78f8ae61131550588f60a24George Mount val taggedViews = layoutBinder.getBindingTargets().filter{ 41396e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && it.getTag() != null && !it.isBinder() 41434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 41596e1c821dd446d1ed78f8ae61131550588f60a24George Mount taggedViews.forEach { 41696e1c821dd446d1ed78f8ae61131550588f60a24George Mount indices.put(it, indexFromTag(it.getTag())) 41796e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 41896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val indexStart = maxIndex() + 1 41996e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getBindingTargets().filter{ 42096e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !taggedViews.contains(it) 42196e1c821dd446d1ed78f8ae61131550588f60a24George Mount }.withIndex().forEach { 42296e1c821dd446d1ed78f8ae61131550588f60a24George Mount indices.put(it.value, it.index + indexStart) 42334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 42434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 4254c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun declareIncludeViews() = kcode("") { 42696e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("private static final android.databinding.ViewDataBinding.IncludedLayoutIndex[][] sIncludes;") 4274c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("private static final android.util.SparseIntArray sViewsWithIds;") 4284c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("static {") { 4294c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount val hasBinders = layoutBinder.getBindingTargets().firstOrNull{ it.isUsed() && it.isBinder()} != null 4304c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount if (!hasBinders) { 4314c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sIncludes = null;") 43200da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 43396e1c821dd446d1ed78f8ae61131550588f60a24George Mount val numBindings = layoutBinder.getBindingTargets().filter{ it.isUsed() }.count() 43496e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("sIncludes = new android.databinding.ViewDataBinding.IncludedLayoutIndex[${numBindings}][];") 43596e1c821dd446d1ed78f8ae61131550588f60a24George Mount val includeMap = HashMap<BindingTarget, ArrayList<BindingTarget>>() 43696e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getBindingTargets().filter{ it.isUsed() && it.isBinder() }.forEach { 43796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val includeTag = it.getTag(); 43896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val parent = layoutBinder.getBindingTargets().firstOrNull { 43996e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !it.isBinder() && includeTag.equals(it.getTag()) 44096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 44196e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (parent == null) { 44296e1c821dd446d1ed78f8ae61131550588f60a24George Mount throw IllegalStateException("Could not find parent of include file") 44396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 44496e1c821dd446d1ed78f8ae61131550588f60a24George Mount var list = includeMap.get(parent) 44596e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (list == null) { 44696e1c821dd446d1ed78f8ae61131550588f60a24George Mount list = ArrayList<BindingTarget>() 44796e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.put(parent, list) 44896e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 44996e1c821dd446d1ed78f8ae61131550588f60a24George Mount list.add(it) 4504c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 45196e1c821dd446d1ed78f8ae61131550588f60a24George Mount 45296e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.keySet().forEach { 45396e1c821dd446d1ed78f8ae61131550588f60a24George Mount val index = indices.get(it) 45496e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("sIncludes[${index}] = new android.databinding.ViewDataBinding.IncludedLayoutIndex[] {") { 45596e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.get(it).forEach { 45696e1c821dd446d1ed78f8ae61131550588f60a24George Mount val bindingIndex = indices.get(it) 45796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val layoutName = it.getIncludedLayout() 45896e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("new android.databinding.ViewDataBinding.IncludedLayoutIndex(\"${layoutName}\", ${bindingIndex}, R.layout.${layoutName}),") 45996e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 46096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 46196e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("};") 46296e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 46396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 46496e1c821dd446d1ed78f8ae61131550588f60a24George Mount val viewsWithIds = layoutBinder.getBindingTargets().filter { 46596e1c821dd446d1ed78f8ae61131550588f60a24George Mount it.isUsed() && !it.isBinder() && (!it.supportsTag() || (it.getId() != null && it.getTag() == null)) 46600da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 46796e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (viewsWithIds.isEmpty()) { 4684c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = null;") 46900da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 4704c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = new android.util.SparseIntArray();") 47196e1c821dd446d1ed78f8ae61131550588f60a24George Mount viewsWithIds.forEach { 47234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("sViewsWithIds.put(${it.androidId}, ${indices.get(it)});") 4734c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 47400da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 4754c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 4764c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("}") 4774c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 47896e1c821dd446d1ed78f8ae61131550588f60a24George Mount 47996e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun maxIndex() : kotlin.Int { 48096e1c821dd446d1ed78f8ae61131550588f60a24George Mount val maxIndex = indices.values().max() 48196e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (maxIndex == null) { 48296e1c821dd446d1ed78f8ae61131550588f60a24George Mount return -1 48396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 48496e1c821dd446d1ed78f8ae61131550588f60a24George Mount return maxIndex 48596e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 48696e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 48796e1c821dd446d1ed78f8ae61131550588f60a24George Mount 48896e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun declareConstructor(minSdk : kotlin.Int) = kcode("") { 48996e1c821dd446d1ed78f8ae61131550588f60a24George Mount val bindingCount = maxIndex() + 1 49096e1c821dd446d1ed78f8ae61131550588f60a24George Mount val parameterType : String 49196e1c821dd446d1ed78f8ae61131550588f60a24George Mount val superParam : String 49296e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (layoutBinder.isMerge()) { 49396e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View[]" 49496e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root[0]" 49596e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 49696e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View" 49796e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root" 49896e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 49996e1c821dd446d1ed78f8ae61131550588f60a24George Mount val rootTagsSupported = minSdk >= 14 500dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 501dea555cf42dc3583604699c8c018d22681f56166George Mount nl("") 50296e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public ${className}(${parameterType} root) {") { 50396e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("this(${superParam}, mapBindings(root, ${bindingCount}, sIncludes, sViewsWithIds));") 504dea555cf42dc3583604699c8c018d22681f56166George Mount } 505dea555cf42dc3583604699c8c018d22681f56166George Mount nl("}") 50696e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("private ${className}(${parameterType} root, Object[] bindings) {") { 50796e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("super(${superParam}, ${model.getObservables().size()}") { 50896e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter { it.getId() != null }.forEach { 509dea555cf42dc3583604699c8c018d22681f56166George Mount tab(", ${fieldConversion(it)}") 51034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 511dea555cf42dc3583604699c8c018d22681f56166George Mount tab(");") 51234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 51334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 514dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 51596e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public ${baseClassName}(${parameterType} root) {") { 51696e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("super(${superParam}, ${model.getObservables().size()});") 51796e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("final Object[] bindings = mapBindings(root, ${bindingCount}, sIncludes, sViewsWithIds);") 518dea555cf42dc3583604699c8c018d22681f56166George Mount } 519dea555cf42dc3583604699c8c018d22681f56166George Mount } 52096e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("setRootTag(root);") 52196e1c821dd446d1ed78f8ae61131550588f60a24George Mount val taggedViews = layoutBinder.getSortedTargets().filter{it.isUsed()} 522dea555cf42dc3583604699c8c018d22681f56166George Mount taggedViews.forEach { 523dea555cf42dc3583604699c8c018d22681f56166George Mount if (!layoutBinder.hasVariations() || it.getId() == null) { 524dea555cf42dc3583604699c8c018d22681f56166George Mount tab("this.${it.fieldName} = ${fieldConversion(it)};") 525dea555cf42dc3583604699c8c018d22681f56166George Mount } 526dea555cf42dc3583604699c8c018d22681f56166George Mount if (!it.isBinder()) { 527de38dd3ef0577d25b2d59863603abe5750d0c231George Mount if (it.getResolvedType() != null && it.getResolvedType().extendsViewStub()) { 528de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("this.${it.fieldName}.setContainingBinding(this);") 529de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 53096e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (it.supportsTag() && it.getTag() != null && 5317ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount (rootTagsSupported || it.getTag().startsWith("binding_"))) { 532dea555cf42dc3583604699c8c018d22681f56166George Mount val originalTag = it.getOriginalTag(); 533dea555cf42dc3583604699c8c018d22681f56166George Mount var tagValue = "null" 534dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag != null) { 535dea555cf42dc3583604699c8c018d22681f56166George Mount tagValue = "\"${originalTag}\"" 536dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@")) { 537dea555cf42dc3583604699c8c018d22681f56166George Mount var packageName = layoutBinder.getModulePackage() 538dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@android:")) { 539dea555cf42dc3583604699c8c018d22681f56166George Mount packageName = "android" 54000da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 541dea555cf42dc3583604699c8c018d22681f56166George Mount val slashIndex = originalTag.indexOf('/') 542dea555cf42dc3583604699c8c018d22681f56166George Mount val resourceId = originalTag.substring(slashIndex + 1) 543dea555cf42dc3583604699c8c018d22681f56166George Mount tagValue = "root.getResources().getString(${packageName}.R.string.${resourceId})" 54400da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 54500da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 546dea555cf42dc3583604699c8c018d22681f56166George Mount tab("this.${it.fieldName}.setTag(${tagValue});") 5477551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 548d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 549d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 550dea555cf42dc3583604699c8c018d22681f56166George Mount tab("invalidateAll();"); 5510fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 552d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 553d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 554dea555cf42dc3583604699c8c018d22681f56166George Mount fun fieldConversion(target : BindingTarget) : String { 555dea555cf42dc3583604699c8c018d22681f56166George Mount if (!target.isUsed()) { 556dea555cf42dc3583604699c8c018d22681f56166George Mount return "null" 557dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 55896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val index = indices.get(target) 559dea555cf42dc3583604699c8c018d22681f56166George Mount if (index == null) { 56096e1c821dd446d1ed78f8ae61131550588f60a24George Mount throw IllegalStateException("Unknown binding target") 561dea555cf42dc3583604699c8c018d22681f56166George Mount } 56296e1c821dd446d1ed78f8ae61131550588f60a24George Mount val variableName = "bindings[${index}]" 563dea555cf42dc3583604699c8c018d22681f56166George Mount return target.superConversion(variableName) 564dea555cf42dc3583604699c8c018d22681f56166George Mount } 565dea555cf42dc3583604699c8c018d22681f56166George Mount } 566dea555cf42dc3583604699c8c018d22681f56166George Mount 567d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareInvalidateAll() = kcode("") { 5687551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("@Override") 5697551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("public void invalidateAll() {") { 570d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val bs = BitSet() 571d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar bs.set(0, model.getInvalidateableFieldLimit()) 572d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val fs = FlagSet(bs, mDirtyFlags.buckets.size()) 573d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in (0..(mDirtyFlags.buckets.size() - 1))) { 574d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${mDirtyFlags.localValue(i)} = ${fs.localValue(i)};") 575d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 5765bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar includedBinders.filter{it.isUsed()}.forEach { binder -> 5777551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar tab("${binder.fieldName}.invalidateAll();") 5787551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 579d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 5800fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 581d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 582d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 583d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareSetVariable() = kcode("") { 5840fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("public boolean setVariable(int variableId, Object variable) {") { 585d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch(variableId) {") { 5865bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 58743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab ("case ${it.getName().br()} :") { 588d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${it.setterName}((${it.getResolvedType().toJavaCode()}) variable);") 589d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 590d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 591d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 592d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 593d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 594d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 595d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 5960fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 597d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 598d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 599d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareLog() = kcode("") { 6000fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private void log(String msg, long i) {") { 601d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("""android.util.Log.d("BINDER", msg + ":" + Long.toHexString(i));""") 6020fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 6030fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 604d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 605d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 606d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun variableSettersAndGetters() = kcode("") { 6075bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar variables.filterNot{it.isUsed()}.forEach { 6085bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("public void ${it.setterName}(${it.getResolvedType().toJavaCode()} ${it.readableUniqueName}) {") { 6095bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("// not used, ignore") 6105bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 6115bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 6125bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("") 6135bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("public ${it.getResolvedType().toJavaCode()} ${it.getterName}() {") { 6145bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("return ${it.getDefaultValue()};") 6155bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 6165bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 6175bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 6185bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 61918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.getUserDefinedType() != null) { 62018243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("public void ${it.setterName}(${it.getResolvedType().toJavaCode()} ${it.readableUniqueName}) {") { 62118243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.isObservable()) { 62218243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("updateRegistration(${it.getId()}, ${it.readableUniqueName});"); 62318243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 62418243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("this.${it.fieldName} = ${it.readableUniqueName};") 62518243f6f1b7527272ef4feccdf4327d80d9f2241George Mount // set dirty flags! 62618243f6f1b7527272ef4feccdf4327d80d9f2241George Mount val flagSet = it.invalidateFlagSet 62718243f6f1b7527272ef4feccdf4327d80d9f2241George Mount mDirtyFlags.mapOr(flagSet) { suffix, index -> 62818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("${mDirtyFlags.getLocalName()}$suffix |= ${flagSet.localValue(index)};") 62918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 63018243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("super.requestRebind();") 631d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 63218243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 63318243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("") 63418243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("public ${it.getResolvedType().toJavaCode()} ${it.getterName}() {") { 63518243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("return ${it.fieldName};") 636d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 63718243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 638d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 639d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 640d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 641d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 642d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun onFieldChange() = kcode("") { 64334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("@Override") 64434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {") { 6454c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("switch (localFieldId) {") { 646d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getObservables().forEach { 647d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("case ${it.getId()} :") { 648d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return ${it.onChangeName}((${it.getResolvedType().toJavaCode()}) object, fieldId);") 649d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 650d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 651d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 652d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 653d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 654d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 65534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 65634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 657d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 658d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getObservables().forEach { 65934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("private boolean ${it.onChangeName}(${it.getResolvedType().toJavaCode()} ${it.readableUniqueName}, int fieldId) {") { 660d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch (fieldId) {", { 661d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val accessedFields: List<FieldAccessExpr> = it.getParents().filterIsInstance(javaClass<FieldAccessExpr>()) 662d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar accessedFields.filter { it.canBeInvalidated() } 663d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .groupBy { it.getName() } 664d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 66543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${it.key.br()}:") { 666d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val field = it.value.first() 667d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mDirtyFlags.mapOr(field.invalidateFlagSet) { suffix, index -> 668d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${mDirtyFlags.localValue(index)} |= ${field.invalidateFlagSet.localValue(index)};") 669d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 670d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 671d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 672d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 673d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 67443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${"".br()}:") { 675d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.invalidateFlagSet 676d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 677d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${mDirtyFlags.getLocalName()}$suffix |= ${flagSet.localValue(index)};") 678d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 679d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 680d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 681d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 682d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) 683d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 684d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 685d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 68634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 68734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 688d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 689d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 690d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 691d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareViews() = kcode("// views") { 692dea555cf42dc3583604699c8c018d22681f56166George Mount val oneLayout = !layoutBinder.hasVariations(); 69396e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter {it.isUsed() && (oneLayout || it.getId() == null)}.forEach { 694dea555cf42dc3583604699c8c018d22681f56166George Mount val access : String 695dea555cf42dc3583604699c8c018d22681f56166George Mount if (oneLayout && it.getId() != null) { 696dea555cf42dc3583604699c8c018d22681f56166George Mount access = "public" 697dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 698dea555cf42dc3583604699c8c018d22681f56166George Mount access = "private" 699dea555cf42dc3583604699c8c018d22681f56166George Mount } 700dea555cf42dc3583604699c8c018d22681f56166George Mount nl("${access} final ${it.interfaceType} ${it.fieldName};") 701d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 702d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 703d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 704d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareVariables() = kcode("// variables") { 7055bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 7060fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private ${it.getResolvedType().toJavaCode()} ${it.fieldName};") 707d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 708d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 709d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 710d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareDirtyFlags() = kcode("// dirty flag") { 711d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.ext.localizedFlags.forEach { flag -> 712de38dd3ef0577d25b2d59863603abe5750d0c231George Mount flag.notEmpty { suffix, value -> 7130fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private") 714d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(" ", if(flag.isDynamic()) null else "static final"); 715d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar app(" ", " ${flag.type} ${flag.getLocalName()}$suffix = ${longToBinary(value)};") 716d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 717d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 718d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 719d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 720d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun flagMapping() = kcode("/* flag mapping") { 721d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (model.getFlagMapping() != null) { 722d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val mapping = model.getFlagMapping() 723d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in mapping.indices) { 724d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("flag $i: ${mapping[i]}") 725d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 726d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 727d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nl("flag mapping end*/") 728d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 729d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 7304c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun executePendingBindings() = kcode("") { 7310fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("@Override") 7324c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("public void executePendingBindings() {") { 733d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val tmpDirtyFlags = FlagSet(mDirtyFlags.buckets) 734d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tmpDirtyFlags.setLocalName("dirtyFlags"); 735d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in (0..mDirtyFlags.buckets.size() - 1)) { 736d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${tmpDirtyFlags.type} ${tmpDirtyFlags.localValue(i)} = ${mDirtyFlags.localValue(i)};") 737d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${mDirtyFlags.localValue(i)} = 0;") 738d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 739d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getPendingExpressions().filterNot {it.isVariable()}.forEach { 740d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${it.getResolvedType().toJavaCode()} ${it.localName} = ${it.getDefaultValue()};") 741d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 742d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 743d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar do { 74474f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyar val batch = ExprModel.filterShouldRead(model.getPendingExpressions()).toArrayList() 745d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val mJustRead = arrayListOf<Expr>() 746d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar while (!batch.none()) { 7470fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val readNow = batch.filter { it.shouldReadNow(mJustRead) } 748d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (readNow.isEmpty()) { 749d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar throw IllegalStateException("do not know what I can read. bailing out ${batch.joinToString("\n")}") 750d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 75143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Log.d { "new read now. batch size: ${batch.size()}, readNow size: ${readNow.size()}" } 752d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 753d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar readNow.forEach { 7540fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl(readWithDependants(it, mJustRead, batch, tmpDirtyFlags)) 755d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 756d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar batch.removeAll(mJustRead) 757d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7580fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// batch finished") 759d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } while(model.markBitsRead()) 760d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 761d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // 76296e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter { it.isUsed() } 763d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .flatMap { it.getBindings() } 764d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .groupBy { it.getExpr() } 765d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 766d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.key.dirtyFlagSet 767d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 768d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 769d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }.joinToString(" || ") 770d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) {") { 771d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.value.forEach { binding -> 77297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("// api target ${binding.getMinApi()}") 77334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val fieldName : String 77434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount if (binding.getTarget().getViewClass(). 77534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount equals(binding.getTarget().getInterfaceType())) { 77634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fieldName = "this.${binding.getTarget().fieldName}" 77734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } else { 77834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fieldName = "((${binding.getTarget().getViewClass()}) this.${binding.getTarget().fieldName})" 77934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 78034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val bindingCode = binding.toJavaCode(fieldName, binding.getExpr().toCode().generate()) 78197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar if (binding.getMinApi() > 1) { 7824c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("if(getBuildSdkInt() >= ${binding.getMinApi()}) {") { 78397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("$bindingCode;") 78497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 78597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("}") 78697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } else { 78797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("$bindingCode;") 78897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 789d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 790d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 791d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 792d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7935bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar includedBinders.filter{it.isUsed()}.forEach { binder -> 7944c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("${binder.fieldName}.executePendingBindings();") 7957551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 79696e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{ 797de38dd3ef0577d25b2d59863603abe5750d0c231George Mount it.isUsed() && it.getResolvedType() != null && it.getResolvedType().extendsViewStub() 798de38dd3ef0577d25b2d59863603abe5750d0c231George Mount }.forEach { 799de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("if (${it.fieldName}.getBinding() != null) {") { 800de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("${it.fieldName}.getBinding().executePendingBindings();") 801de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 802de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("}") 803de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 804d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8050fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 806d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 807d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 808d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar fun readWithDependants(expr : Expr, mJustRead : MutableList<Expr>, batch : MutableList<Expr>, 809d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tmpDirtyFlags : FlagSet, inheritedFlags : FlagSet? = null) : KCode = kcode("") { 810d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mJustRead.add(expr) 81143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Log.d { expr.getUniqueKey() } 812d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = expr.shouldReadFlagSet 813d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val needsIfWrapper = inheritedFlags == null || !flagSet.bitsEqual(inheritedFlags) 814d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val ifClause = "if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 81543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 81643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.joinToString(" || ") 817d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar })" 818d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 819d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val readCode = kcode("") { 820d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (!expr.isVariable()) { 821d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // it is not a variable read it. 822d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("// read ${expr.getUniqueKey()}") 823d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // create an if case for all dependencies that might be null 824d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val nullables = expr.getDependencies().filter { 825e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount it.isMandatory() && it.getOther().getResolvedType().isNullable() 82674f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyar }.map { it.getOther() } 827d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (!expr.isEqualityCheck() && nullables.isNotEmpty()) { 828d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab ("if ( ${nullables.map { "${it.localName} != null" }.joinToString(" && ")}) {") { 829d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${expr.localName}").app(" = ", expr.toCode(true)).app(";") 830d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 831d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 832d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } else { 833d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${expr.localName}").app(" = ", expr.toCode(true)).app(";") 834d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8357920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount if (expr.isObservable()) { 836d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("updateRegistration(${expr.getId()}, ${expr.localName});") 837d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8380fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 839d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 8400fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar // if I am the condition for an expression, set its flag 8410fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val conditionals = expr.getDependants().filter { !it.isConditional() 8420fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar && it.getDependant() is TernaryExpr && (it.getDependant() as TernaryExpr).getPred() == expr } 8430fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar .map { it.getDependant() } 8440fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar if (conditionals.isNotEmpty()) { 8450fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// setting conditional flags") 8460fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("if (${expr.localName}) {") { 8470fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar conditionals.forEach { 8480fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val set = it.getRequirementFlagSet(true) 8490fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar mDirtyFlags.mapOr(set) { suffix , index -> 8500fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 851d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 852d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 853d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8540fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("} else {") { 8550fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar conditionals.forEach { 8560fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val set = it.getRequirementFlagSet(false) 8570fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar mDirtyFlags.mapOr(set) { suffix , index -> 8580fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 8590fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 8600fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 8610fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } tab("}") 862d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8630fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar 864d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val chosen = expr.getDependants().filter { 865d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val dependant = it.getDependant() 866d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar batch.contains(dependant) && 867d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar dependant.shouldReadFlagSet.andNot(flagSet).isEmpty() && 868d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar dependant.shouldReadNow(mJustRead) 869d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 870d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (chosen.isNotEmpty()) { 871d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar val nextInheritedFlags = if (needsIfWrapper) flagSet else inheritedFlags 872d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar chosen.forEach { 873d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readWithDependants(it.getDependant(), mJustRead, batch, tmpDirtyFlags, nextInheritedFlags)) 874d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 875d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 876d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 877d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar if (needsIfWrapper) { 878d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tab(ifClause) { 879d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar app(" {") 880d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readCode) 881d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 882d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar tab("}") 883d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } else { 884d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar nl(readCode) 885d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 886d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 88743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 888dea555cf42dc3583604699c8c018d22681f56166George Mount fun declareFactories() = kcode("") { 88996e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (!layoutBinder.isMerge()) { 89096e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public static ${baseClassName} inflate(android.view.ViewGroup root) {") { 89196e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("return bind(android.view.LayoutInflater.from(root.getContext()).inflate(${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, root, true));") 892dea555cf42dc3583604699c8c018d22681f56166George Mount } 89396e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 89496e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public static ${baseClassName} inflate(android.content.Context context) {") { 89596e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("return bind(android.view.LayoutInflater.from(context).inflate(${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, null, false));") 89696e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 89796e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 89896e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("public static ${baseClassName} bind(android.view.View view) {") { 89996e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("if (!\"${layoutBinder.getTag()}_0\".equals(view.getTag())) {") { 90096e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("throw new RuntimeException(\"view tag isn't correct on view\");") 90196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 90296e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("}") 90396e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("return new ${baseClassName}(view);") 90496e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 90596e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 906dea555cf42dc3583604699c8c018d22681f56166George Mount } 907dea555cf42dc3583604699c8c018d22681f56166George Mount } 908dea555cf42dc3583604699c8c018d22681f56166George Mount 9094c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount public fun writeBaseClass() : String = 91043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar kcode("package ${layoutBinder.getPackage()};") { 911fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.Bindable;") 912fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.DataBindingUtil;") 913fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.ViewDataBinding;") 9144c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("public abstract class ${baseClassName} extends ViewDataBinding {") 91596e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 916de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("public final ${it.interfaceType} ${it.fieldName};") 91734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 91834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 91934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("protected ${baseClassName}(android.view.View root_, int localFieldCount") { 92096e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 921de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab(", ${it.interfaceType} ${it.readableUniqueName}") 92234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 92334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 92434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab(") {") { 92534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("super(root_, localFieldCount);") 92696e1c821dd446d1ed78f8ae61131550588f60a24George Mount layoutBinder.getSortedTargets().filter{it.getId() != null}.forEach { 92734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab("this.${it.fieldName} = ${it.readableUniqueName};") 92834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 9294c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 9304c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 9314c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("") 93243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar variables.forEach { 93318243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.getUserDefinedType() != null) { 934895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar //it.getExpandedUserDefinedType(ModelAnalyzer.getInstance()); 935895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar val type = ModelAnalyzer.getInstance().applyImports(it.getUserDefinedType(), model.getImports()) 9364c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public abstract void ${it.setterName}(${type} ${it.readableUniqueName});") 93718243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 93843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 9394c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public static ${baseClassName} inflate(android.view.ViewGroup root) {") { 940a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar tab("return DataBindingUtil.<${baseClassName}>inflate(root.getContext(), ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, root, true);") 94143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 9424c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 9434c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public static ${baseClassName} inflate(android.content.Context context) {") { 944a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar tab("return DataBindingUtil.<${baseClassName}>inflate(context, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, null, false);") 9454c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 9464c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 9474c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public static ${baseClassName} bind(android.view.View view) {") { 948a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar tab("return (${baseClassName})DataBindingUtil.bindTo(view, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()});") 9494c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 9504c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 95143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar nl("}") 95243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.generate() 953dea555cf42dc3583604699c8c018d22681f56166George Mount} 954