1d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar/* 2d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Copyright (C) 2015 The Android Open Source Project 3d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * 4d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 5d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * you may not use this file except in compliance with the License. 6d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * You may obtain a copy of the License at 7d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * 8d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 9d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * 10d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Unless required by applicable law or agreed to in writing, software 11d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 12d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * See the License for the specific language governing permissions and 14d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * limitations under the License. 15d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar */ 16d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 17fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.tool; 18d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 19fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.Expr; 20fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ExprModel; 21d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mountimport android.databinding.tool.processing.ErrorMessages; 22731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyarimport android.databinding.tool.processing.Scope; 23731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyarimport android.databinding.tool.processing.scopes.LocationScopeProvider; 24fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelAnalyzer; 25fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelClass; 26731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyarimport android.databinding.tool.store.Location; 27fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.store.ResourceBundle; 28fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.store.SetterStore; 29d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mountimport android.databinding.tool.store.SetterStore.BindingGetterCall; 30e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarimport android.databinding.tool.util.L; 312611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyarimport android.databinding.tool.util.Preconditions; 32d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 33d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.ArrayList; 34e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarimport java.util.HashMap; 35d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.List; 36e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyarimport java.util.Map; 37d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 38731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyarpublic class BindingTarget implements LocationScopeProvider { 39895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar List<Binding> mBindings = new ArrayList<Binding>(); 40d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount List<InverseBinding> mInverseBindings = new ArrayList<InverseBinding>(); 41d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar ExprModel mModel; 4279fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount ModelClass mResolvedClass; 4334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount 445bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar // if this target presents itself in multiple layout files with different view types, 455bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar // it receives an interface type and should use it in the getter instead. 46d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount ResourceBundle.BindingTargetBundle mBundle; 473bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar 483bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar public BindingTarget(ResourceBundle.BindingTargetBundle bundle) { 493bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar mBundle = bundle; 505bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 515bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 525bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar public boolean isUsed() { 533bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar return mBundle.isUsed(); 54d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 55d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 56d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public void addBinding(String name, Expr expr) { 57d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (SetterStore.get(ModelAnalyzer.getInstance()).isTwoWayEventAttribute(name)) { 58d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount L.e(ErrorMessages.TWO_WAY_EVENT_ATTRIBUTE, name); 59d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 60d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mBindings.add(new Binding(this, name, expr)); 61d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (expr.isTwoWay()) { 62d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount try { 63d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount Scope.enter(expr); 64d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount expr.assertIsInvertible(); 65d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount final InverseBinding inverseBinding = new InverseBinding(this, name, expr); 66d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mInverseBindings.add(inverseBinding); 67d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mBindings.add(new Binding(this, inverseBinding.getEventAttribute(), 68d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mModel.twoWayListenerExpr(inverseBinding), 69d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount inverseBinding.getEventSetter())); 70d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } finally { 71d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount Scope.exit(); 72d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 73d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 74d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 75d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 765bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar public String getInterfaceType() { 773bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar return mBundle.getInterfaceType() == null ? mBundle.getFullClassName() : mBundle.getInterfaceType(); 78d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 79d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 80d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public InverseBinding addInverseBinding(String name, BindingGetterCall call) { 81d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount final InverseBinding inverseBinding = new InverseBinding(this, name, null); 82d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount inverseBinding.setGetterCall(call); 83d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mInverseBindings.add(inverseBinding); 84d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mBindings.add(new Binding(this, inverseBinding.getEventAttribute(), 85d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mModel.twoWayListenerExpr(inverseBinding))); 86d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return inverseBinding; 87d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 88d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 89731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar @Override 90731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar public List<Location> provideScopeLocation() { 91731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar return mBundle.provideScopeLocation(); 92731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar } 93731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar 94d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public String getId() { 953bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar return mBundle.getId(); 96d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 97d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 9800da715547ee7d5d38a3b8576090ca427a94daa5George Mount public String getTag() { 9900da715547ee7d5d38a3b8576090ca427a94daa5George Mount return mBundle.getTag(); 10000da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 10100da715547ee7d5d38a3b8576090ca427a94daa5George Mount 10200da715547ee7d5d38a3b8576090ca427a94daa5George Mount public String getOriginalTag() { 10300da715547ee7d5d38a3b8576090ca427a94daa5George Mount return mBundle.getOriginalTag(); 10400da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 10500da715547ee7d5d38a3b8576090ca427a94daa5George Mount 106d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public String getViewClass() { 1073bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar return mBundle.getFullClassName(); 108d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 109d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 11079fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount public ModelClass getResolvedType() { 111d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (mResolvedClass == null) { 112d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (mBundle.isBinder()) { 113d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mResolvedClass = ModelAnalyzer.getInstance(). 114d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount findClass(ModelAnalyzer.VIEW_DATA_BINDING, mModel.getImports()); 115d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } else { 116d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mResolvedClass = ModelAnalyzer.getInstance().findClass(mBundle.getFullClassName(), 117d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mModel.getImports()); 118d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 119d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 120d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return mResolvedClass; 121d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 122d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 1237551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar public String getIncludedLayout() { 1243bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar return mBundle.getIncludedLayout(); 1257551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 1267551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 1277551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar public boolean isBinder() { 1283bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar return getIncludedLayout() != null; 1297551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar } 1307551861a29997eac7eaf6318e4d9f1cebd8b81d6Yigit Boyar 13100da715547ee7d5d38a3b8576090ca427a94daa5George Mount public boolean supportsTag() { 13200da715547ee7d5d38a3b8576090ca427a94daa5George Mount return !SetterStore.get(ModelAnalyzer.getInstance()) 13300da715547ee7d5d38a3b8576090ca427a94daa5George Mount .isUntaggable(mBundle.getFullClassName()); 13400da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 13500da715547ee7d5d38a3b8576090ca427a94daa5George Mount 136d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public List<Binding> getBindings() { 137d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return mBindings; 138d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 139d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 140d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public List<InverseBinding> getInverseBindings() { 141d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return mInverseBindings; 142d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 143d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 144d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public ExprModel getModel() { 145d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return mModel; 146d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 147d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 148d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public void setModel(ExprModel model) { 149d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mModel = model; 150d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 151e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar 152975c05c00dae9193a636c4775df81d8665fc6749George Mount public void resolveListeners() { 153975c05c00dae9193a636c4775df81d8665fc6749George Mount for (Binding binding : mBindings) { 154975c05c00dae9193a636c4775df81d8665fc6749George Mount binding.resolveListeners(); 155975c05c00dae9193a636c4775df81d8665fc6749George Mount } 156975c05c00dae9193a636c4775df81d8665fc6749George Mount } 157975c05c00dae9193a636c4775df81d8665fc6749George Mount 158d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public void resolveTwoWayExpressions() { 159d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount for (Binding binding : mBindings) { 160d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount binding.resolveTwoWayExpressions(); 161d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 162d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 163d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 164e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar /** 165e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar * Called after BindingTarget is finalized. 166e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar * <p> 167e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar * We traverse all bindings and ask SetterStore to figure out if any can be combined. 168e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar * When N bindings are combined, they are demoted from being a binding expression and a new 169e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar * ArgList expression is added as the new binding expression that depends on others. 170e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar */ 171e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar public void resolveMultiSetters() { 172e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar L.d("resolving multi setters for %s", getId()); 173e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar final SetterStore setterStore = SetterStore.get(ModelAnalyzer.getInstance()); 174e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar final String[] attributes = new String[mBindings.size()]; 175e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar final ModelClass[] types = new ModelClass[mBindings.size()]; 176e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar for (int i = 0; i < mBindings.size(); i ++) { 177e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar Binding binding = mBindings.get(i); 178731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar try { 179731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar Scope.enter(binding); 180731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar attributes[i] = binding.getName(); 181731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar types[i] = binding.getExpr().getResolvedType(); 182731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar } finally { 183731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar Scope.exit(); 184731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar } 185e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar } 186e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar final List<SetterStore.MultiAttributeSetter> multiAttributeSetterCalls = setterStore 187e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar .getMultiAttributeSetterCalls(attributes, getResolvedType(), types); 188e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar if (multiAttributeSetterCalls.isEmpty()) { 189e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar return; 190e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar } 191e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar final Map<String, Binding> lookup = new HashMap<String, Binding>(); 192e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar for (Binding binding : mBindings) { 193e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar String name = binding.getName(); 194e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar if (name.startsWith("android:")) { 195e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar lookup.put(name, binding); 196e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar } else { 197e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar int ind = name.indexOf(":"); 198e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar if (ind == -1) { 199e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar lookup.put(name, binding); 200e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar } else { 201e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar lookup.put(name.substring(ind + 1), binding); 202e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar } 203e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar } 204e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar } 205e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar List<MergedBinding> mergeBindings = new ArrayList<MergedBinding>(); 206e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar for (final SetterStore.MultiAttributeSetter setter : multiAttributeSetterCalls) { 207e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar L.d("resolved %s", setter); 2089784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar final List<Binding> mergedBindings = new ArrayList<Binding>(); 2092611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar for (String attribute : setter.attributes) { 2102611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar Binding binding = lookup.get(attribute); 2112611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar Preconditions.checkNotNull(binding, "cannot find binding for %s", attribute); 2122611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar mergedBindings.add(binding); 2132611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar } 2142611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar 215e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar for (Binding binding : mergedBindings) { 216e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar binding.getExpr().setBindingExpression(false); 217e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar mBindings.remove(binding); 218e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar } 219e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar MergedBinding mergedBinding = new MergedBinding(getModel(), setter, this, 2202611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar mergedBindings); 221e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar mergeBindings.add(mergedBinding); 222e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar } 223e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar for (MergedBinding binding : mergeBindings) { 224e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar mBindings.add(binding); 225e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar } 226e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar } 227d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 228