LayoutBinderWriter.kt revision fead9ca09b117136b35bc5bf137340a754f9eddd
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 4243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 43d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun String.stripNonJava() = this.split("[^a-zA-Z0-9]").map{ it.trim() }.joinToCamelCaseAsVar() 44d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 45d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarclass ExprModelExt { 46d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val usedFieldNames = hashSetOf<String>() 47d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val localizedFlags = arrayListOf<FlagSet>() 48d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 49d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun localizeFlag(set : FlagSet, name:String) : FlagSet { 50d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar localizedFlags.add(set) 51d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val result = getUniqueFieldName(name) 52d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar set.setLocalName(result) 53d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return set 54d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 55d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 56d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun getUniqueFieldName(base : String) : String { 57d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var candidate = base 58d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var i = 0 59d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar while (usedFieldNames.contains(candidate)) { 60d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar i ++ 61d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar candidate = base + i 62d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 63d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar usedFieldNames.add(candidate) 64d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return candidate 65d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 66d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 67d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 68d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval ExprModel.ext by Delegates.lazy { (target : ExprModel) -> 69d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar ExprModelExt() 70d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 71d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 72d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun ExprModel.getUniqueFieldName(base : String) : String = ext.getUniqueFieldName(base) 73d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 74d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun ExprModel.localizeFlag(set : FlagSet, base : String) : FlagSet = ext.localizeFlag(set, base) 75d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 76d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval BindingTarget.readableUniqueName by Delegates.lazy {(target: BindingTarget) -> 7700da715547ee7d5d38a3b8576090ca427a94daa5George Mount val variableName : String 7800da715547ee7d5d38a3b8576090ca427a94daa5George Mount if (target.getId() == null) { 7900da715547ee7d5d38a3b8576090ca427a94daa5George Mount variableName = "boundView" + target.getTag() 8000da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 8100da715547ee7d5d38a3b8576090ca427a94daa5George Mount variableName = target.getId().androidId().stripNonJava() 8200da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 8300da715547ee7d5d38a3b8576090ca427a94daa5George Mount target.getModel().ext.getUniqueFieldName(variableName) 84d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 857551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 86d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval BindingTarget.fieldName by Delegates.lazy { (target : BindingTarget) -> 87d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "m${target.readableUniqueName.capitalize()}" 88d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 89d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 90d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval BindingTarget.getterName by Delegates.lazy { (target : BindingTarget) -> 91d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "get${target.readableUniqueName.capitalize()}" 92d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 93d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 94d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval BindingTarget.androidId by Delegates.lazy { (target : BindingTarget) -> 9543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar "R.id.${target.getId().androidId()}" 96d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 97d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 98d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval Expr.readableUniqueName by Delegates.lazy { (expr : Expr) -> 9943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Log.d { "readableUniqueName for ${expr.getUniqueKey()}" } 100d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val stripped = "${expr.getUniqueKey().stripNonJava()}" 101d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar expr.getModel().ext.getUniqueFieldName(stripped) 102d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 103d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 104d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval Expr.fieldName by Delegates.lazy { (expr : Expr) -> 105d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "m${expr.readableUniqueName.capitalize()}" 106d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 107d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 108d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval Expr.hasFlag by Delegates.lazy { (expr : Expr) -> 109d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar expr.getId() < expr.getModel().getInvalidateableFieldLimit() 110d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 111d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 112d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval Expr.localName by Delegates.lazy { (expr : Expr) -> 113d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if(expr.isVariable()) expr.fieldName else "${expr.readableUniqueName}" 114d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 115d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 116d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval Expr.setterName by Delegates.lazy { (expr : Expr) -> 117d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "set${expr.readableUniqueName.capitalize()}" 118d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 119d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 120d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval Expr.onChangeName by Delegates.lazy { (expr : Expr) -> 121d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "onChange${expr.readableUniqueName.capitalize()}" 122d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 123d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 124d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval Expr.getterName by Delegates.lazy { (expr : Expr) -> 125d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "get${expr.readableUniqueName.capitalize()}" 126d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 127d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 128d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval Expr.staticFieldName by Delegates.lazy { (expr : Expr) -> 129d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "s${expr.readableUniqueName.capitalize()}" 130d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 131d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 132d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval Expr.dirtyFlagName by Delegates.lazy { (expr : Expr) -> 133d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "sFlag${expr.readableUniqueName.capitalize()}" 134d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 135d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 136d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval Expr.shouldReadFlagName by Delegates.lazy { (expr : Expr) -> 137d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "sFlagRead${expr.readableUniqueName.capitalize()}" 138d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 139d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 140d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval Expr.invalidateFlagName by Delegates.lazy { (expr : Expr) -> 141d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "sFlag${expr.readableUniqueName.capitalize()}Invalid" 142d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 143d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 144d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval Expr.conditionalFlagPrefix by Delegates.lazy { (expr : Expr) -> 145d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "sFlag${expr.readableUniqueName.capitalize()}Is" 146d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 147d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 148d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 149d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.toCode(full : Boolean = false) : KCode { 150d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val it = this 151d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (isDynamic() && !full) { 152d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return kcode(localName) 153d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 154d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return when (it) { 155d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is ComparisonExpr -> kcode("") { 156d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getLeft().toCode()) 157d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(it.getOp()) 158d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getRight().toCode()) 159d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 160d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is FieldAccessExpr -> kcode("") { 161a70fed6415aa1e8bbbe929aee776402ac3b81c86George Mount app("", it.getChild().toCode()) 162e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount if (it.getGetter().type == Callable.Type.FIELD) { 163d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(".", it.getGetter().name) 164d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } else { 165d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(".", it.getGetter().name).app("()") 166d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 167d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 168d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is GroupExpr -> kcode("(").app("", it.getWrapped().toCode()).app(")") 169d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is StaticIdentifierExpr -> kcode(it.getResolvedType().toJavaCode()) 170d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is IdentifierExpr -> kcode(it.localName) 171d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is MathExpr -> kcode("") { 172d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getLeft().toCode()) 173d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(it.getOp()) 174d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getRight().toCode()) 175d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 176d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is MethodCallExpr -> kcode("") { 177d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getTarget().toCode()) 178d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(".", it.getGetter().name) 179d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("(") 180d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var first = true 181d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.getArgs().forEach { 182d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar apps(if (first) "" else ",", it.toCode()) 183d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar first = false 184d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 185d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(")") 186d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 187d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is SymbolExpr -> kcode(it.getText()) // TODO 188d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is TernaryExpr -> kcode("") { 189d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("", it.getPred().toCode()) 190d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app("?", it.getIfTrue().toCode()) 191d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(":", it.getIfFalse().toCode()) 192d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 193c752a5f795baf6df435ef60881316cb748df407cGeorge Mount is ResourceExpr -> kcode("") { 194c752a5f795baf6df435ef60881316cb748df407cGeorge Mount app("", it.toJava()) 195c752a5f795baf6df435ef60881316cb748df407cGeorge Mount } 1965cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount is BracketExpr -> kcode("") { 1975cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("", it.getTarget().toCode()) 1985cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount val bracketType = it.getAccessor(); 1995cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount when (bracketType) { 2005cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount BracketExpr.BracketAccessor.ARRAY -> { 2015cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("[", it.getArg().toCode()) 2025cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("]") 2035cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2045cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount BracketExpr.BracketAccessor.LIST -> { 2055cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(".get(") 2065cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount if (it.argCastsInteger()) { 2075cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("(Integer)") 2085cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2095cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app("", it.getArg().toCode()) 2105cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(")") 2115cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2125cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount BracketExpr.BracketAccessor.MAP -> { 2135cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(".get(", it.getArg().toCode()) 2145cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount app(")") 2155cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2165cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 2175cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 218e4b93061ac703e48fc2c9994c9059ed016f05559George Mount is CastExpr -> kcode("") { 219e4b93061ac703e48fc2c9994c9059ed016f05559George Mount app("(", it.getCastType()) 220e4b93061ac703e48fc2c9994c9059ed016f05559George Mount app(") ", it.getCastExpr().toCode()) 221e4b93061ac703e48fc2c9994c9059ed016f05559George Mount } 222d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar else -> kcode("//NOT IMPLEMENTED YET") 223d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 224d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 225d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 226d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 227d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.isVariable() = this is IdentifierExpr && this.isDynamic() 228d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 229d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.conditionalFlagName(output : Boolean, suffix : String) = "${dirtyFlagName}_${output}$suffix" 230d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 231d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 232d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval Expr.dirtyFlagSet by Delegates.lazy { (expr : Expr) -> 233d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val fs = FlagSet(expr.getInvalidFlags(), expr.getModel().getFlagBucketCount()) 234d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar expr.getModel().localizeFlag(fs, expr.dirtyFlagName) 235d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 236d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 237d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval Expr.invalidateFlagSet by Delegates.lazy { (expr : Expr) -> 238d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val fs = FlagSet(expr.getId()) 239d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar expr.getModel().localizeFlag(fs, expr.invalidateFlagName) 240d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 241d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 242d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval Expr.shouldReadFlagSet by Delegates.lazy { (expr : Expr) -> 243d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val fs = FlagSet(expr.getShouldReadFlags(), expr.getModel().getFlagBucketCount()) 244d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar expr.getModel().localizeFlag(fs, expr.shouldReadFlagName) 245d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 246d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 247d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarval Expr.conditionalFlags by Delegates.lazy { (expr : Expr) -> 248d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val model = expr.getModel() 249d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar arrayListOf(model.localizeFlag(FlagSet(expr.getRequirementFlagIndex(false)), 250d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "${expr.conditionalFlagPrefix}False"), 251d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.localizeFlag(FlagSet(expr.getRequirementFlagIndex(true)), 252d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "${expr.conditionalFlagPrefix}True")) 253d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 254d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 255d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.getRequirementFlagSet(expected : Boolean) : FlagSet = conditionalFlags[if(expected) 1 else 0] 256d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 257d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.notEmpty(cb : (suffix : String, value : Long) -> Unit) { 258d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar buckets.withIndex().forEach { 259d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (it.value != 0L) { 260d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar cb(getWordSuffix(it.index), buckets[it.index]) 261d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 262d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 263d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 264d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 265d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.getBitSuffix(bitIndex : Int) : String { 266d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val word = bitIndex / FlagSet.sBucketSize 267d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return getWordSuffix(word) 268d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 269d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 270d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.getWordSuffix(wordIndex : Int) : String { 271d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return if(wordIndex == 0) "" else "_${wordIndex}" 272d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 273d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 274d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.localValue(bucketIndex : Int) = 275d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (getLocalName() == null) buckets[bucketIndex] 276d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar else "${getLocalName()}${getWordSuffix(bucketIndex)}" 277d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 278d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.or(other : FlagSet, cb : (suffix : String) -> Unit) { 279d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val min = Math.min(buckets.size(), other.buckets.size()) 280d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in 0..(min - 1)) { 281d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // if these two can match by any chance, call the callback 282d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (intersect(other, i)) { 283d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar cb(getWordSuffix(i)) 284d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 285d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 286d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 287d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 288d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun <T> FlagSet.mapOr(other : FlagSet, cb : (suffix : String, index : Int) -> T) : List<T> { 289d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val min = Math.min(buckets.size(), other.buckets.size()) 290d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val result = arrayListOf<T>() 291d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in 0..(min - 1)) { 292d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // if these two can match by any chance, call the callback 293d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (intersect(other, i)) { 294d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar result.add(cb(getWordSuffix(i), i)) 295d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 296d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 297d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return result 298d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 299d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 30043596c2b2997e40b709627419732100d78a62ff0Yigit Boyarclass LayoutBinderWriter(val layoutBinder : LayoutBinder) { 301d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val model = layoutBinder.getModel() 30243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val mDirtyFlags by Delegates.lazy { 30343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val fs = FlagSet(BitSet(), model.getFlagBucketCount()); 30443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Arrays.fill(fs.buckets, -1) 30543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs.setDynamic(true) 30643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.localizeFlag(fs, "mDirtyFlags") 30743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs 308d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 309d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 31043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val dynamics by Delegates.lazy { model.getExprMap().values().filter { it.isDynamic() } } 311d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val className = layoutBinder.getClassName() 312d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 31343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val identifiers by Delegates.lazy { 31443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar dynamics.filter { it is IdentifierExpr } 31543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 316d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 3174c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount val baseClassName = "${layoutBinder.getInterfaceName()}" 318d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 3197551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar val includedBinders by Delegates.lazy { 3207551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar layoutBinder.getBindingTargets().filter { it.isBinder() } 3217551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 3227551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 32343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar val variables by Delegates.lazy { 32443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.getExprMap().values().filterIsInstance(javaClass<IdentifierExpr>()).filter { it.isVariable() } 32543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 326d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 3275bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar val usedVariables by Delegates.lazy { 3285bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar variables.filter {it.isUsed()} 3295bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 330d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 3315bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar public fun write() : String { 3325bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar layoutBinder.resolveWhichExpressionsAreUsed() 3335bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar return kcode("package ${layoutBinder.getPackage()};") { 334a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar nl("import ${layoutBinder.getModulePackage()}.R;") 335a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar nl("import ${layoutBinder.getModulePackage()}.BR;") 3365bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("import android.view.View;") 3374c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("public class ${className} extends ${baseClassName} {") { 3384c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(declareIncludeViews()) 3395bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareViews()) 3405bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareVariables()) 3415bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareConstructor()) 3425bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareInvalidateAll()) 3435bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareLog()) 3445bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareSetVariable()) 3455bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(variableSettersAndGetters()) 3465bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(viewGetters()) 3475bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(onFieldChange()) 3485bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 3494c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(executePendingBindings()) 3505bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 3515bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareDirtyFlags()) 3525bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 3535bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 3545bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(flagMapping()) 3555bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("//end") 3565bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar }.generate() 3575bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 3584c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun declareIncludeViews() = kcode("") { 3594c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("private static final android.util.SparseIntArray sIncludes;") 3604c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("private static final android.util.SparseIntArray sViewsWithIds;") 3614c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("static {") { 3624c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount val hasBinders = layoutBinder.getBindingTargets().firstOrNull{ it.isUsed() && it.isBinder()} != null 3634c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount if (!hasBinders) { 3644c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sIncludes = null;") 36500da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 3664c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sIncludes = new android.util.SparseIntArray();") 3674c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount val numTaggedViews = layoutBinder.getBindingTargets(). 3684c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount filter{it.isUsed() && !it.isBinder()}.count() 3694c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount layoutBinder.getBindingTargets().filter{ it.isUsed() && it.isBinder()}.withIndex() 3704c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount .forEach { 3714c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sIncludes.put(${it.value.androidId}, ${it.index + numTaggedViews});") 3724c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 37300da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 3744c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount val hasViewsWithIds = layoutBinder.getBindingTargets().firstOrNull{ it.isUsed() && !it.supportsTag()} != null 3754c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount if (!hasViewsWithIds) { 3764c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = null;") 37700da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 3784c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = new android.util.SparseIntArray();") 3794c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount layoutBinder.getBindingTargets().filter{ it.isUsed() && !it.supportsTag() }. 3804c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount forEach { 3814c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds.put(${it.androidId}, ${it.getTag()});") 3824c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 38300da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 3844c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 3854c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("}") 3864c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 3874c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun declareConstructor() = kcode("") { 3884c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("public ${className}(View root) {") { 3894c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("super(root, ${model.getObservables().size()});") 3904c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount val viewCount = layoutBinder.getBindingTargets().filter{it.isUsed()}.count() 3914c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("View[] views = new View[${viewCount}];") 3924c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("mapTaggedChildViews(root, views, sIncludes, sViewsWithIds);"); 3934c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount val taggedViews = layoutBinder.getBindingTargets().filter{it.isUsed() && !it.isBinder()} 3944c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount taggedViews.forEach { 3954c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount if (it.getTag() == null) { 39600da715547ee7d5d38a3b8576090ca427a94daa5George Mount tab("this.${it.fieldName} = (${it.getViewClass()}) root;") 3977551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } else { 3984c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("this.${it.fieldName} = (${it.getViewClass()}) views[${it.getTag()}];") 39900da715547ee7d5d38a3b8576090ca427a94daa5George Mount if (it.supportsTag()) { 40000da715547ee7d5d38a3b8576090ca427a94daa5George Mount val originalTag = it.getOriginalTag(); 40100da715547ee7d5d38a3b8576090ca427a94daa5George Mount var tagValue = "null" 40200da715547ee7d5d38a3b8576090ca427a94daa5George Mount if (originalTag != null) { 40300da715547ee7d5d38a3b8576090ca427a94daa5George Mount tagValue = "\"${originalTag}\"" 40400da715547ee7d5d38a3b8576090ca427a94daa5George Mount if (originalTag.startsWith("@")) { 405a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar var packageName = layoutBinder.getModulePackage() 40600da715547ee7d5d38a3b8576090ca427a94daa5George Mount if (originalTag.startsWith("@android:")) { 40700da715547ee7d5d38a3b8576090ca427a94daa5George Mount packageName = "android" 40800da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 40900da715547ee7d5d38a3b8576090ca427a94daa5George Mount val slashIndex = originalTag.indexOf('/') 41000da715547ee7d5d38a3b8576090ca427a94daa5George Mount val resourceId = originalTag.substring(slashIndex + 1) 41100da715547ee7d5d38a3b8576090ca427a94daa5George Mount tagValue = "root.getResources().getString(${packageName}.R.string.${resourceId})" 41200da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 41300da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 41400da715547ee7d5d38a3b8576090ca427a94daa5George Mount tab("this.${it.fieldName}.setTag(${tagValue});") 41500da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 4167551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 417d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 4184c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount val taggedCount = taggedViews.count() 4194c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount layoutBinder.getBindingTargets().filter{it.isUsed() && it.isBinder()}.withIndex() 4204c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount .forEach { 4214c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("this.${it.value.fieldName} = ${it.value.getViewClass()}.bind(views[${it.index + taggedCount}]);") 4224c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 423d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("invalidateAll();"); 424d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 4250fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 426d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 427d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 428d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareInvalidateAll() = kcode("") { 4297551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("@Override") 4307551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("public void invalidateAll() {") { 431d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val bs = BitSet() 432d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar bs.set(0, model.getInvalidateableFieldLimit()) 433d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val fs = FlagSet(bs, mDirtyFlags.buckets.size()) 434d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in (0..(mDirtyFlags.buckets.size() - 1))) { 435d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${mDirtyFlags.localValue(i)} = ${fs.localValue(i)};") 436d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 4375bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar includedBinders.filter{it.isUsed()}.forEach { binder -> 4387551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar tab("${binder.fieldName}.invalidateAll();") 4397551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 440d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 4410fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 442d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 443d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 444d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareSetVariable() = kcode("") { 4450fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("public boolean setVariable(int variableId, Object variable) {") { 446d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch(variableId) {") { 4475bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 44843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab ("case ${it.getName().br()} :") { 449d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${it.setterName}((${it.getResolvedType().toJavaCode()}) variable);") 450d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 451d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 452d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 453d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 454d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 455d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 456d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 4570fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 458d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 459d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 460d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareLog() = kcode("") { 4610fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private void log(String msg, long i) {") { 462d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("""android.util.Log.d("BINDER", msg + ":" + Long.toHexString(i));""") 4630fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 4640fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 465d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 466d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 467d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun variableSettersAndGetters() = kcode("") { 4685bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar variables.filterNot{it.isUsed()}.forEach { 4695bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("public void ${it.setterName}(${it.getResolvedType().toJavaCode()} ${it.readableUniqueName}) {") { 4705bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("// not used, ignore") 4715bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 4725bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 4735bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("") 4745bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("public ${it.getResolvedType().toJavaCode()} ${it.getterName}() {") { 4755bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("return ${it.getDefaultValue()};") 4765bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 4775bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 4785bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 4795bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 48018243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.getUserDefinedType() != null) { 48118243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("public void ${it.setterName}(${it.getResolvedType().toJavaCode()} ${it.readableUniqueName}) {") { 48218243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.isObservable()) { 48318243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("updateRegistration(${it.getId()}, ${it.readableUniqueName});"); 48418243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 48518243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("this.${it.fieldName} = ${it.readableUniqueName};") 48618243f6f1b7527272ef4feccdf4327d80d9f2241George Mount // set dirty flags! 48718243f6f1b7527272ef4feccdf4327d80d9f2241George Mount val flagSet = it.invalidateFlagSet 48818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount mDirtyFlags.mapOr(flagSet) { suffix, index -> 48918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("${mDirtyFlags.getLocalName()}$suffix |= ${flagSet.localValue(index)};") 49018243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 49118243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("super.requestRebind();") 492d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 49318243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 49418243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("") 49518243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("public ${it.getResolvedType().toJavaCode()} ${it.getterName}() {") { 49618243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("return ${it.fieldName};") 497d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 49818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 499d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 500d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 501d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 502d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 503d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun onFieldChange() = kcode("") { 504d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("@Override") 5054c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {") { 5064c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("switch (localFieldId) {") { 507d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getObservables().forEach { 508d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("case ${it.getId()} :") { 509d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return ${it.onChangeName}((${it.getResolvedType().toJavaCode()}) object, fieldId);") 510d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 511d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 512d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 513d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 514d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 515d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 516d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 517d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 518d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getObservables().forEach { 519d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("private boolean ${it.onChangeName}(${it.getResolvedType().toJavaCode()} ${it.readableUniqueName}, int fieldId) {") { 520d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch (fieldId) {", { 521d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val accessedFields: List<FieldAccessExpr> = it.getParents().filterIsInstance(javaClass<FieldAccessExpr>()) 522d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar accessedFields.filter { it.canBeInvalidated() } 523d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .groupBy { it.getName() } 524d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 52543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${it.key.br()}:") { 526d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val field = it.value.first() 527d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mDirtyFlags.mapOr(field.invalidateFlagSet) { suffix, index -> 528d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${mDirtyFlags.localValue(index)} |= ${field.invalidateFlagSet.localValue(index)};") 529d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 530d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 531d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 532d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 533d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 53443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${"".br()}:") { 535d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.invalidateFlagSet 536d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 537d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${mDirtyFlags.getLocalName()}$suffix |= ${flagSet.localValue(index)};") 538d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 539d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 540d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 541d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 542d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) 543d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 544d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 545d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 546d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 547d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 548d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 549d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 550d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareViews() = kcode("// views") { 5515bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar layoutBinder.getBindingTargets().filter{it.isUsed()}.forEach { 55200da715547ee7d5d38a3b8576090ca427a94daa5George Mount nl("private final ${it.getViewClass()} ${it.fieldName};") 553d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 554d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 555d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 556d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun viewGetters() = kcode("// view getters") { 55700da715547ee7d5d38a3b8576090ca427a94daa5George Mount layoutBinder.getBindingTargets().filter{it.getId() != null}.forEach { 5580fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("@Override") 5595bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("public ${it.getInterfaceType()} ${it.getterName}() {") { 5605bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar if (it.isUsed()) { 5615bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("return ${it.fieldName};") 5625bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } else { 5635bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("return null;") 5645bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5655bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 566d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 5670fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 568d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 569d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 570d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 571d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareVariables() = kcode("// variables") { 5725bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 5730fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private ${it.getResolvedType().toJavaCode()} ${it.fieldName};") 574d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 575d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 576d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 577d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareDirtyFlags() = kcode("// dirty flag") { 578d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.ext.localizedFlags.forEach { flag -> 579d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar flag.notEmpty { (suffix, value) -> 5800fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private") 581d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(" ", if(flag.isDynamic()) null else "static final"); 582d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar app(" ", " ${flag.type} ${flag.getLocalName()}$suffix = $value;") 583d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 584d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 585d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 586d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 587d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun flagMapping() = kcode("/* flag mapping") { 588d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (model.getFlagMapping() != null) { 589d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val mapping = model.getFlagMapping() 590d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in mapping.indices) { 591d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("flag $i: ${mapping[i]}") 592d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 593d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 594d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nl("flag mapping end*/") 595d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 596d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 5974c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun executePendingBindings() = kcode("") { 5980fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("@Override") 5994c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("public void executePendingBindings() {") { 600d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val tmpDirtyFlags = FlagSet(mDirtyFlags.buckets) 601d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tmpDirtyFlags.setLocalName("dirtyFlags"); 602d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in (0..mDirtyFlags.buckets.size() - 1)) { 603d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${tmpDirtyFlags.type} ${tmpDirtyFlags.localValue(i)} = ${mDirtyFlags.localValue(i)};") 604d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${mDirtyFlags.localValue(i)} = 0;") 605d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 6062c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount //tab("""log("dirty flags", mDirtyFlags);""") 607d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.getPendingExpressions().filterNot {it.isVariable()}.forEach { 608d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${it.getResolvedType().toJavaCode()} ${it.localName} = ${it.getDefaultValue()};") 609d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 610d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 611d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar do { 612d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val batch = model.filterShouldRead(model.getPendingExpressions()).toArrayList() 613d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val mJustRead = arrayListOf<Expr>() 614d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar while (!batch.none()) { 6150fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val readNow = batch.filter { it.shouldReadNow(mJustRead) } 616d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (readNow.isEmpty()) { 617d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar throw IllegalStateException("do not know what I can read. bailing out ${batch.joinToString("\n")}") 618d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 61943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Log.d { "new read now. batch size: ${batch.size()}, readNow size: ${readNow.size()}" } 620d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 621d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar readNow.forEach { 6220fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl(readWithDependants(it, mJustRead, batch, tmpDirtyFlags)) 623d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 624d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar batch.removeAll(mJustRead) 625d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 6260fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// batch finished") 627d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } while(model.markBitsRead()) 628d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 629d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // 6305bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar layoutBinder.getBindingTargets().filter { it.isUsed() } 631d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .flatMap { it.getBindings() } 632d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .groupBy { it.getExpr() } 633d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 634d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.key.dirtyFlagSet 635d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 636d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 637d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }.joinToString(" || ") 638d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) {") { 639d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.value.forEach { binding -> 64097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("// api target ${binding.getMinApi()}") 64197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar val bindingCode = binding.toJavaCode(binding.getTarget().fieldName, binding.getExpr().toCode().generate()) 64297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar if (binding.getMinApi() > 1) { 6434c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("if(getBuildSdkInt() >= ${binding.getMinApi()}) {") { 64497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("$bindingCode;") 64597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 64697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("}") 64797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } else { 64897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar tab("$bindingCode;") 64997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 650d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 651d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 652d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 653d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 6547551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar // 6555bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar includedBinders.filter{it.isUsed()}.forEach { binder -> 6564c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("${binder.fieldName}.executePendingBindings();") 6577551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 658d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 6590fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 660d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 661d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 662d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun readWithDependants(expr : Expr, mJustRead : MutableList<Expr>, batch : MutableList<Expr>, tmpDirtyFlags : FlagSet) : KCode = kcode("") { 663d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mJustRead.add(expr) 66443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Log.d { expr.getUniqueKey() } 665d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = expr.shouldReadFlagSet 666d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 66743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 66843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.joinToString(" || ") 669d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) {") { 670d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (!expr.isVariable()) { 671d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // it is not a variable read it. 672d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("// read ${expr.getUniqueKey()}") 673d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // create an if case for all dependencies that might be null 674d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val nullables = expr.getDependencies().filter { 675e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount it.isMandatory() && it.getOther().getResolvedType().isNullable() 67643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 677d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .map { it.getOther() } 678d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (!expr.isEqualityCheck() && nullables.isNotEmpty()) { 679d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab ("if ( ${nullables.map { "${it.localName} != null" }.joinToString(" && ")}) {") { 680d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${expr.localName}").app(" = ", expr.toCode(true)).app(";") 6812c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount //tab("""log("${expr}" + ${expr.localName},0);""") 682d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 683d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 684d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } else { 685d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("${expr.localName}").app(" = ", expr.toCode(true)).app(";") 6862c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount //tab("""log("${expr}" + ${expr.localName},0);""") 687d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 6887920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount if (expr.isObservable()) { 689d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("updateRegistration(${expr.getId()}, ${expr.localName});") 690d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 6910fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 692d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 6930fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar // if I am the condition for an expression, set its flag 6940fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val conditionals = expr.getDependants().filter { !it.isConditional() 6950fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar && it.getDependant() is TernaryExpr && (it.getDependant() as TernaryExpr).getPred() == expr } 6960fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar .map { it.getDependant() } 6970fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar if (conditionals.isNotEmpty()) { 6980fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// setting conditional flags") 6990fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("if (${expr.localName}) {") { 7000fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar conditionals.forEach { 7010fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val set = it.getRequirementFlagSet(true) 7020fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar mDirtyFlags.mapOr(set) { suffix , index -> 7030fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 704d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 705d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 706d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7070fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("} else {") { 7080fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar conditionals.forEach { 7090fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar val set = it.getRequirementFlagSet(false) 7100fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar mDirtyFlags.mapOr(set) { suffix , index -> 7110fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 7120fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 7130fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 7140fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } tab("}") 715d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7160fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar 717d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val chosen = expr.getDependants().filter { 7180fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar batch.contains(it.getDependant()) && it.getDependant().shouldReadNow(mJustRead) 719d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 720d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (chosen.isNotEmpty()) { 721d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar chosen.forEach { 722d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nl(readWithDependants(it.getDependant(), mJustRead, batch, tmpDirtyFlags)) 723d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 724d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 725d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 726d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 727d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 72843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 7294c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount public fun writeBaseClass() : String = 73043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar kcode("package ${layoutBinder.getPackage()};") { 731fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.Bindable;") 732fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.DataBindingUtil;") 733fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.ViewDataBinding;") 7344c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("public abstract class ${baseClassName} extends ViewDataBinding {") 7354c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("protected ${baseClassName}(android.view.View root, int localFieldCount) {") { 7364c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("super(root, localFieldCount);") 7374c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 7384c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 7394c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("") 74043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar variables.forEach { 74118243f6f1b7527272ef4feccdf4327d80d9f2241George Mount if (it.getUserDefinedType() != null) { 74218243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("@Bindable") 743895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar //it.getExpandedUserDefinedType(ModelAnalyzer.getInstance()); 744895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar val type = ModelAnalyzer.getInstance().applyImports(it.getUserDefinedType(), model.getImports()) 7454c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public abstract void ${it.setterName}(${type} ${it.readableUniqueName});") 74618243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 74743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 74800da715547ee7d5d38a3b8576090ca427a94daa5George Mount layoutBinder.getBindingTargets().filter{ it.getId() != null }.forEach { 7494c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public abstract ${it.getInterfaceType()} ${it.getterName}();") 7504c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 7514c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("") 7524c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public static ${baseClassName} inflate(android.view.ViewGroup root) {") { 753a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar tab("return DataBindingUtil.<${baseClassName}>inflate(root.getContext(), ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, root, true);") 75443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 7554c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 7564c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public static ${baseClassName} inflate(android.content.Context context) {") { 757a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar tab("return DataBindingUtil.<${baseClassName}>inflate(context, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()}, null, false);") 7584c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 7594c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 7604c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("public static ${baseClassName} bind(android.view.View view) {") { 761a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar tab("return (${baseClassName})DataBindingUtil.bindTo(view, ${layoutBinder.getModulePackage()}.R.layout.${layoutBinder.getLayoutname()});") 7624c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 7634c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 76443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar nl("}") 76543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.generate() 766d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar}