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 16e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarimport android.databinding.tool.BindingTarget 17d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mountimport android.databinding.tool.InverseBinding 18716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport android.databinding.tool.LayoutBinder 19fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.Expr 20fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ExprModel 21fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.FieldAccessExpr 22716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport android.databinding.tool.expr.IdentifierExpr 23793e979f25e190162eacf46d6a4efc3efc1d2f91George Mountimport android.databinding.tool.expr.ListenerExpr 2409aeb26073fc8a98263806f53e44819ebe5046c6Yigit Boyarimport android.databinding.tool.expr.ResourceExpr 25d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mountimport android.databinding.tool.expr.TernaryExpr 267b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarimport android.databinding.tool.ext.androidId 27d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mountimport android.databinding.tool.ext.br 287b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarimport android.databinding.tool.ext.joinToCamelCaseAsVar 2959229481aec5a284d322a2ca80dff836485feb0cYigit Boyarimport android.databinding.tool.ext.lazyProp 30716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport android.databinding.tool.ext.versionedLazy 3192a428505b9102bc0560d2d5be1768da097909c2George Mountimport android.databinding.tool.processing.ErrorMessages 32fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelAnalyzer 337b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyarimport android.databinding.tool.util.L 3496e1c821dd446d1ed78f8ae61131550588f60a24George Mountimport java.util.ArrayList 35716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport java.util.Arrays 36716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport java.util.BitSet 3734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport java.util.HashMap 3843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 39fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyarfun String.stripNonJava() = this.split("[^a-zA-Z0-9]".toRegex()).map{ it.trim() }.joinToCamelCaseAsVar() 40d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 41019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarenum class Scope { 42fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar FIELD, 43fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar METHOD, 44fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar FLAG, 45fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar EXECUTE_PENDING_METHOD, 46019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar CONSTRUCTOR_PARAM 47019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar} 48019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar 49d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarclass ExprModelExt { 50019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val usedFieldNames = hashMapOf<Scope, MutableSet<String>>(); 51fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar init { 5239113ca579a3d4e1c24e204f102e6dc9b26125afTor Norbye Scope.values().forEach { usedFieldNames[it] = hashSetOf<String>() } 53019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar } 54d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val localizedFlags = arrayListOf<FlagSet>() 55d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 56d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun localizeFlag(set : FlagSet, name:String) : FlagSet { 57d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar localizedFlags.add(set) 58793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount val result = getUniqueName(name, Scope.FLAG, false) 5959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar set.localName = result 60d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return set 61d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 62d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 63793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount fun getUniqueName(base : String, scope : Scope, isPublic : kotlin.Boolean) : String { 64793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount var candidateBase = base 6559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (!isPublic && candidateBase.length > 20) { 66793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount candidateBase = candidateBase.substring(0, 20); 67793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } 68793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount var candidate = candidateBase 69d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var i = 0 705d454e5f2397a3b160f081ce123b4ca7ff0fc356Yigit Boyar while (usedFieldNames[scope]!!.contains(candidate)) { 71d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar i ++ 72793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount candidate = candidateBase + i 73d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 745d454e5f2397a3b160f081ce123b4ca7ff0fc356Yigit Boyar usedFieldNames[scope]!!.add(candidate) 75d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return candidate 76d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 77d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 78d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 7959229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval ExprModel.ext by lazyProp { target : ExprModel -> 80d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar ExprModelExt() 81d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 82d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 83793e979f25e190162eacf46d6a4efc3efc1d2f91George Mountfun ExprModel.getUniqueFieldName(base : String, isPublic : kotlin.Boolean) : String = ext.getUniqueName(base, Scope.FIELD, isPublic) 84793e979f25e190162eacf46d6a4efc3efc1d2f91George Mountfun ExprModel.getUniqueMethodName(base : String, isPublic : kotlin.Boolean) : String = ext.getUniqueName(base, Scope.METHOD, isPublic) 85793e979f25e190162eacf46d6a4efc3efc1d2f91George Mountfun ExprModel.getConstructorParamName(base : String) : String = ext.getUniqueName(base, Scope.CONSTRUCTOR_PARAM, false) 86d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 87d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun ExprModel.localizeFlag(set : FlagSet, base : String) : FlagSet = ext.localizeFlag(set, base) 88d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 8959229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.needsLocalField by lazyProp { expr : Expr -> 9059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar expr.canBeEvaluatedToAVariable() && !(expr.isVariable() && !expr.isUsed) && (expr.isDynamic || expr is ResourceExpr) 9109aeb26073fc8a98263806f53e44819ebe5046c6Yigit Boyar} 9209aeb26073fc8a98263806f53e44819ebe5046c6Yigit Boyar 9309aeb26073fc8a98263806f53e44819ebe5046c6Yigit Boyar 94019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar// not necessarily unique. Uniqueness is solved per scope 9559229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval BindingTarget.readableName by lazyProp { target: BindingTarget -> 9659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (target.id == null) { 9759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar "boundView" + indexFromTag(target.tag) 9800da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 9959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar target.id.androidId().stripNonJava() 10000da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 101d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 1027551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 103de38dd3ef0577d25b2d59863603abe5750d0c231George Mountfun BindingTarget.superConversion(variable : String) : String { 10459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (resolvedType != null && resolvedType.extendsViewStub()) { 10559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar return "new android.databinding.ViewStubProxy((android.view.ViewStub) $variable)" 106de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } else { 10759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar return "($interfaceClass) $variable" 108de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 109de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 110de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 11159229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval BindingTarget.fieldName : String by lazyProp { target : BindingTarget -> 112019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar val name : String 113793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount val isPublic : kotlin.Boolean 11459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (target.id == null) { 115019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar name = "m${target.readableName}" 116793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount isPublic = false 117019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar } else { 118019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar name = target.readableName 119793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount isPublic = true 12034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 12159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar target.model.getUniqueFieldName(name, isPublic) 122d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 123d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 12459229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval BindingTarget.androidId by lazyProp { target : BindingTarget -> 12559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (target.id.startsWith("@android:id/")) { 12659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar "android.R.id.${target.id.androidId()}" 127fdfbbcd5ecf37d77a4b9ab1cefdebd68de71ca2bGeorge Mount } else { 12859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar "R.id.${target.id.androidId()}" 129fdfbbcd5ecf37d77a4b9ab1cefdebd68de71ca2bGeorge Mount } 130d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 131d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 13259229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval BindingTarget.interfaceClass by lazyProp { target : BindingTarget -> 13359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (target.resolvedType != null && target.resolvedType.extendsViewStub()) { 134de38dd3ef0577d25b2d59863603abe5750d0c231George Mount "android.databinding.ViewStubProxy" 135de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } else { 13659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar target.interfaceType 137de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 138de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 139de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 14059229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval BindingTarget.constructorParamName by lazyProp { target : BindingTarget -> 14159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar target.model.getConstructorParamName(target.readableName) 142d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 143d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 144019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar// not necessarily unique. Uniqueness is decided per scope 14559229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.readableName by lazyProp { expr : Expr -> 14659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val stripped = "${expr.uniqueKey.stripNonJava()}" 14759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar L.d("readableUniqueName for [%s] %s is %s", System.identityHashCode(expr), expr.uniqueKey, stripped) 148019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar stripped 149de38dd3ef0577d25b2d59863603abe5750d0c231George Mount} 150de38dd3ef0577d25b2d59863603abe5750d0c231George Mount 15159229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.fieldName by lazyProp { expr : Expr -> 15259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar expr.model.getUniqueFieldName("m${expr.readableName.capitalize()}", false) 153d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 154d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 155d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mountval InverseBinding.fieldName by lazyProp { inverseBinding : InverseBinding -> 156af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar val targetName = inverseBinding.target.fieldName; 157af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar val eventName = inverseBinding.eventAttribute.stripNonJava() 158af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar inverseBinding.model.getUniqueFieldName("$targetName$eventName", false) 159d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount} 160d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 16159229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.listenerClassName by lazyProp { expr : Expr -> 16259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar expr.model.getUniqueFieldName("${expr.resolvedType.simpleName}Impl", false) 163716ba89e7f459f49ea85070d4710c1d79d715298George Mount} 164716ba89e7f459f49ea85070d4710c1d79d715298George Mount 16559229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.oldValueName by lazyProp { expr : Expr -> 16659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar expr.model.getUniqueFieldName("mOld${expr.readableName.capitalize()}", false) 16720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount} 16820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 16959229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.executePendingLocalName by lazyProp { expr : Expr -> 17059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if(expr.needsLocalField) "${expr.model.ext.getUniqueName(expr.readableName, Scope.EXECUTE_PENDING_METHOD, false)}" 17109aeb26073fc8a98263806f53e44819ebe5046c6Yigit Boyar else expr.toCode().generate() 172d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 173d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 17459229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.setterName by lazyProp { expr : Expr -> 17559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar expr.model.getUniqueMethodName("set${expr.readableName.capitalize()}", true) 176d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 177d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 17859229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.onChangeName by lazyProp { expr : Expr -> 17959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar expr.model.getUniqueMethodName("onChange${expr.readableName.capitalize()}", false) 180d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 181d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 18259229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.getterName by lazyProp { expr : Expr -> 18359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar expr.model.getUniqueMethodName("get${expr.readableName.capitalize()}", true) 184d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 185d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 18659229481aec5a284d322a2ca80dff836485feb0cYigit Boyarfun Expr.isVariable() = this is IdentifierExpr && this.isDynamic 187d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 18859229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.dirtyFlagSet by lazyProp { expr : Expr -> 18959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar FlagSet(expr.invalidFlags, expr.model.flagBucketCount) 190d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 191d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 19259229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.invalidateFlagSet by lazyProp { expr : Expr -> 19359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar FlagSet(expr.id) 194d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 195d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 19659229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.shouldReadFlagSet by versionedLazy { expr : Expr -> 19759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar FlagSet(expr.shouldReadFlags, expr.model.flagBucketCount) 198d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 199d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 20059229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.shouldReadWithConditionalsFlagSet by versionedLazy { expr : Expr -> 20159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar FlagSet(expr.shouldReadFlagsWithConditionals, expr.model.flagBucketCount) 202eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar} 203eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar 20459229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval Expr.conditionalFlags by lazyProp { expr : Expr -> 205d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar arrayListOf(FlagSet(expr.getRequirementFlagIndex(false)), 206d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar FlagSet(expr.getRequirementFlagIndex(true))) 207d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 208d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 20959229481aec5a284d322a2ca80dff836485feb0cYigit Boyarval LayoutBinder.requiredComponent by lazyProp { layoutBinder: LayoutBinder -> 210d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount val requiredFromBindings = layoutBinder. 21159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar bindingTargets. 21259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar flatMap { it.bindings }. 213d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount firstOrNull { it.bindingAdapterInstanceClass != null }?.bindingAdapterInstanceClass 214d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount val requiredFromInverse = layoutBinder. 215d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount bindingTargets. 216d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount flatMap { it.inverseBindings }. 217d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount firstOrNull { it.bindingAdapterInstanceClass != null }?.bindingAdapterInstanceClass 218d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount requiredFromBindings ?: requiredFromInverse 219e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount} 220e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 221d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun Expr.getRequirementFlagSet(expected : Boolean) : FlagSet = conditionalFlags[if(expected) 1 else 0] 222d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 223d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.notEmpty(cb : (suffix : String, value : Long) -> Unit) { 224d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar buckets.withIndex().forEach { 225d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (it.value != 0L) { 226d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar cb(getWordSuffix(it.index), buckets[it.index]) 227d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 228d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 229d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 230d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 23159229481aec5a284d322a2ca80dff836485feb0cYigit Boyarfun getWordSuffix(wordIndex : Int) : String { 23259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar return if(wordIndex == 0) "" else "_$wordIndex" 233d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 234d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 235d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun FlagSet.localValue(bucketIndex : Int) = 23659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (localName == null) binaryCode(bucketIndex) 23759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar else "$localName${getWordSuffix(bucketIndex)}" 238d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 239d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyarfun FlagSet.binaryCode(bucketIndex : Int) = longToBinary(buckets[bucketIndex]) 240d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 241d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar 24259229481aec5a284d322a2ca80dff836485feb0cYigit Boyarfun longToBinary(l : Long) = "0x${java.lang.Long.toHexString(l)}L" 243d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 244d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun <T> FlagSet.mapOr(other : FlagSet, cb : (suffix : String, index : Int) -> T) : List<T> { 24559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val min = Math.min(buckets.size, other.buckets.size) 246d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val result = arrayListOf<T>() 247d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in 0..(min - 1)) { 248d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // if these two can match by any chance, call the callback 249d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (intersect(other, i)) { 250d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar result.add(cb(getWordSuffix(i), i)) 251d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 252d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 253d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return result 254d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 255d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 25696e1c821dd446d1ed78f8ae61131550588f60a24George Mountfun indexFromTag(tag : String) : kotlin.Int { 25796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val startIndex : kotlin.Int 2587ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount if (tag.startsWith("binding_")) { 25959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar startIndex = "binding_".length; 26096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 26196e1c821dd446d1ed78f8ae61131550588f60a24George Mount startIndex = tag.lastIndexOf('_') + 1 26296e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 26396e1c821dd446d1ed78f8ae61131550588f60a24George Mount return Integer.parseInt(tag.substring(startIndex)) 26496e1c821dd446d1ed78f8ae61131550588f60a24George Mount} 26596e1c821dd446d1ed78f8ae61131550588f60a24George Mount 26643596c2b2997e40b709627419732100d78a62ff0Yigit Boyarclass LayoutBinderWriter(val layoutBinder : LayoutBinder) { 26759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val model = layoutBinder.model 26834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount val indices = HashMap<BindingTarget, kotlin.Int>() 26959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val mDirtyFlags by lazy { 27059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val fs = FlagSet(BitSet(), model.flagBucketCount); 27143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar Arrays.fill(fs.buckets, -1) 27259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar fs.isDynamic = true 27343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar model.localizeFlag(fs, "mDirtyFlags") 27443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar fs 275d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 276d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 27759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val className = layoutBinder.implementationName 278d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 27959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val baseClassName = "${layoutBinder.className}" 280d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 28159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val includedBinders by lazy { 28259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.bindingTargets.filter { it.isBinder } 2837551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 2847551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 28559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val variables by lazy { 28659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar model.exprMap.values.filterIsInstance(IdentifierExpr::class.java).filter { it.isVariable() } 28743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 288d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 28959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val usedVariables by lazy { 29059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar variables.filter {it.isUsed } 2915bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 292d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 29396e1c821dd446d1ed78f8ae61131550588f60a24George Mount public fun write(minSdk : kotlin.Int) : String { 2945bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar layoutBinder.resolveWhichExpressionsAreUsed() 29534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount calculateIndices(); 29659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar return kcode("package ${layoutBinder.`package`};") { 29759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("import ${layoutBinder.modulePackage}.R;") 29859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("import ${layoutBinder.modulePackage}.BR;") 2995bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("import android.view.View;") 300dea555cf42dc3583604699c8c018d22681f56166George Mount val classDeclaration : String 301dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 30259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar classDeclaration = "$className extends $baseClassName" 303dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 30459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar classDeclaration = "$className extends android.databinding.ViewDataBinding" 305dea555cf42dc3583604699c8c018d22681f56166George Mount } 30659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public class $classDeclaration {") { 3074c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(declareIncludeViews()) 3085bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareViews()) 3095bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareVariables()) 31020c7182163d99575d382e065f5a5fe45ed6b87e2George Mount tab(declareBoundValues()) 311716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab(declareListeners()) 312d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount tab(declareInverseBindingImpls()); 31396e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab(declareConstructor(minSdk)) 3145bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareInvalidateAll()) 315447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab(declareHasPendingBindings()) 3165bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareSetVariable()) 3175bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(variableSettersAndGetters()) 3185bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(onFieldChange()) 3195bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 3204c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab(executePendingBindings()) 3215bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 322716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab(declareListenerImpls()) 3235bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(declareDirtyFlags()) 324dea555cf42dc3583604699c8c018d22681f56166George Mount if (!layoutBinder.hasVariations()) { 325dea555cf42dc3583604699c8c018d22681f56166George Mount tab(declareFactories()) 326dea555cf42dc3583604699c8c018d22681f56166George Mount } 3275bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 3285bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 3295bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab(flagMapping()) 3305bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("//end") 3315bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar }.generate() 3325bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 33334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount fun calculateIndices() : Unit { 33459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val taggedViews = layoutBinder.bindingTargets.filter{ 33559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.isUsed && it.tag != null && !it.isBinder 33634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 33796e1c821dd446d1ed78f8ae61131550588f60a24George Mount taggedViews.forEach { 33859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar indices.put(it, indexFromTag(it.tag)) 33996e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 34096e1c821dd446d1ed78f8ae61131550588f60a24George Mount val indexStart = maxIndex() + 1 34159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.bindingTargets.filter{ 34259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.isUsed && !taggedViews.contains(it) 34396e1c821dd446d1ed78f8ae61131550588f60a24George Mount }.withIndex().forEach { 34496e1c821dd446d1ed78f8ae61131550588f60a24George Mount indices.put(it.value, it.index + indexStart) 34534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 34634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 3474c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun declareIncludeViews() = kcode("") { 348239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount nl("private static final android.databinding.ViewDataBinding.IncludedLayouts sIncludes;") 3494c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("private static final android.util.SparseIntArray sViewsWithIds;") 3504c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("static {") { 35159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val hasBinders = layoutBinder.bindingTargets.firstOrNull{ it.isUsed && it.isBinder } != null 3524c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount if (!hasBinders) { 3534c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sIncludes = null;") 35400da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 35559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val numBindings = layoutBinder.bindingTargets.filter{ it.isUsed }.count() 35659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("sIncludes = new android.databinding.ViewDataBinding.IncludedLayouts($numBindings);") 35796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val includeMap = HashMap<BindingTarget, ArrayList<BindingTarget>>() 35859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.bindingTargets.filter{ it.isUsed && it.isBinder }.forEach { 35959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val includeTag = it.tag; 36059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val parent = layoutBinder.bindingTargets.firstOrNull { 36159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.isUsed && !it.isBinder && includeTag.equals(it.tag) 36259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar } ?: throw IllegalStateException("Could not find parent of include file") 36359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar var list = includeMap[parent] 36496e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (list == null) { 36596e1c821dd446d1ed78f8ae61131550588f60a24George Mount list = ArrayList<BindingTarget>() 36696e1c821dd446d1ed78f8ae61131550588f60a24George Mount includeMap.put(parent, list) 36796e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 36896e1c821dd446d1ed78f8ae61131550588f60a24George Mount list.add(it) 3694c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 37096e1c821dd446d1ed78f8ae61131550588f60a24George Mount 37159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar includeMap.keys.forEach { 37259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val index = indices[it] 37359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("sIncludes.setIncludes($index, ") { 374239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount tab ("new String[] {${ 37559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar includeMap[it]!!.map { 37659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar "\"${it.includedLayout}\"" 377239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount }.joinToString(", ") 378239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount }},") 379239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount tab("new int[] {${ 38059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar includeMap[it]!!.map { 38159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar "${indices[it]}" 382239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount }.joinToString(", ") 383239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount }},") 384239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount tab("new int[] {${ 38559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar includeMap[it]!!.map { 38659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar "R.layout.${it.includedLayout}" 387239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount }.joinToString(", ") 388239e15adad52d3a7d77852953a5dd7eee82f7f2cGeorge Mount }});") 38996e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 39096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 39196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 39259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val viewsWithIds = layoutBinder.bindingTargets.filter { 39359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.isUsed && !it.isBinder && (!it.supportsTag() || (it.id != null && it.tag == null)) 39400da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 39596e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (viewsWithIds.isEmpty()) { 3964c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = null;") 39700da715547ee7d5d38a3b8576090ca427a94daa5George Mount } else { 3984c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("sViewsWithIds = new android.util.SparseIntArray();") 39996e1c821dd446d1ed78f8ae61131550588f60a24George Mount viewsWithIds.forEach { 40059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("sViewsWithIds.put(${it.androidId}, ${indices[it]});") 4014c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 40200da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 4034c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 4044c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("}") 4054c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 40696e1c821dd446d1ed78f8ae61131550588f60a24George Mount 40796e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun maxIndex() : kotlin.Int { 40859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val maxIndex = indices.values.max() 40996e1c821dd446d1ed78f8ae61131550588f60a24George Mount if (maxIndex == null) { 41096e1c821dd446d1ed78f8ae61131550588f60a24George Mount return -1 41196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 41296e1c821dd446d1ed78f8ae61131550588f60a24George Mount return maxIndex 41396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 41496e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 41596e1c821dd446d1ed78f8ae61131550588f60a24George Mount 41696e1c821dd446d1ed78f8ae61131550588f60a24George Mount fun declareConstructor(minSdk : kotlin.Int) = kcode("") { 41796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val bindingCount = maxIndex() + 1 41896e1c821dd446d1ed78f8ae61131550588f60a24George Mount val parameterType : String 41996e1c821dd446d1ed78f8ae61131550588f60a24George Mount val superParam : String 42059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (layoutBinder.isMerge) { 42196e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View[]" 42296e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root[0]" 42396e1c821dd446d1ed78f8ae61131550588f60a24George Mount } else { 42496e1c821dd446d1ed78f8ae61131550588f60a24George Mount parameterType = "View" 42596e1c821dd446d1ed78f8ae61131550588f60a24George Mount superParam = "root" 42696e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 42796e1c821dd446d1ed78f8ae61131550588f60a24George Mount val rootTagsSupported = minSdk >= 14 428dea555cf42dc3583604699c8c018d22681f56166George Mount if (layoutBinder.hasVariations()) { 429dea555cf42dc3583604699c8c018d22681f56166George Mount nl("") 43059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public $className(android.databinding.DataBindingComponent bindingComponent, $parameterType root) {") { 43159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("this(bindingComponent, $superParam, mapBindings(bindingComponent, root, $bindingCount, sIncludes, sViewsWithIds));") 432dea555cf42dc3583604699c8c018d22681f56166George Mount } 433dea555cf42dc3583604699c8c018d22681f56166George Mount nl("}") 43459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("private $className(android.databinding.DataBindingComponent bindingComponent, $parameterType root, Object[] bindings) {") { 43559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("super(bindingComponent, $superParam, ${model.observables.size}") { 43659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.sortedTargets.filter { it.id != null }.forEach { 437dea555cf42dc3583604699c8c018d22681f56166George Mount tab(", ${fieldConversion(it)}") 43834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 439dea555cf42dc3583604699c8c018d22681f56166George Mount tab(");") 44034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 44134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 442dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 44359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public $baseClassName(android.databinding.DataBindingComponent bindingComponent, $parameterType root) {") { 44459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("super(bindingComponent, $superParam, ${model.observables.size});") 44559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("final Object[] bindings = mapBindings(bindingComponent, root, $bindingCount, sIncludes, sViewsWithIds);") 446dea555cf42dc3583604699c8c018d22681f56166George Mount } 447dea555cf42dc3583604699c8c018d22681f56166George Mount } 448e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount if (layoutBinder.requiredComponent != null) { 449e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("ensureBindingComponentIsNotNull(${layoutBinder.requiredComponent}.class);") 450e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 45159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val taggedViews = layoutBinder.sortedTargets.filter{it.isUsed } 452dea555cf42dc3583604699c8c018d22681f56166George Mount taggedViews.forEach { 45359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (!layoutBinder.hasVariations() || it.id == null) { 454dea555cf42dc3583604699c8c018d22681f56166George Mount tab("this.${it.fieldName} = ${fieldConversion(it)};") 455dea555cf42dc3583604699c8c018d22681f56166George Mount } 45659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (!it.isBinder) { 45759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (it.resolvedType != null && it.resolvedType.extendsViewStub()) { 458de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("this.${it.fieldName}.setContainingBinding(this);") 459de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 46059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (it.supportsTag() && it.tag != null && 46159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar (rootTagsSupported || it.tag.startsWith("binding_"))) { 46259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val originalTag = it.originalTag; 463dea555cf42dc3583604699c8c018d22681f56166George Mount var tagValue = "null" 46492a428505b9102bc0560d2d5be1768da097909c2George Mount if (originalTag != null && !originalTag.startsWith("@{")) { 46559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tagValue = "\"$originalTag\"" 466dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@")) { 46759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar var packageName = layoutBinder.modulePackage 468dea555cf42dc3583604699c8c018d22681f56166George Mount if (originalTag.startsWith("@android:")) { 469dea555cf42dc3583604699c8c018d22681f56166George Mount packageName = "android" 47000da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 471dea555cf42dc3583604699c8c018d22681f56166George Mount val slashIndex = originalTag.indexOf('/') 472dea555cf42dc3583604699c8c018d22681f56166George Mount val resourceId = originalTag.substring(slashIndex + 1) 47359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tagValue = "root.getResources().getString($packageName.R.string.$resourceId)" 47400da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 47500da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 47659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("this.${it.fieldName}.setTag($tagValue);") 47759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar } else if (it.tag != null && !it.tag.startsWith("binding_") && 47859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.originalTag != null) { 47959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar L.e(ErrorMessages.ROOT_TAG_NOT_SUPPORTED, it.originalTag) 4807551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 481d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 482d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 4834d4979490e1fa374c0d7f3599fed0a9e83a579d0George Mount tab("setRootTag(root);") 484dea555cf42dc3583604699c8c018d22681f56166George Mount tab("invalidateAll();"); 4850fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 486d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 487d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 488dea555cf42dc3583604699c8c018d22681f56166George Mount fun fieldConversion(target : BindingTarget) : String { 48959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (!target.isUsed) { 490dea555cf42dc3583604699c8c018d22681f56166George Mount return "null" 491dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 49259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val index = indices[target] ?: throw IllegalStateException("Unknown binding target") 49359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val variableName = "bindings[$index]" 494dea555cf42dc3583604699c8c018d22681f56166George Mount return target.superConversion(variableName) 495dea555cf42dc3583604699c8c018d22681f56166George Mount } 496dea555cf42dc3583604699c8c018d22681f56166George Mount } 497dea555cf42dc3583604699c8c018d22681f56166George Mount 498d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareInvalidateAll() = kcode("") { 4997551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("@Override") 5007551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar nl("public void invalidateAll() {") { 50159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val fs = FlagSet(layoutBinder.model.invalidateAnyBitSet, 50259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.model.flagBucketCount); 5031c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 50459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar for (i in (0..(mDirtyFlags.buckets.size - 1))) { 5051c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.localValue(i)} = ${fs.localValue(i)};") 5061c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 5071c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 50859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar includedBinders.filter{it.isUsed }.forEach { binder -> 5097551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar tab("${binder.fieldName}.invalidateAll();") 5107551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 5112f64c44e4fa296cf658ca986c095eab62f82a31dYigit Boyar tab("requestRebind();"); 512d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 5130fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 514d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 515d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 516447971abca811b11b8c1d8e7bfaa294856d03c16George Mount fun declareHasPendingBindings() = kcode("") { 517447971abca811b11b8c1d8e7bfaa294856d03c16George Mount nl("@Override") 518447971abca811b11b8c1d8e7bfaa294856d03c16George Mount nl("public boolean hasPendingBindings() {") { 51959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (mDirtyFlags.buckets.size > 0) { 520447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("synchronized(this) {") { 52159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val flagCheck = 0.rangeTo(mDirtyFlags.buckets.size - 1).map { 522447971abca811b11b8c1d8e7bfaa294856d03c16George Mount "${mDirtyFlags.localValue(it)} != 0" 523447971abca811b11b8c1d8e7bfaa294856d03c16George Mount }.joinToString(" || ") 52459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("if ($flagCheck) {") { 525447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("return true;") 526447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 527447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("}") 528447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 529447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("}") 530447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 53159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar includedBinders.filter{it.isUsed }.forEach { binder -> 532447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("if (${binder.fieldName}.hasPendingBindings()) {") { 533447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("return true;") 534447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 535447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("}") 536447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 537447971abca811b11b8c1d8e7bfaa294856d03c16George Mount tab("return false;") 538447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 539447971abca811b11b8c1d8e7bfaa294856d03c16George Mount nl("}") 540447971abca811b11b8c1d8e7bfaa294856d03c16George Mount } 541447971abca811b11b8c1d8e7bfaa294856d03c16George Mount 542d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareSetVariable() = kcode("") { 5430fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("public boolean setVariable(int variableId, Object variable) {") { 544d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch(variableId) {") { 5455bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 54659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab ("case ${it.name.br()} :") { 54759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("${it.setterName}((${it.resolvedType.toJavaCode()}) variable);") 548d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 549d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 550d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 55159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val declaredOnly = variables.filter { !it.isUsed && it.isDeclared }; 55223910cf498c35704a03ba4f3889de2ab97ccbe21George Mount declaredOnly.forEachIndexed { i, identifierExpr -> 55359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab ("case ${identifierExpr.name.br()} :") { 55459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (i == declaredOnly.size - 1) { 55523910cf498c35704a03ba4f3889de2ab97ccbe21George Mount tab("return true;") 55623910cf498c35704a03ba4f3889de2ab97ccbe21George Mount } 55723910cf498c35704a03ba4f3889de2ab97ccbe21George Mount } 55823910cf498c35704a03ba4f3889de2ab97ccbe21George Mount } 559d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 560d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 561d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 562d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 5630fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 564d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 565d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 566d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun variableSettersAndGetters() = kcode("") { 56759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar variables.filterNot{it.isUsed }.forEach { 56859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public void ${it.setterName}(${it.resolvedType.toJavaCode()} ${it.readableName}) {") { 5695bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar tab("// not used, ignore") 5705bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5715bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 5725bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("") 57359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public ${it.resolvedType.toJavaCode()} ${it.getterName}() {") { 57459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("return ${it.defaultValue};") 5755bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5765bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar nl("}") 5775bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 5785bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 57959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (it.userDefinedType != null) { 58059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public void ${it.setterName}(${it.resolvedType.toJavaCode()} ${it.readableName}) {") { 58159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (it.isObservable) { 58259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("updateRegistration(${it.id}, ${it.readableName});"); 58318243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 584019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("this.${it.fieldName} = ${it.readableName};") 58518243f6f1b7527272ef4feccdf4327d80d9f2241George Mount // set dirty flags! 58618243f6f1b7527272ef4feccdf4327d80d9f2241George Mount val flagSet = it.invalidateFlagSet 5871c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 5881c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 58959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("${mDirtyFlags.localName}$suffix |= ${flagSet.localValue(index)};") 5901c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 5911c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab ("}") 592d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount // TODO: Remove this condition after releasing version 1.1 of SDK 593d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (ModelAnalyzer.getInstance().findClass("android.databinding.ViewDataBinding", null).isObservable) { 594d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount tab("notifyPropertyChanged(${it.name.br()});") 595d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 59618243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("super.requestRebind();") 597d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 59818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 59918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("") 60059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public ${it.resolvedType.toJavaCode()} ${it.getterName}() {") { 60118243f6f1b7527272ef4feccdf4327d80d9f2241George Mount tab("return ${it.fieldName};") 602d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 60318243f6f1b7527272ef4feccdf4327d80d9f2241George Mount nl("}") 604d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 605d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 606d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 607d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 608d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun onFieldChange() = kcode("") { 60934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("@Override") 61034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {") { 6114c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("switch (localFieldId) {") { 61259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar model.observables.forEach { 61359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("case ${it.id} :") { 61459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("return ${it.onChangeName}((${it.resolvedType.toJavaCode()}) object, fieldId);") 615d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 616d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 617d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 618d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 619d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 620d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 62134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 62234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 623d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 62459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar model.observables.forEach { 62559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("private boolean ${it.onChangeName}(${it.resolvedType.toJavaCode()} ${it.readableName}, int fieldId) {") { 626d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("switch (fieldId) {", { 62759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val accessedFields: List<FieldAccessExpr> = it.parents.filterIsInstance(FieldAccessExpr::class.java) 628c4a07bddb4dd5c3bfbecf4d87909c5b447ae56dcGeorge Mount accessedFields.filter { it.hasBindableAnnotations() } 62988ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar .groupBy { it.brName } 630d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .forEach { 63188ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar // If two expressions look different but resolve to the same method, 63288ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar // we are not yet able to merge them. This is why we merge their 63388ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar // flags below. 63488ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar tab("case ${it.key}:") { 6351c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 63688ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar val flagSet = it.value.foldRight(FlagSet()) { l, r -> l.invalidateFlagSet.or(r) } 63788ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar 63888ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 63988ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar tab("${mDirtyFlags.localValue(index)} |= ${flagSet.localValue(index)};") 6401c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 6411c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 642d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 643d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 644d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 645d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 64643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar tab("case ${"".br()}:") { 647d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val flagSet = it.invalidateFlagSet 6481c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 6491c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar mDirtyFlags.mapOr(flagSet) { suffix, index -> 65059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("${mDirtyFlags.localName}$suffix |= ${flagSet.localValue(index)};") 6511c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 6521c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 653d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return true;") 654d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 655d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 656d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }) 657d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("}") 658d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("return false;") 659d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 66034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("}") 66134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 662d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 663d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 664d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 665d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareViews() = kcode("// views") { 666dea555cf42dc3583604699c8c018d22681f56166George Mount val oneLayout = !layoutBinder.hasVariations(); 66759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.sortedTargets.filter {it.isUsed && (oneLayout || it.id == null)}.forEach { 668dea555cf42dc3583604699c8c018d22681f56166George Mount val access : String 66959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (oneLayout && it.id != null) { 670dea555cf42dc3583604699c8c018d22681f56166George Mount access = "public" 671dea555cf42dc3583604699c8c018d22681f56166George Mount } else { 672dea555cf42dc3583604699c8c018d22681f56166George Mount access = "private" 673dea555cf42dc3583604699c8c018d22681f56166George Mount } 67459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("$access final ${it.interfaceClass} ${it.fieldName};") 675d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 676d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 677d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 678d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareVariables() = kcode("// variables") { 6795bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar usedVariables.forEach { 68059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("private ${it.resolvedType.toJavaCode()} ${it.fieldName};") 681d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 682d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 683d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 68420c7182163d99575d382e065f5a5fe45ed6b87e2George Mount fun declareBoundValues() = kcode("// values") { 68559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.sortedTargets.filter { it.isUsed } 68659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar .flatMap { it.bindings } 68720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .filter { it.requiresOldValue() } 68859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar .flatMap{ it.componentExpressions.toArrayList() } 68920c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .groupBy { it } 69020c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .forEach { 69159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val expr = it.key 69259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("private ${expr.resolvedType.toJavaCode()} ${expr.oldValueName};") 69320c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 69420c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 69520c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 696716ba89e7f459f49ea85070d4710c1d79d715298George Mount fun declareListeners() = kcode("// listeners") { 69759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar model.exprMap.values.filter { 698793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount it is ListenerExpr 699716ba89e7f459f49ea85070d4710c1d79d715298George Mount }.groupBy { it }.forEach { 700793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount val expr = it.key as ListenerExpr 701716ba89e7f459f49ea85070d4710c1d79d715298George Mount nl("private ${expr.listenerClassName} ${expr.fieldName};") 702716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 703716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 704716ba89e7f459f49ea85070d4710c1d79d715298George Mount 705d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount fun declareInverseBindingImpls() = kcode("// Inverse Binding Event Handlers") { 706af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar layoutBinder.sortedTargets.filter { it.isUsed }.forEach { target -> 707af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar target.inverseBindings.forEach { inverseBinding -> 708d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount val className : String 709d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount val param : String 710af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar if (inverseBinding.isOnBinder) { 711d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount className = "android.databinding.ViewDataBinding.PropertyChangedInverseListener" 712d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount param = "BR.${inverseBinding.eventAttribute}" 713d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } else { 714d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount className = "android.databinding.InverseBindingListener" 715d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount param = "" 716d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 717af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar nl("private $className ${inverseBinding.fieldName} = new $className($param) {") { 718d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount tab("@Override") 719d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount tab("public void onChange() {") { 720d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount tab(inverseBinding.toJavaCode("mBindingComponent", mDirtyFlags)).app(";"); 721d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 722d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount tab("}") 723d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 724d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount nl("};") 725d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 726d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 727d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 728d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun declareDirtyFlags() = kcode("// dirty flag") { 729d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.ext.localizedFlags.forEach { flag -> 730de38dd3ef0577d25b2d59863603abe5750d0c231George Mount flag.notEmpty { suffix, value -> 7310fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("private") 73259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar app(" ", if(flag.isDynamic) null else "static final"); 73359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar app(" ", " ${flag.type} ${flag.localName}$suffix = ${longToBinary(value)};") 734d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 735d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 736d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 737d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 738d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun flagMapping() = kcode("/* flag mapping") { 73959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (model.flagMapping != null) { 74059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val mapping = model.flagMapping 741d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (i in mapping.indices) { 742d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar tab("flag $i: ${mapping[i]}") 743d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 744d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 745d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nl("flag mapping end*/") 746d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 747d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 7484c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount fun executePendingBindings() = kcode("") { 7490fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("@Override") 750e725f0d81e1b07e88f819be9a82181eeeb680dbfGeorge Mount nl("protected void executeBindings() {") { 751d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val tmpDirtyFlags = FlagSet(mDirtyFlags.buckets) 75259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tmpDirtyFlags.localName = "dirtyFlags"; 75359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar for (i in (0..mDirtyFlags.buckets.size - 1)) { 7541c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${tmpDirtyFlags.type} ${tmpDirtyFlags.localValue(i)} = 0;") 755d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7561c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("synchronized(this) {") { 75759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar for (i in (0..mDirtyFlags.buckets.size - 1)) { 7581c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${tmpDirtyFlags.localValue(i)} = ${mDirtyFlags.localValue(i)};") 7591c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar tab("${mDirtyFlags.localValue(i)} = 0;") 7601c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } 7611c44adacab2c1baa937a604da136024f1e92a088Yigit Boyar } tab("}") 76259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar model.pendingExpressions.filter { it.needsLocalField }.forEach { 76359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("${it.resolvedType.toJavaCode()} ${it.executePendingLocalName} = ${if (it.isVariable()) it.fieldName else it.defaultValue};") 764d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 765b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("writing executePendingBindings for %s", className) 766d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar do { 76759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val batch = ExprModel.filterShouldRead(model.pendingExpressions).toArrayList() 768a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val justRead = arrayListOf<Expr>() 769b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar L.d("batch: %s", batch) 770d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar while (!batch.none()) { 771a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val readNow = batch.filter { it.shouldReadNow(justRead) } 772d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (readNow.isEmpty()) { 773d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar throw IllegalStateException("do not know what I can read. bailing out ${batch.joinToString("\n")}") 774d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 77559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar L.d("new read now. batch size: %d, readNow size: %d", batch.size, readNow.size) 776a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount nl(readWithDependants(readNow, justRead, batch, tmpDirtyFlags)) 777a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount batch.removeAll(justRead) 778d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 7790fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar tab("// batch finished") 780a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } while (model.markBitsRead()) 7817b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar // verify everything is read. 78259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val batch = ExprModel.filterShouldRead(model.pendingExpressions).toArrayList() 7837b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar if (batch.isNotEmpty()) { 7847b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar L.e("could not generate code for %s. This might be caused by circular dependencies." 78559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar + "Please report on b.android.com. %d %s %s", layoutBinder.layoutname, 78659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar batch.size, batch[0], batch[0].toCode().generate()) 7877b07818f07c28c6dec34ca2a9ab5f61e86afb493Yigit Boyar } 788d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar // 78959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.sortedTargets.filter { it.isUsed } 79059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar .flatMap { it.bindings } 791a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount .groupBy { 79259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar "${tmpDirtyFlags.mapOr(it.expr.dirtyFlagSet) { suffix, index -> 79359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${it.expr.dirtyFlagSet.localValue(index)}) != 0" 794a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount }.joinToString(" || ") }" 795a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount }.forEach { 796a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount tab("if (${it.key}) {") { 79759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.value.groupBy { Math.max(1, it.minApi) }.forEach { 798a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val setterValues = kcode("") { 799d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.value.forEach { binding -> 800a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val fieldName: String 80159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (binding.target.viewClass. 80259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar equals(binding.target.interfaceType)) { 80359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar fieldName = "this.${binding.target.fieldName}" 80434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } else { 80559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar fieldName = "((${binding.target.viewClass}) this.${binding.target.fieldName})" 80634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 807a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount tab(binding.toJavaCode(fieldName, "this.mBindingComponent")).app(";") 808a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 809a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 810a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount tab("// api target ${it.key}") 811a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount if (it.key > 1) { 812a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount tab("if(getBuildSdkInt() >= ${it.key}) {") { 813a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount app("", setterValues) 814d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 815a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount tab("}") 816a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } else { 817a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount app("", setterValues) 81820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 81920c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 820a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 821a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount tab("}") 822a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 823a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount 82420c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 82559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.sortedTargets.filter { it.isUsed } 82659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar .flatMap { it.bindings } 82720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount .filter { it.requiresOldValue() } 82859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar .groupBy {"${tmpDirtyFlags.mapOr(it.expr.dirtyFlagSet) { suffix, index -> 82959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${it.expr.dirtyFlagSet.localValue(index)}) != 0" 830a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount }.joinToString(" || ") 831a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount }"}.forEach { 832a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount tab("if (${it.key}) {") { 83359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.value.groupBy { it.expr }.map { it.value.first() }.forEach { 83459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.componentExpressions.forEach { expr -> 835a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount tab("this.${expr.oldValueName} = ${expr.toCode().generate()};") 836d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 837d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 838a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 839a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount tab("}") 840a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 84159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar includedBinders.filter{it.isUsed }.forEach { binder -> 8424c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("${binder.fieldName}.executePendingBindings();") 8437551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 84459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.sortedTargets.filter{ 84559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.isUsed && it.resolvedType != null && it.resolvedType.extendsViewStub() 846de38dd3ef0577d25b2d59863603abe5750d0c231George Mount }.forEach { 847de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("if (${it.fieldName}.getBinding() != null) {") { 848de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("${it.fieldName}.getBinding().executePendingBindings();") 849de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 850de38dd3ef0577d25b2d59863603abe5750d0c231George Mount tab("}") 851de38dd3ef0577d25b2d59863603abe5750d0c231George Mount } 852d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 8530fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar nl("}") 854d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 855d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 856a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount fun readWithDependants(expressionList: List<Expr>, justRead: MutableList<Expr>, 857a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount batch: MutableList<Expr>, tmpDirtyFlags: FlagSet, 858a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount inheritedFlags: FlagSet? = null) : KCode = kcode("") { 859a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount expressionList.groupBy { it.shouldReadFlagSet }.forEach { 860a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val flagSet = it.key 861a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val needsIfWrapper = inheritedFlags == null || !flagSet.bitsEqual(inheritedFlags) 862a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val expressions = it.value 863a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val ifClause = "if (${tmpDirtyFlags.mapOr(flagSet){ suffix, index -> 864a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount "(${tmpDirtyFlags.localValue(index)} & ${flagSet.localValue(index)}) != 0" 865a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount }.joinToString(" || ") 866a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount })" 867a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val readCode = kcode("") { 868a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val dependants = ArrayList<Expr>() 869a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount expressions.groupBy { condition(it) }.forEach { 870a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val condition = it.key 8710b6d118e6eeb3bc100fc6a6e66016ab812cb2783Yigit Boyar val assignedValues = it.value.filter { it.needsLocalField && !it.isVariable() } 872a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount if (!assignedValues.isEmpty()) { 873a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val assignment = kcode("") { 874a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount assignedValues.forEach { expr: Expr -> 87559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("// read ${expr.uniqueKey}") 876a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount tab("${expr.executePendingLocalName}").app(" = ", expr.toFullCode()).app(";") 877a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 878a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 879a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount if (condition != null) { 88059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("if ($condition) {") { 881a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount app("", assignment) 882a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 883a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount tab ("}") 884a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } else { 885a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount app("", assignment) 886d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 88759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.value.filter { it.isObservable }.forEach { expr: Expr -> 88859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("updateRegistration(${expr.id}, ${expr.executePendingLocalName});") 8899e7a4ce47ae5f4428f7630fe03a7ad66d06177fbGeorge Mount } 890a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 891a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount 892a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount it.value.forEach { expr: Expr -> 893a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount justRead.add(expr) 89459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar L.d("%s / readWithDependants %s", className, expr.uniqueKey); 895a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount L.d("flag set:%s . inherited flags: %s. need another if: %s", flagSet, inheritedFlags, needsIfWrapper); 896a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount 897a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount // if I am the condition for an expression, set its flag 89859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar expr.dependants.filter { 89959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar !it.isConditional && it.dependant is TernaryExpr && 90059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar (it.dependant as TernaryExpr).pred == expr 90159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar }.map { it.dependant }.groupBy { 902eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar // group by when those ternaries will be evaluated (e.g. don't set conditional flags for no reason) 90359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val ternaryBitSet = it.shouldReadFlagsWithConditionals 90459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val isBehindTernary = ternaryBitSet.nextSetBit(model.invalidateAnyFlagIndex) == -1 905eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar if (!isBehindTernary) { 906eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar val ternaryFlags = it.shouldReadWithConditionalsFlagSet 907eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar "if(${tmpDirtyFlags.mapOr(ternaryFlags){ suffix, index -> 908eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar "(${tmpDirtyFlags.localValue(index)} & ${ternaryFlags.localValue(index)}) != 0" 909eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar }.joinToString(" || ")}) {" 910eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } else { 911eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar // TODO if it is behind a ternary, we should set it when its predicate is elevated 912eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar // Normally, this would mean that there is another code path to re-read our current expression. 913eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar // Unfortunately, this may not be true due to the coverage detection in `expr#markAsReadIfDone`, this may never happen. 914eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar // for v1.0, we'll go with always setting it and suffering an unnecessary calculation for this edge case. 915eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar // we can solve this by listening to elevation events from the model. 916eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar "" 917a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 918eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar }.forEach { 919eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar val hasAnotherIf = it.key != "" 920eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar if (hasAnotherIf) { 921eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar tab(it.key) { 922eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar tab("if (${expr.executePendingLocalName}) {") { 923eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar it.value.forEach { 924eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar val set = it.getRequirementFlagSet(true) 925eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar mDirtyFlags.mapOr(set) { suffix, index -> 926eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 927eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } 928eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } 929eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } 930eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar tab("} else {") { 931eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar it.value.forEach { 932eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar val set = it.getRequirementFlagSet(false) 933eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar mDirtyFlags.mapOr(set) { suffix, index -> 934eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 935eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } 936eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } 937eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar }.tab("}") 938eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar }.app("}") 939eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } else { 940eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar tab("if (${expr.executePendingLocalName}) {") { 941eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar it.value.forEach { 942eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar val set = it.getRequirementFlagSet(true) 943eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar mDirtyFlags.mapOr(set) { suffix, index -> 944eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 945eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } 946a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 947a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 948eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar tab("} else {") { 949eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar it.value.forEach { 950eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar val set = it.getRequirementFlagSet(false) 951eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar mDirtyFlags.mapOr(set) { suffix, index -> 952eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar tab("${tmpDirtyFlags.localValue(index)} |= ${set.localValue(index)};") 953eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } 954eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } 955eebcbdd5d35e56a2c8ef37feeb65df46130d001dYigit Boyar } app("}") 956a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 957a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 95859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val chosen = expr.dependants.filter { 95959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val dependant = it.dependant 960a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount batch.contains(dependant) && 96159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar dependant.shouldReadFlagSet.andNot(flagSet).isEmpty && 962a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount dependant.shouldReadNow(justRead) 963a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 964a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount if (chosen.isNotEmpty()) { 96559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar dependants.addAll(chosen.map { it.dependant }) 9660fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 9670fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar } 968a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 969a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount if (dependants.isNotEmpty()) { 970a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount val nextInheritedFlags = if (needsIfWrapper) flagSet else inheritedFlags 971a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount nl(readWithDependants(dependants, justRead, batch, tmpDirtyFlags, nextInheritedFlags)) 972a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 973d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 9740fa158e8aa91297cc246e3bb9e5d1388dc2355ccYigit Boyar 975a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount if (needsIfWrapper) { 976a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount tab(ifClause) { 977a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount app(" {") 978a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount app("", readCode) 979d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 980a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount tab("}") 981a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } else { 982a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount app("", readCode) 983d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 984d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 985a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } 986a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount 987a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount fun condition(expr : Expr) : String? { 988a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount if (expr.canBeEvaluatedToAVariable() && !expr.isVariable()) { 989a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount // create an if case for all dependencies that might be null 99059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val nullables = expr.dependencies.filter { 99159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.isMandatory && it.other.resolvedType.isNullable 99259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar }.map { it.other } 99359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (!expr.isEqualityCheck && nullables.isNotEmpty()) { 994a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount return "${nullables.map { "${it.executePendingLocalName} != null" }.joinToString(" && ")}" 995a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount } else { 996a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount return null 997d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 998d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } else { 999a0820baa03e731f274ef55c5541e9fc101bbaddbGeorge Mount return null 1000d8c8ec27ed2ec0b11fa37f476395ce27834471f0Yigit Boyar } 1001d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 1002716ba89e7f459f49ea85070d4710c1d79d715298George Mount 1003716ba89e7f459f49ea85070d4710c1d79d715298George Mount fun declareListenerImpls() = kcode("// Listener Stub Implementations") { 100459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar model.exprMap.values.filter { 100559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar it.isUsed && it is ListenerExpr 1006716ba89e7f459f49ea85070d4710c1d79d715298George Mount }.groupBy { it }.forEach { 1007793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount val expr = it.key as ListenerExpr 100859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val listenerType = expr.resolvedType; 1009793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount val extendsImplements : String 101059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (listenerType.isInterface) { 1011793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount extendsImplements = "implements" 1012793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } else { 1013793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount extendsImplements = "extends" 1014793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } 101559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public static class ${expr.listenerClassName} $extendsImplements ${listenerType.canonicalName}{") { 101659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (expr.child.isDynamic) { 101759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("private ${expr.child.resolvedType.toJavaCode()} value;") 101859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public ${expr.listenerClassName} setValue(${expr.child.resolvedType.toJavaCode()} value) {") { 1019716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab("this.value = value;") 1020716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab("return value == null ? null : this;") 1021716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 1022716ba89e7f459f49ea85070d4710c1d79d715298George Mount tab("}") 1023716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 102459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val listenerMethod = expr.method 102559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val parameterTypes = listenerMethod.parameterTypes 1026793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount val returnType = listenerMethod.getReturnType(parameterTypes.toArrayList()) 1027793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount tab("@Override") 102859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public $returnType ${listenerMethod.name}(${ 1029716ba89e7f459f49ea85070d4710c1d79d715298George Mount parameterTypes.withIndex().map { 1030716ba89e7f459f49ea85070d4710c1d79d715298George Mount "${it.value.toJavaCode()} arg${it.index}" 1031716ba89e7f459f49ea85070d4710c1d79d715298George Mount }.joinToString(", ") 1032793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount }) {") { 1033793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount val obj : String 103459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (expr.child.isDynamic) { 1035793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount obj = "this.value" 1036793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } else { 103759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar obj = expr.child.toCode().generate(); 1038793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } 1039793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount val returnStr : String 104059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (!returnType.isVoid) { 1041793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount returnStr = "return " 1042793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } else { 1043793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount returnStr = "" 1044716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 1045793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount val args = parameterTypes.withIndex().map { 1046793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount "arg${it.index}" 1047793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount }.joinToString(", ") 104859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("$returnStr$obj.${expr.name}($args);") 1049716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 1050793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount tab("}") 1051716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 1052716ba89e7f459f49ea85070d4710c1d79d715298George Mount nl("}") 1053716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 1054716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 105543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 1056dea555cf42dc3583604699c8c018d22681f56166George Mount fun declareFactories() = kcode("") { 105759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot) {") { 1058e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return inflate(inflater, root, attachToRoot, android.databinding.DataBindingUtil.getDefaultComponent());") 1059e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1060e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount nl("}") 106159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot, android.databinding.DataBindingComponent bindingComponent) {") { 106259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("return android.databinding.DataBindingUtil.<$baseClassName>inflate(inflater, ${layoutBinder.modulePackage}.R.layout.${layoutBinder.layoutname}, root, attachToRoot, bindingComponent);") 1063081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount } 1064081ec223f1f2f801bd907ec6344b0c6aeee133e5George Mount nl("}") 106559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (!layoutBinder.isMerge) { 106659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public static $baseClassName inflate(android.view.LayoutInflater inflater) {") { 1067e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return inflate(inflater, android.databinding.DataBindingUtil.getDefaultComponent());") 1068e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1069e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount nl("}") 107059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.databinding.DataBindingComponent bindingComponent) {") { 107159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("return bind(inflater.inflate(${layoutBinder.modulePackage}.R.layout.${layoutBinder.layoutname}, null, false), bindingComponent);") 107296e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 107396e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 107459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public static $baseClassName bind(android.view.View view) {") { 1075e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return bind(view, android.databinding.DataBindingUtil.getDefaultComponent());") 1076e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1077e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount nl("}") 107859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public static $baseClassName bind(android.view.View view, android.databinding.DataBindingComponent bindingComponent) {") { 107959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("if (!\"${layoutBinder.tag}_0\".equals(view.getTag())) {") { 1080f80b08430f11515ff944f89006799f21545602b9George Mount tab("throw new RuntimeException(\"view tag isn't correct on view:\" + view.getTag());") 108196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 108296e1c821dd446d1ed78f8ae61131550588f60a24George Mount tab("}") 108359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("return new $baseClassName(bindingComponent, view);") 108496e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 108596e1c821dd446d1ed78f8ae61131550588f60a24George Mount nl("}") 1086dea555cf42dc3583604699c8c018d22681f56166George Mount } 1087dea555cf42dc3583604699c8c018d22681f56166George Mount } 1088dea555cf42dc3583604699c8c018d22681f56166George Mount 10898b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar /** 10908b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar * When called for a library compilation, we do not generate real implementations 10918b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar */ 10928b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar public fun writeBaseClass(forLibrary : Boolean) : String = 109359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar kcode("package ${layoutBinder.`package`};") { 1094fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.Bindable;") 1095fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.DataBindingUtil;") 1096fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount nl("import android.databinding.ViewDataBinding;") 109759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar nl("public abstract class $baseClassName extends ViewDataBinding {") 109859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.sortedTargets.filter{it.id != null}.forEach { 109959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public final ${it.interfaceClass} ${it.fieldName};") 110034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 110134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount nl("") 110259229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("protected $baseClassName(android.databinding.DataBindingComponent bindingComponent, android.view.View root_, int localFieldCount") { 110359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.sortedTargets.filter{it.id != null}.forEach { 110459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab(", ${it.interfaceClass} ${it.constructorParamName}") 110534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 110634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 110734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount tab(") {") { 1108e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("super(bindingComponent, root_, localFieldCount);") 110959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar layoutBinder.sortedTargets.filter{it.id != null}.forEach { 1110019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar tab("this.${it.fieldName} = ${it.constructorParamName};") 111134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 11124c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 11134c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 11144c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount nl("") 111543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar variables.forEach { 111659229481aec5a284d322a2ca80dff836485feb0cYigit Boyar if (it.userDefinedType != null) { 111759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar val type = ModelAnalyzer.getInstance().applyImports(it.userDefinedType, model.imports) 111859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public abstract void ${it.setterName}($type ${it.readableName});") 111918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 112043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 112159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot) {") { 1122e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return inflate(inflater, root, attachToRoot, android.databinding.DataBindingUtil.getDefaultComponent());") 1123e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1124e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("}") 112559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public static $baseClassName inflate(android.view.LayoutInflater inflater) {") { 1126e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return inflate(inflater, android.databinding.DataBindingUtil.getDefaultComponent());") 1127e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1128e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("}") 112959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public static $baseClassName bind(android.view.View view) {") { 11308b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar if (forLibrary) { 11318b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar tab("return null;") 11328b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar } else { 1133e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return bind(view, android.databinding.DataBindingUtil.getDefaultComponent());") 11348b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar } 113543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 11364c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 113759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot, android.databinding.DataBindingComponent bindingComponent) {") { 11388b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar if (forLibrary) { 11398b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar tab("return null;") 11408b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar } else { 114159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("return DataBindingUtil.<$baseClassName>inflate(inflater, ${layoutBinder.modulePackage}.R.layout.${layoutBinder.layoutname}, root, attachToRoot, bindingComponent);") 11428b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar } 11434c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 11444c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 114559229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.databinding.DataBindingComponent bindingComponent) {") { 1146e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount if (forLibrary) { 1147e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("return null;") 1148e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } else { 114959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("return DataBindingUtil.<$baseClassName>inflate(inflater, ${layoutBinder.modulePackage}.R.layout.${layoutBinder.layoutname}, null, false, bindingComponent);") 1150e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1151e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1152e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount tab("}") 115359229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("public static $baseClassName bind(android.view.View view, android.databinding.DataBindingComponent bindingComponent) {") { 11548b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar if (forLibrary) { 11558b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar tab("return null;") 11568b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar } else { 115759229481aec5a284d322a2ca80dff836485feb0cYigit Boyar tab("return ($baseClassName)bind(bindingComponent, view, ${layoutBinder.modulePackage}.R.layout.${layoutBinder.layoutname});") 11588b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar } 11594c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount } 11604c5cc009bcbcfb19e33fb19db5ec80f83f7b3326George Mount tab("}") 116143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar nl("}") 116243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar }.generate() 1163dea555cf42dc3583604699c8c018d22681f56166George Mount} 1164