13561e3e665698843b1c664385a842e779198960bGeorge Mount/* 23561e3e665698843b1c664385a842e779198960bGeorge Mount * Copyright (C) 2015 The Android Open Source Project 33561e3e665698843b1c664385a842e779198960bGeorge Mount * 43561e3e665698843b1c664385a842e779198960bGeorge Mount * Licensed under the Apache License, Version 2.0 (the "License"); 53561e3e665698843b1c664385a842e779198960bGeorge Mount * you may not use this file except in compliance with the License. 63561e3e665698843b1c664385a842e779198960bGeorge Mount * You may obtain a copy of the License at 73561e3e665698843b1c664385a842e779198960bGeorge Mount * 83561e3e665698843b1c664385a842e779198960bGeorge Mount * http://www.apache.org/licenses/LICENSE-2.0 93561e3e665698843b1c664385a842e779198960bGeorge Mount * 103561e3e665698843b1c664385a842e779198960bGeorge Mount * Unless required by applicable law or agreed to in writing, software 113561e3e665698843b1c664385a842e779198960bGeorge Mount * distributed under the License is distributed on an "AS IS" BASIS, 123561e3e665698843b1c664385a842e779198960bGeorge Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133561e3e665698843b1c664385a842e779198960bGeorge Mount * See the License for the specific language governing permissions and 143561e3e665698843b1c664385a842e779198960bGeorge Mount * limitations under the License. 153561e3e665698843b1c664385a842e779198960bGeorge Mount */ 16fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.tool.store; 1797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 18d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mountimport android.databinding.InverseBindingListener; 19fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelAnalyzer; 20fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelClass; 21fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelMethod; 22fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.util.GenerationalClassUtil; 23fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.util.L; 242611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyarimport android.databinding.tool.util.Preconditions; 254ba16229a40e9758db86d4fb1df5119fdcb8aa2aDeepanshu Guptaimport android.databinding.tool.util.StringUtils; 26fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount 273561e3e665698843b1c664385a842e779198960bGeorge Mountimport java.io.IOException; 283561e3e665698843b1c664385a842e779198960bGeorge Mountimport java.io.Serializable; 293561e3e665698843b1c664385a842e779198960bGeorge Mountimport java.util.ArrayList; 30a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport java.util.Arrays; 31cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mountimport java.util.Collections; 32cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mountimport java.util.Comparator; 333561e3e665698843b1c664385a842e779198960bGeorge Mountimport java.util.HashMap; 34a128d1c99ea98bb48c45d648906652e3d618d513George Mountimport java.util.HashSet; 35cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mountimport java.util.Iterator; 363561e3e665698843b1c664385a842e779198960bGeorge Mountimport java.util.List; 37a7e767e576adebcddf043ad34ccb8dd167f777b3George Mountimport java.util.Map; 383561e3e665698843b1c664385a842e779198960bGeorge Mountimport java.util.Set; 39cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mountimport java.util.TreeMap; 403561e3e665698843b1c664385a842e779198960bGeorge Mount 413561e3e665698843b1c664385a842e779198960bGeorge Mountimport javax.annotation.processing.ProcessingEnvironment; 423561e3e665698843b1c664385a842e779198960bGeorge Mountimport javax.lang.model.element.ExecutableElement; 43e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mountimport javax.lang.model.element.Modifier; 443561e3e665698843b1c664385a842e779198960bGeorge Mountimport javax.lang.model.element.TypeElement; 453561e3e665698843b1c664385a842e779198960bGeorge Mountimport javax.lang.model.element.VariableElement; 463561e3e665698843b1c664385a842e779198960bGeorge Mountimport javax.lang.model.type.ArrayType; 473561e3e665698843b1c664385a842e779198960bGeorge Mountimport javax.lang.model.type.DeclaredType; 48b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mountimport javax.lang.model.type.TypeKind; 493561e3e665698843b1c664385a842e779198960bGeorge Mountimport javax.lang.model.type.TypeMirror; 503561e3e665698843b1c664385a842e779198960bGeorge Mount 513561e3e665698843b1c664385a842e779198960bGeorge Mountpublic class SetterStore { 523561e3e665698843b1c664385a842e779198960bGeorge Mount private static SetterStore sStore; 533561e3e665698843b1c664385a842e779198960bGeorge Mount 54d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private final IntermediateV2 mStore; 5579fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount private final ModelAnalyzer mClassAnalyzer; 56a128d1c99ea98bb48c45d648906652e3d618d513George Mount private HashMap<String, List<String>> mInstanceAdapters; 57d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private final HashSet<String> mInverseEventAttributes = new HashSet<String>(); 583561e3e665698843b1c664385a842e779198960bGeorge Mount 59cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount private Comparator<MultiAttributeSetter> COMPARE_MULTI_ATTRIBUTE_SETTERS = 60cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount new Comparator<MultiAttributeSetter>() { 61cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount @Override 62cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount public int compare(MultiAttributeSetter o1, MultiAttributeSetter o2) { 63cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (o1.attributes.length != o2.attributes.length) { 64cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return o2.attributes.length - o1.attributes.length; 65cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 66716ba89e7f459f49ea85070d4710c1d79d715298George Mount ModelClass view1 = mClassAnalyzer.findClass(o1.mKey.viewType, null).erasure(); 67716ba89e7f459f49ea85070d4710c1d79d715298George Mount ModelClass view2 = mClassAnalyzer.findClass(o2.mKey.viewType, null).erasure(); 68cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (!view1.equals(view2)) { 69cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (view1.isAssignableFrom(view2)) { 70cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return 1; 71cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } else { 72cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return -1; 73cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 74cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 75cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (!o1.mKey.attributeIndices.keySet() 76cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount .equals(o2.mKey.attributeIndices.keySet())) { 77cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount // order by attribute name 78cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount Iterator<String> o1Keys = o1.mKey.attributeIndices.keySet().iterator(); 79cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount Iterator<String> o2Keys = o2.mKey.attributeIndices.keySet().iterator(); 80cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount while (o1Keys.hasNext()) { 81cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount String key1 = o1Keys.next(); 82cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount String key2 = o2Keys.next(); 83cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount int compare = key1.compareTo(key2); 84cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (compare != 0) { 85cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return compare; 86cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 87cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 882611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar Preconditions.check(false, 89cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount "The sets don't match! That means the keys shouldn't match also"); 90cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 91cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount // Same view type. Same attributes 92cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount for (String attribute : o1.mKey.attributeIndices.keySet()) { 93cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount final int index1 = o1.mKey.attributeIndices.get(attribute); 94cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount final int index2 = o2.mKey.attributeIndices.get(attribute); 95cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount ModelClass type1 = mClassAnalyzer 96cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount .findClass(o1.mKey.parameterTypes[index1], null); 97cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount ModelClass type2 = mClassAnalyzer 98cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount .findClass(o2.mKey.parameterTypes[index2], null); 99cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (type1.equals(type2)) { 100cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount continue; 101cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 102cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (o1.mCasts[index1] != null) { 103cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (o2.mCasts[index2] == null) { 104cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return 1; // o2 is better 105cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } else { 106cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount continue; // both are casts 107cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 108cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } else if (o2.mCasts[index2] != null) { 109cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return -1; // o1 is better 110cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 111cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (o1.mConverters[index1] != null) { 112cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (o2.mConverters[index2] == null) { 113cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return 1; // o2 is better 114cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } else { 115cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount continue; // both are conversions 116cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 117cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } else if (o2.mConverters[index2] != null) { 118cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return -1; // o1 is better 119cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 120cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 121cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (type1.isPrimitive()) { 122cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (type2.isPrimitive()) { 123cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount int type1ConversionLevel = ModelMethod 124cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount .getImplicitConversionLevel(type1); 125cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount int type2ConversionLevel = ModelMethod 126cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount .getImplicitConversionLevel(type2); 127cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return type2ConversionLevel - type1ConversionLevel; 128cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } else { 129cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount // type1 is primitive and has higher priority 130cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return -1; 131cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 132cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } else if (type2.isPrimitive()) { 133cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return 1; 134cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 135cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (type1.isAssignableFrom(type2)) { 136cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return 1; 137cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } else if (type2.isAssignableFrom(type1)) { 138cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return -1; 139cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 140cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 141cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount // hmmm... same view type, same attributes, same parameter types... ? 142cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return 0; 143cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 144cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount }; 145cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 146d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private SetterStore(ModelAnalyzer modelAnalyzer, IntermediateV2 store) { 14779fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount mClassAnalyzer = modelAnalyzer; 1484711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount mStore = store; 149d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount for (HashMap<AccessorKey, InverseDescription> adapter : mStore.inverseAdapters.values()) { 150d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount for (InverseDescription inverseDescription : adapter.values()) { 151d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mInverseEventAttributes.add(inverseDescription.event); 152d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 153d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 154d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount for (HashMap<String, InverseDescription> method : mStore.inverseMethods.values()) { 155d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount for (InverseDescription inverseDescription : method.values()) { 156d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mInverseEventAttributes.add(inverseDescription.event); 157d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 158d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1593561e3e665698843b1c664385a842e779198960bGeorge Mount } 1603561e3e665698843b1c664385a842e779198960bGeorge Mount 16179fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount public static SetterStore get(ModelAnalyzer modelAnalyzer) { 1623561e3e665698843b1c664385a842e779198960bGeorge Mount if (sStore == null) { 163e8609ca3a9e95cb730d74f8a6114bc2ae11b6a10Yigit Boyar sStore = load(modelAnalyzer); 1643561e3e665698843b1c664385a842e779198960bGeorge Mount } 1653561e3e665698843b1c664385a842e779198960bGeorge Mount return sStore; 1663561e3e665698843b1c664385a842e779198960bGeorge Mount } 1673561e3e665698843b1c664385a842e779198960bGeorge Mount 168e8609ca3a9e95cb730d74f8a6114bc2ae11b6a10Yigit Boyar private static SetterStore load(ModelAnalyzer modelAnalyzer) { 169d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount IntermediateV2 store = new IntermediateV2(); 170a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar List<Intermediate> previousStores = GenerationalClassUtil 171e8609ca3a9e95cb730d74f8a6114bc2ae11b6a10Yigit Boyar .loadObjects(GenerationalClassUtil.ExtensionFilter.SETTER_STORE); 172a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar for (Intermediate intermediate : previousStores) { 173a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar merge(store, intermediate); 1743561e3e665698843b1c664385a842e779198960bGeorge Mount } 17579fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount return new SetterStore(modelAnalyzer, store); 1763561e3e665698843b1c664385a842e779198960bGeorge Mount } 1773561e3e665698843b1c664385a842e779198960bGeorge Mount 1783561e3e665698843b1c664385a842e779198960bGeorge Mount public void addRenamedMethod(String attribute, String declaringClass, String method, 1793561e3e665698843b1c664385a842e779198960bGeorge Mount TypeElement declaredOn) { 1801331801c598a377a2c16e1aed8f975b728adc06eGeorge Mount attribute = stripNamespace(attribute); 1814711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount HashMap<String, MethodDescription> renamed = mStore.renamedMethods.get(attribute); 1823561e3e665698843b1c664385a842e779198960bGeorge Mount if (renamed == null) { 183895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar renamed = new HashMap<String, MethodDescription>(); 1844711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount mStore.renamedMethods.put(attribute, renamed); 1853561e3e665698843b1c664385a842e779198960bGeorge Mount } 186e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount MethodDescription methodDescription = new MethodDescription( 187e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount declaredOn.getQualifiedName().toString(), method); 188a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar L.d("STORE addmethod desc %s", methodDescription); 1893561e3e665698843b1c664385a842e779198960bGeorge Mount renamed.put(declaringClass, methodDescription); 1903561e3e665698843b1c664385a842e779198960bGeorge Mount } 1913561e3e665698843b1c664385a842e779198960bGeorge Mount 192d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public void addInverseMethod(String attribute, String event, String declaringClass, 193d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount String method, TypeElement declaredOn) { 194d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount attribute = stripNamespace(attribute); 195d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount event = stripNamespace(event); 196d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount HashMap<String, InverseDescription> inverseMethods = mStore.inverseMethods.get(attribute); 197d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (inverseMethods == null) { 198d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount inverseMethods = new HashMap<String, InverseDescription>(); 199d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mStore.inverseMethods.put(attribute, inverseMethods); 200d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 201d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount InverseDescription methodDescription = new InverseDescription( 202d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount declaredOn.getQualifiedName().toString(), method, event); 203d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount L.d("STORE addInverseMethod desc %s", methodDescription); 204d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount inverseMethods.put(declaringClass, methodDescription); 205d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 206d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 207b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount public void addBindingAdapter(ProcessingEnvironment processingEnv, String attribute, 208e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount ExecutableElement bindingMethod, boolean takesComponent) { 209cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount attribute = stripNamespace(attribute); 210a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar L.d("STORE addBindingAdapter %s %s", attribute, bindingMethod); 2114711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount HashMap<AccessorKey, MethodDescription> adapters = mStore.adapterMethods.get(attribute); 2123561e3e665698843b1c664385a842e779198960bGeorge Mount 2133561e3e665698843b1c664385a842e779198960bGeorge Mount if (adapters == null) { 214895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar adapters = new HashMap<AccessorKey, MethodDescription>(); 2154711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount mStore.adapterMethods.put(attribute, adapters); 2163561e3e665698843b1c664385a842e779198960bGeorge Mount } 2173561e3e665698843b1c664385a842e779198960bGeorge Mount List<? extends VariableElement> parameters = bindingMethod.getParameters(); 218e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount final int viewIndex = takesComponent ? 1 : 0; 219e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount TypeMirror viewType = eraseType(processingEnv, parameters.get(viewIndex).asType()); 220b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount String view = getQualifiedName(viewType); 221e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount TypeMirror parameterType = eraseType(processingEnv, parameters.get(viewIndex + 1).asType()); 222b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount String value = getQualifiedName(parameterType); 2233561e3e665698843b1c664385a842e779198960bGeorge Mount 2243561e3e665698843b1c664385a842e779198960bGeorge Mount AccessorKey key = new AccessorKey(view, value); 2253561e3e665698843b1c664385a842e779198960bGeorge Mount if (adapters.containsKey(key)) { 2263561e3e665698843b1c664385a842e779198960bGeorge Mount throw new IllegalArgumentException("Already exists!"); 2273561e3e665698843b1c664385a842e779198960bGeorge Mount } 2283561e3e665698843b1c664385a842e779198960bGeorge Mount 229e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount adapters.put(key, new MethodDescription(bindingMethod, 1, takesComponent)); 2303561e3e665698843b1c664385a842e779198960bGeorge Mount } 2313561e3e665698843b1c664385a842e779198960bGeorge Mount 232d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public void addInverseAdapter(ProcessingEnvironment processingEnv, String attribute, 233d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount String event, ExecutableElement bindingMethod, boolean takesComponent) { 234d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount attribute = stripNamespace(attribute); 235d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount event = stripNamespace(event); 236d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount L.d("STORE addInverseAdapter %s %s", attribute, bindingMethod); 237d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount HashMap<AccessorKey, InverseDescription> adapters = mStore.inverseAdapters.get(attribute); 238d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 239d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (adapters == null) { 240d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount adapters = new HashMap<AccessorKey, InverseDescription>(); 241d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mStore.inverseAdapters.put(attribute, adapters); 242d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 243d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount List<? extends VariableElement> parameters = bindingMethod.getParameters(); 244d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount final int viewIndex = takesComponent ? 1 : 0; 245d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount TypeMirror viewType = eraseType(processingEnv, parameters.get(viewIndex).asType()); 246d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount String view = getQualifiedName(viewType); 247d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount TypeMirror returnType = eraseType(processingEnv, bindingMethod.getReturnType()); 248d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount String value = getQualifiedName(returnType); 249d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 250d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount AccessorKey key = new AccessorKey(view, value); 251d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (adapters.containsKey(key)) { 252d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount throw new IllegalArgumentException("Already exists!"); 253d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 254d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 255d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount adapters.put(key, new InverseDescription(bindingMethod, event, takesComponent)); 256d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 257d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 258b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount private static TypeMirror eraseType(ProcessingEnvironment processingEnv, 259b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount TypeMirror typeMirror) { 260b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount if (hasTypeVar(typeMirror)) { 261b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount return processingEnv.getTypeUtils().erasure(typeMirror); 262b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } else { 263b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount return typeMirror; 264b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 265b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 266b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount 267b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount private static ModelClass eraseType(ModelClass modelClass) { 268b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount if (hasTypeVar(modelClass)) { 269b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount return modelClass.erasure(); 270b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } else { 271b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount return modelClass; 272b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 273b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 274b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount 275b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount private static boolean hasTypeVar(TypeMirror typeMirror) { 276b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount TypeKind kind = typeMirror.getKind(); 277b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount if (kind == TypeKind.TYPEVAR) { 278b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount return true; 279b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } else if (kind == TypeKind.ARRAY) { 280b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount return hasTypeVar(((ArrayType) typeMirror).getComponentType()); 281b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } else if (kind == TypeKind.DECLARED) { 282b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount DeclaredType declaredType = (DeclaredType) typeMirror; 283b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments(); 284b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount if (typeArguments == null || typeArguments.isEmpty()) { 285b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount return false; 286b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 287b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount for (TypeMirror arg : typeArguments) { 288b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount if (hasTypeVar(arg)) { 289b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount return true; 290b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 291b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 292b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount return false; 293b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } else { 294b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount return false; 295b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 296b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 297b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount 298b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount private static boolean hasTypeVar(ModelClass type) { 299b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount if (type.isTypeVar()) { 300b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount return true; 301b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } else if (type.isArray()) { 302b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount return hasTypeVar(type.getComponentType()); 303b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } else { 304b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount List<ModelClass> typeArguments = type.getTypeArguments(); 305b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount if (typeArguments == null) { 306b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount return false; 307b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 308b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount for (ModelClass arg : typeArguments) { 309b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount if (hasTypeVar(arg)) { 310b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount return true; 311b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 312b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 313b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount return false; 314b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 315b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 316b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount 317b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount public void addBindingAdapter(ProcessingEnvironment processingEnv, String[] attributes, 31896b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount ExecutableElement bindingMethod, boolean takesComponent, boolean requireAll) { 319cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount L.d("STORE add multi-value BindingAdapter %d %s", attributes.length, bindingMethod); 320b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount MultiValueAdapterKey key = new MultiValueAdapterKey(processingEnv, bindingMethod, 32196b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount attributes, takesComponent, requireAll); 32220c7182163d99575d382e065f5a5fe45ed6b87e2George Mount MethodDescription methodDescription = new MethodDescription(bindingMethod, 323e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount attributes.length, takesComponent); 324cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount mStore.multiValueAdapters.put(key, methodDescription); 325cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 326cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 327cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount private static String[] stripAttributes(String[] attributes) { 328cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount String[] strippedAttributes = new String[attributes.length]; 329cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount for (int i = 0; i < attributes.length; i++) { 330d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (attributes[i] != null) { 331d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount strippedAttributes[i] = stripNamespace(attributes[i]); 332d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 333cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 334cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return strippedAttributes; 335cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 336cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 33700da715547ee7d5d38a3b8576090ca427a94daa5George Mount public void addUntaggableTypes(String[] typeNames, TypeElement declaredOn) { 338a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar L.d("STORE addUntaggableTypes %s %s", Arrays.toString(typeNames), declaredOn); 33900da715547ee7d5d38a3b8576090ca427a94daa5George Mount String declaredType = declaredOn.getQualifiedName().toString(); 34000da715547ee7d5d38a3b8576090ca427a94daa5George Mount for (String type : typeNames) { 34100da715547ee7d5d38a3b8576090ca427a94daa5George Mount mStore.untaggableTypes.put(type, declaredType); 34200da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 34300da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 34400da715547ee7d5d38a3b8576090ca427a94daa5George Mount 3453561e3e665698843b1c664385a842e779198960bGeorge Mount private static String getQualifiedName(TypeMirror type) { 346bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount final TypeKind kind = type.getKind(); 347bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount if (kind == TypeKind.ARRAY) { 348e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount return getQualifiedName(((ArrayType) type).getComponentType()) + "[]"; 349bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount } else if (kind == TypeKind.DECLARED && isIncompleteType(type)) { 350bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount DeclaredType declaredType = (DeclaredType) type; 351bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount return declaredType.asElement().toString(); 352e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } else { 353e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount return type.toString(); 3543561e3e665698843b1c664385a842e779198960bGeorge Mount } 3553561e3e665698843b1c664385a842e779198960bGeorge Mount } 3563561e3e665698843b1c664385a842e779198960bGeorge Mount 357bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount private static boolean isIncompleteType(TypeMirror type) { 358bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount final TypeKind kind = type.getKind(); 359bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount if (kind == TypeKind.TYPEVAR || kind == TypeKind.WILDCARD) { 360bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount return true; 361bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount } else if (kind == TypeKind.DECLARED) { 362bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount DeclaredType declaredType = (DeclaredType) type; 363bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount List<? extends TypeMirror> typeArgs = declaredType.getTypeArguments(); 364bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount if (typeArgs == null) { 365bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount return false; 366bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount } 367bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount for (TypeMirror arg : typeArgs) { 368bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount if (isIncompleteType(arg)) { 369bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount return true; 370bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount } 371bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount } 372bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount } 373bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount return false; 374bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount } 375bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount 3763561e3e665698843b1c664385a842e779198960bGeorge Mount public void addConversionMethod(ExecutableElement conversionMethod) { 377a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar L.d("STORE addConversionMethod %s", conversionMethod); 3783561e3e665698843b1c664385a842e779198960bGeorge Mount List<? extends VariableElement> parameters = conversionMethod.getParameters(); 3793561e3e665698843b1c664385a842e779198960bGeorge Mount String fromType = getQualifiedName(parameters.get(0).asType()); 3803561e3e665698843b1c664385a842e779198960bGeorge Mount String toType = getQualifiedName(conversionMethod.getReturnType()); 381e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount MethodDescription methodDescription = new MethodDescription(conversionMethod, 1, false); 3824711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount HashMap<String, MethodDescription> convertTo = mStore.conversionMethods.get(fromType); 3833561e3e665698843b1c664385a842e779198960bGeorge Mount if (convertTo == null) { 384895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar convertTo = new HashMap<String, MethodDescription>(); 3854711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount mStore.conversionMethods.put(fromType, convertTo); 3863561e3e665698843b1c664385a842e779198960bGeorge Mount } 3873561e3e665698843b1c664385a842e779198960bGeorge Mount convertTo.put(toType, methodDescription); 3883561e3e665698843b1c664385a842e779198960bGeorge Mount } 3893561e3e665698843b1c664385a842e779198960bGeorge Mount 3903561e3e665698843b1c664385a842e779198960bGeorge Mount public void clear(Set<String> classes) { 391895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar ArrayList<AccessorKey> removedAccessorKeys = new ArrayList<AccessorKey>(); 3924711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount for (HashMap<AccessorKey, MethodDescription> adapters : mStore.adapterMethods.values()) { 3933561e3e665698843b1c664385a842e779198960bGeorge Mount for (AccessorKey key : adapters.keySet()) { 3943561e3e665698843b1c664385a842e779198960bGeorge Mount MethodDescription description = adapters.get(key); 3953561e3e665698843b1c664385a842e779198960bGeorge Mount if (classes.contains(description.type)) { 3963561e3e665698843b1c664385a842e779198960bGeorge Mount removedAccessorKeys.add(key); 3973561e3e665698843b1c664385a842e779198960bGeorge Mount } 3983561e3e665698843b1c664385a842e779198960bGeorge Mount } 39900da715547ee7d5d38a3b8576090ca427a94daa5George Mount removeFromMap(adapters, removedAccessorKeys); 4003561e3e665698843b1c664385a842e779198960bGeorge Mount } 4013561e3e665698843b1c664385a842e779198960bGeorge Mount 402895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar ArrayList<String> removedRenamed = new ArrayList<String>(); 4034711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount for (HashMap<String, MethodDescription> renamed : mStore.renamedMethods.values()) { 4043561e3e665698843b1c664385a842e779198960bGeorge Mount for (String key : renamed.keySet()) { 4053561e3e665698843b1c664385a842e779198960bGeorge Mount if (classes.contains(renamed.get(key).type)) { 4063561e3e665698843b1c664385a842e779198960bGeorge Mount removedRenamed.add(key); 4073561e3e665698843b1c664385a842e779198960bGeorge Mount } 4083561e3e665698843b1c664385a842e779198960bGeorge Mount } 40900da715547ee7d5d38a3b8576090ca427a94daa5George Mount removeFromMap(renamed, removedRenamed); 4103561e3e665698843b1c664385a842e779198960bGeorge Mount } 4113561e3e665698843b1c664385a842e779198960bGeorge Mount 412895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar ArrayList<String> removedConversions = new ArrayList<String>(); 4134711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount for (HashMap<String, MethodDescription> convertTos : mStore.conversionMethods.values()) { 4143561e3e665698843b1c664385a842e779198960bGeorge Mount for (String toType : convertTos.keySet()) { 4153561e3e665698843b1c664385a842e779198960bGeorge Mount MethodDescription methodDescription = convertTos.get(toType); 4163561e3e665698843b1c664385a842e779198960bGeorge Mount if (classes.contains(methodDescription.type)) { 4173561e3e665698843b1c664385a842e779198960bGeorge Mount removedConversions.add(toType); 4183561e3e665698843b1c664385a842e779198960bGeorge Mount } 4193561e3e665698843b1c664385a842e779198960bGeorge Mount } 42000da715547ee7d5d38a3b8576090ca427a94daa5George Mount removeFromMap(convertTos, removedConversions); 42100da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 42200da715547ee7d5d38a3b8576090ca427a94daa5George Mount 423895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar ArrayList<String> removedUntaggable = new ArrayList<String>(); 42400da715547ee7d5d38a3b8576090ca427a94daa5George Mount for (String typeName : mStore.untaggableTypes.keySet()) { 42500da715547ee7d5d38a3b8576090ca427a94daa5George Mount if (classes.contains(mStore.untaggableTypes.get(typeName))) { 42600da715547ee7d5d38a3b8576090ca427a94daa5George Mount removedUntaggable.add(typeName); 4273561e3e665698843b1c664385a842e779198960bGeorge Mount } 4283561e3e665698843b1c664385a842e779198960bGeorge Mount } 42900da715547ee7d5d38a3b8576090ca427a94daa5George Mount removeFromMap(mStore.untaggableTypes, removedUntaggable); 43000da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 43100da715547ee7d5d38a3b8576090ca427a94daa5George Mount 43200da715547ee7d5d38a3b8576090ca427a94daa5George Mount private static <K, V> void removeFromMap(Map<K, V> map, List<K> keys) { 43300da715547ee7d5d38a3b8576090ca427a94daa5George Mount for (K key : keys) { 43400da715547ee7d5d38a3b8576090ca427a94daa5George Mount map.remove(key); 43500da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 43600da715547ee7d5d38a3b8576090ca427a94daa5George Mount keys.clear(); 4373561e3e665698843b1c664385a842e779198960bGeorge Mount } 4383561e3e665698843b1c664385a842e779198960bGeorge Mount 439a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public void write(String projectPackage, ProcessingEnvironment processingEnvironment) 440a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar throws IOException { 441a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar GenerationalClassUtil.writeIntermediateFile(processingEnvironment, 442e8609ca3a9e95cb730d74f8a6114bc2ae11b6a10Yigit Boyar projectPackage, projectPackage + 443e8609ca3a9e95cb730d74f8a6114bc2ae11b6a10Yigit Boyar GenerationalClassUtil.ExtensionFilter.SETTER_STORE.getExtension(), mStore); 4443561e3e665698843b1c664385a842e779198960bGeorge Mount } 4453561e3e665698843b1c664385a842e779198960bGeorge Mount 446cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount private static String stripNamespace(String attribute) { 4477a25150b56cb9256f9f4786f47694b03ba312d72George Mount if (!attribute.startsWith("android:")) { 4487a25150b56cb9256f9f4786f47694b03ba312d72George Mount int colon = attribute.indexOf(':'); 4497a25150b56cb9256f9f4786f47694b03ba312d72George Mount if (colon >= 0) { 4507a25150b56cb9256f9f4786f47694b03ba312d72George Mount attribute = attribute.substring(colon + 1); 4517a25150b56cb9256f9f4786f47694b03ba312d72George Mount } 4527a25150b56cb9256f9f4786f47694b03ba312d72George Mount } 453cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return attribute; 454cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 455cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 456d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public boolean isTwoWayEventAttribute(String attribute) { 457d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount attribute = stripNamespace(attribute); 458d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return mInverseEventAttributes.contains(attribute); 459d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 460cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount public List<MultiAttributeSetter> getMultiAttributeSetterCalls(String[] attributes, 461cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount ModelClass viewType, ModelClass[] valueType) { 462cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount attributes = stripAttributes(attributes); 463cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount final ArrayList<MultiAttributeSetter> calls = new ArrayList<MultiAttributeSetter>(); 464b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount if (viewType != null && viewType.isGeneric()) { 465b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount List<ModelClass> viewGenerics = viewType.getTypeArguments(); 466b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount for (int i = 0; i < valueType.length; i++) { 467b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount valueType[i] = eraseType(valueType[i], viewGenerics); 468b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 469b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount viewType = viewType.erasure(); 470b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 471cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount ArrayList<MultiAttributeSetter> matching = getMatchingMultiAttributeSetters(attributes, 472cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount viewType, valueType); 473cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount Collections.sort(matching, COMPARE_MULTI_ATTRIBUTE_SETTERS); 474cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount while (!matching.isEmpty()) { 475cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount MultiAttributeSetter bestMatch = matching.get(0); 476cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount calls.add(bestMatch); 477cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount removeConsumedAttributes(matching, bestMatch.attributes); 478cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 479cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return calls; 480cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 481cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 482a128d1c99ea98bb48c45d648906652e3d618d513George Mount private static String simpleName(String className) { 483a128d1c99ea98bb48c45d648906652e3d618d513George Mount int dotIndex = className.lastIndexOf('.'); 484a128d1c99ea98bb48c45d648906652e3d618d513George Mount if (dotIndex < 0) { 485a128d1c99ea98bb48c45d648906652e3d618d513George Mount return className; 486a128d1c99ea98bb48c45d648906652e3d618d513George Mount } else { 487a128d1c99ea98bb48c45d648906652e3d618d513George Mount return className.substring(dotIndex + 1); 488a128d1c99ea98bb48c45d648906652e3d618d513George Mount } 489a128d1c99ea98bb48c45d648906652e3d618d513George Mount } 490a128d1c99ea98bb48c45d648906652e3d618d513George Mount 491a128d1c99ea98bb48c45d648906652e3d618d513George Mount public Map<String, List<String>> getComponentBindingAdapters() { 492a128d1c99ea98bb48c45d648906652e3d618d513George Mount ensureInstanceAdapters(); 493a128d1c99ea98bb48c45d648906652e3d618d513George Mount return mInstanceAdapters; 494a128d1c99ea98bb48c45d648906652e3d618d513George Mount } 495a128d1c99ea98bb48c45d648906652e3d618d513George Mount 496a128d1c99ea98bb48c45d648906652e3d618d513George Mount private String getBindingAdapterCall(String className) { 497a128d1c99ea98bb48c45d648906652e3d618d513George Mount ensureInstanceAdapters(); 498a128d1c99ea98bb48c45d648906652e3d618d513George Mount final String simpleName = simpleName(className); 499a128d1c99ea98bb48c45d648906652e3d618d513George Mount List<String> adapters = mInstanceAdapters.get(simpleName); 500a128d1c99ea98bb48c45d648906652e3d618d513George Mount if (adapters.size() == 1) { 501a128d1c99ea98bb48c45d648906652e3d618d513George Mount return "get" + simpleName + "()"; 502a128d1c99ea98bb48c45d648906652e3d618d513George Mount } else { 503a128d1c99ea98bb48c45d648906652e3d618d513George Mount int index = adapters.indexOf(className) + 1; 504a128d1c99ea98bb48c45d648906652e3d618d513George Mount return "get" + simpleName + index + "()"; 505a128d1c99ea98bb48c45d648906652e3d618d513George Mount } 506a128d1c99ea98bb48c45d648906652e3d618d513George Mount } 507a128d1c99ea98bb48c45d648906652e3d618d513George Mount 508a128d1c99ea98bb48c45d648906652e3d618d513George Mount private void ensureInstanceAdapters() { 509a128d1c99ea98bb48c45d648906652e3d618d513George Mount if (mInstanceAdapters == null) { 5109784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar HashSet<String> adapters = new HashSet<String>(); 511a128d1c99ea98bb48c45d648906652e3d618d513George Mount for (HashMap<AccessorKey, MethodDescription> methods : mStore.adapterMethods.values()) { 512a128d1c99ea98bb48c45d648906652e3d618d513George Mount for (MethodDescription method : methods.values()) { 513a128d1c99ea98bb48c45d648906652e3d618d513George Mount if (!method.isStatic) { 514a128d1c99ea98bb48c45d648906652e3d618d513George Mount adapters.add(method.type); 515a128d1c99ea98bb48c45d648906652e3d618d513George Mount } 516a128d1c99ea98bb48c45d648906652e3d618d513George Mount } 517a128d1c99ea98bb48c45d648906652e3d618d513George Mount } 518a128d1c99ea98bb48c45d648906652e3d618d513George Mount for (MethodDescription method : mStore.multiValueAdapters.values()) { 519a128d1c99ea98bb48c45d648906652e3d618d513George Mount if (!method.isStatic) { 520a128d1c99ea98bb48c45d648906652e3d618d513George Mount adapters.add(method.type); 521a128d1c99ea98bb48c45d648906652e3d618d513George Mount } 522a128d1c99ea98bb48c45d648906652e3d618d513George Mount } 523d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount for (Map<AccessorKey, InverseDescription> methods : mStore.inverseAdapters.values()) { 524d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount for (InverseDescription method : methods.values()) { 525d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (!method.isStatic) { 526d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount adapters.add(method.type); 527d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 528d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 529d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 5309784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar mInstanceAdapters = new HashMap<String, List<String>>(); 531a128d1c99ea98bb48c45d648906652e3d618d513George Mount for (String adapter : adapters) { 532a128d1c99ea98bb48c45d648906652e3d618d513George Mount final String simpleName = simpleName(adapter); 533a128d1c99ea98bb48c45d648906652e3d618d513George Mount List<String> list = mInstanceAdapters.get(simpleName); 534a128d1c99ea98bb48c45d648906652e3d618d513George Mount if (list == null) { 5359784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar list = new ArrayList<String>(); 536a128d1c99ea98bb48c45d648906652e3d618d513George Mount mInstanceAdapters.put(simpleName, list); 537a128d1c99ea98bb48c45d648906652e3d618d513George Mount } 538a128d1c99ea98bb48c45d648906652e3d618d513George Mount list.add(adapter); 539a128d1c99ea98bb48c45d648906652e3d618d513George Mount } 540a128d1c99ea98bb48c45d648906652e3d618d513George Mount for (List<String> list : mInstanceAdapters.values()) { 541a128d1c99ea98bb48c45d648906652e3d618d513George Mount if (list.size() > 1) { 542a128d1c99ea98bb48c45d648906652e3d618d513George Mount Collections.sort(list); 543a128d1c99ea98bb48c45d648906652e3d618d513George Mount } 544a128d1c99ea98bb48c45d648906652e3d618d513George Mount } 545a128d1c99ea98bb48c45d648906652e3d618d513George Mount } 546a128d1c99ea98bb48c45d648906652e3d618d513George Mount } 547a128d1c99ea98bb48c45d648906652e3d618d513George Mount 548cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount // Removes all MultiAttributeSetters that require any of the values in attributes 549cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount private static void removeConsumedAttributes(ArrayList<MultiAttributeSetter> matching, 550cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount String[] attributes) { 551cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount for (int i = matching.size() - 1; i >= 0; i--) { 552cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount final MultiAttributeSetter setter = matching.get(i); 553cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount boolean found = false; 554cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount for (String attribute : attributes) { 555cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (isInArray(attribute, setter.attributes)) { 556cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount found = true; 557cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount break; 558cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 559cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 560cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (found) { 561cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount matching.remove(i); 562cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 563cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 564cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 565cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 566cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount // Linear search through the String array for a specific value. 567cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount private static boolean isInArray(String str, String[] array) { 568cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount for (String value : array) { 569cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (value.equals(str)) { 570cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return true; 571cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 572cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 573cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return false; 574cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 575cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 576cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount private ArrayList<MultiAttributeSetter> getMatchingMultiAttributeSetters(String[] attributes, 577cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount ModelClass viewType, ModelClass[] valueType) { 578cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount final ArrayList<MultiAttributeSetter> setters = new ArrayList<MultiAttributeSetter>(); 579cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount for (MultiValueAdapterKey adapter : mStore.multiValueAdapters.keySet()) { 58096b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount if (adapter.requireAll && adapter.attributes.length > attributes.length) { 581cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount continue; 582cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 583b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount ModelClass viewClass = mClassAnalyzer.findClass(adapter.viewType, null); 584b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount if (viewClass.isGeneric()) { 585b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount viewClass = viewClass.erasure(); 586b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 587cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (!viewClass.isAssignableFrom(viewType)) { 588cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount continue; 589cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 590cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount final MethodDescription method = mStore.multiValueAdapters.get(adapter); 591cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount final MultiAttributeSetter setter = createMultiAttributeSetter(method, attributes, 592cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount valueType, adapter); 593cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (setter != null) { 594cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount setters.add(setter); 595cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 596cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 597cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return setters; 598cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 599cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 600cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount private MultiAttributeSetter createMultiAttributeSetter(MethodDescription method, 601cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount String[] allAttributes, ModelClass[] attributeValues, MultiValueAdapterKey adapter) { 602cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount int matchingAttributes = 0; 603cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount String[] casts = new String[adapter.attributes.length]; 604cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount MethodDescription[] conversions = new MethodDescription[adapter.attributes.length]; 60596b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount boolean[] supplied = new boolean[adapter.attributes.length]; 606cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 607cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount for (int i = 0; i < allAttributes.length; i++) { 608cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount Integer index = adapter.attributeIndices.get(allAttributes[i]); 609cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (index != null) { 61096b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount supplied[index] = true; 611cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount matchingAttributes++; 612cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount final String parameterTypeStr = adapter.parameterTypes[index]; 613b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount final ModelClass parameterType = eraseType( 614b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount mClassAnalyzer.findClass(parameterTypeStr, null)); 615cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount final ModelClass attributeType = attributeValues[i]; 616cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (!parameterType.isAssignableFrom(attributeType)) { 617cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (ModelMethod.isBoxingConversion(parameterType, attributeType)) { 618cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount // automatic boxing is ok 619cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount continue; 620cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } else if (ModelMethod.isImplicitConversion(attributeType, parameterType)) { 621cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount // implicit conversion is ok 622cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount continue; 623cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 624cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount // Look for a converter 625cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount conversions[index] = getConversionMethod(attributeType, parameterType, null); 626cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (conversions[index] == null) { 627cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (attributeType.isObject()) { 628cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount // Cast is allowed also 629cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount casts[index] = parameterTypeStr; 630cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } else { 631cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount // Parameter type mismatch 632cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return null; 633cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 634cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 635cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 636cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 637cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 638cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 63996b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount if ((adapter.requireAll && matchingAttributes != adapter.attributes.length) || 64096b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount matchingAttributes == 0) { 641cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return null; 642cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } else { 64396b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount return new MultiAttributeSetter(adapter, supplied, method, conversions, casts); 644cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 645cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 646cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 647cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount public SetterCall getSetterCall(String attribute, ModelClass viewType, 648cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount ModelClass valueType, Map<String, String> imports) { 649cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount attribute = stripNamespace(attribute); 65097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar SetterCall setterCall = null; 65197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar MethodDescription conversionMethod = null; 6528e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount if (viewType != null) { 653716ba89e7f459f49ea85070d4710c1d79d715298George Mount viewType = viewType.erasure(); 6548e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount HashMap<AccessorKey, MethodDescription> adapters = mStore.adapterMethods.get(attribute); 6558e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount ModelMethod bestSetterMethod = getBestSetter(viewType, valueType, attribute, imports); 6568e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount ModelClass bestViewType = null; 6578e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount ModelClass bestValueType = null; 6588e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount if (bestSetterMethod != null) { 6598e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount bestViewType = bestSetterMethod.getDeclaringClass(); 6608e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount bestValueType = bestSetterMethod.getParameterTypes()[0]; 66197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar setterCall = new ModelMethodSetter(bestSetterMethod); 6628e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 6633561e3e665698843b1c664385a842e779198960bGeorge Mount 6648e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount if (adapters != null) { 6658e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount for (AccessorKey key : adapters.keySet()) { 6668e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount try { 6678e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount ModelClass adapterViewType = mClassAnalyzer 668716ba89e7f459f49ea85070d4710c1d79d715298George Mount .findClass(key.viewType, imports).erasure(); 669c619d8f69127c1200103d8119101c5f0675661d0George Mount if (adapterViewType != null && adapterViewType.isAssignableFrom(viewType)) { 6708e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount try { 671b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount L.d("setter parameter type is %s", key.valueType); 672b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount final ModelClass adapterValueType = eraseType(mClassAnalyzer 673b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount .findClass(key.valueType, imports)); 674b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount L.d("setter %s takes type %s, compared to %s", 675b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount adapters.get(key).method, adapterValueType.toJavaCode(), 676b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount valueType.toJavaCode()); 6778e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount boolean isBetterView = bestViewType == null || 678d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount bestViewType.isAssignableFrom(adapterViewType); 6798e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount if (isBetterParameter(valueType, adapterValueType, bestValueType, 6808e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount isBetterView, imports)) { 6818e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount bestViewType = adapterViewType; 6828e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount bestValueType = adapterValueType; 683fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount MethodDescription adapter = adapters.get(key); 684716ba89e7f459f49ea85070d4710c1d79d715298George Mount setterCall = new AdapterSetter(adapter, adapterValueType); 6858e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 6861b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 6878e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } catch (Exception e) { 68897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar L.e(e, "Unknown class: %s", key.valueType); 6898e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 690974a07824642fabd896930f20c7b176fd2333e31George Mount } 6918e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } catch (Exception e) { 69297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar L.e(e, "Unknown class: %s", key.viewType); 6933561e3e665698843b1c664385a842e779198960bGeorge Mount } 6943561e3e665698843b1c664385a842e779198960bGeorge Mount } 6953561e3e665698843b1c664385a842e779198960bGeorge Mount } 6963561e3e665698843b1c664385a842e779198960bGeorge Mount 69797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar conversionMethod = getConversionMethod(valueType, bestValueType, imports); 698fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (valueType.isObject() && setterCall != null && bestValueType.isNullable()) { 699fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount setterCall.setCast(bestValueType); 700fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 7013561e3e665698843b1c664385a842e779198960bGeorge Mount } 70297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar if (setterCall == null) { 7035f3aae011cc291c2abbb90215c2e6f89a5f2626dGeorge Mount if (viewType != null && !viewType.isViewDataBinding()) { 704716ba89e7f459f49ea85070d4710c1d79d715298George Mount return null; // no setter found!! 7055f3aae011cc291c2abbb90215c2e6f89a5f2626dGeorge Mount } 70697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar setterCall = new DummySetter(getDefaultSetter(attribute)); 7073561e3e665698843b1c664385a842e779198960bGeorge Mount } 70897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar setterCall.setConverter(conversionMethod); 70997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar return setterCall; 7103561e3e665698843b1c664385a842e779198960bGeorge Mount } 7113561e3e665698843b1c664385a842e779198960bGeorge Mount 712d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public BindingGetterCall getGetterCall(String attribute, ModelClass viewType, 713d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount ModelClass valueType, Map<String, String> imports) { 714d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (viewType == null) { 715d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return null; 716d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } else if (viewType.isViewDataBinding()) { 717d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return new ViewDataBindingGetterCall(attribute); 718d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 719d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 720d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount attribute = stripNamespace(attribute); 721d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount viewType = viewType.erasure(); 722d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 723d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount InverseMethod bestMethod = getBestGetter(viewType, valueType, attribute, imports); 724d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount HashMap<AccessorKey, InverseDescription> adapters = mStore.inverseAdapters.get(attribute); 725d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (adapters != null) { 726d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount for (AccessorKey key : adapters.keySet()) { 727d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount try { 728d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount ModelClass adapterViewType = mClassAnalyzer 729d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount .findClass(key.viewType, imports).erasure(); 730d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (adapterViewType != null && adapterViewType.isAssignableFrom(viewType)) { 731d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount try { 732d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount L.d("getter return type is %s", key.valueType); 733d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount final ModelClass adapterValueType = eraseType(mClassAnalyzer 734d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount .findClass(key.valueType, imports)); 735d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount L.d("getter %s returns type %s, compared to %s", 736d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount adapters.get(key).method, adapterValueType.toJavaCode(), 737d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount valueType); 738d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount boolean isBetterView = bestMethod.viewType == null || 739d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount bestMethod.viewType.isAssignableFrom(adapterViewType); 740d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (valueType == null || 741d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount isBetterParameter(adapterValueType, valueType, 742d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount bestMethod.returnType, isBetterView, imports)) { 743d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount bestMethod.viewType = adapterViewType; 744d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount bestMethod.returnType = adapterValueType; 745d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount InverseDescription inverseDescription = adapters.get(key); 746d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount ModelClass listenerType = ModelAnalyzer.getInstance().findClass( 747d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount InverseBindingListener.class); 748d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount BindingSetterCall eventCall = getSetterCall( 749d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount inverseDescription.event, viewType, listenerType, imports); 750d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (eventCall == null) { 751d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount List<MultiAttributeSetter> setters = 752d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount getMultiAttributeSetterCalls( 753d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount new String[]{inverseDescription.event}, 754d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount viewType, new ModelClass[] {listenerType}); 755d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (setters.size() != 1) { 756d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount L.e("Could not find event '%s' on View type '%s'", 757d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount inverseDescription.event, 758d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount viewType.getCanonicalName()); 759d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } else { 760d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount bestMethod.call = new AdapterGetter(inverseDescription, 761d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount setters.get(0)); 762d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 763d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } else { 764d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount bestMethod.call = new AdapterGetter(inverseDescription, 765d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount eventCall); 766d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 767d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 768d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 769d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } catch (Exception e) { 770d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount L.e(e, "Unknown class: %s", key.valueType); 771d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 772d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 773d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } catch (Exception e) { 774d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount L.e(e, "Unknown class: %s", key.viewType); 775d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 776d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 777d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 778d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 779d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return bestMethod.call; 780d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 781d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 78200da715547ee7d5d38a3b8576090ca427a94daa5George Mount public boolean isUntaggable(String viewType) { 78300da715547ee7d5d38a3b8576090ca427a94daa5George Mount return mStore.untaggableTypes.containsKey(viewType); 78400da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 78500da715547ee7d5d38a3b8576090ca427a94daa5George Mount 78679fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount private ModelMethod getBestSetter(ModelClass viewType, ModelClass argumentType, 787a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount String attribute, Map<String, String> imports) { 78891d538470c011e19fa4375cc3531b5dd9ae01d55George Mount if (viewType.isGeneric()) { 789b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount argumentType = eraseType(argumentType, viewType.getTypeArguments()); 79091d538470c011e19fa4375cc3531b5dd9ae01d55George Mount viewType = viewType.erasure(); 79191d538470c011e19fa4375cc3531b5dd9ae01d55George Mount } 792895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar List<String> setterCandidates = new ArrayList<String>(); 7934711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount HashMap<String, MethodDescription> renamed = mStore.renamedMethods.get(attribute); 7943561e3e665698843b1c664385a842e779198960bGeorge Mount if (renamed != null) { 7950935fcaf455ce6fc6916194da651b556e1ec0326George Mount for (String className : renamed.keySet()) { 796974a07824642fabd896930f20c7b176fd2333e31George Mount try { 797a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount ModelClass renamedViewType = mClassAnalyzer.findClass(className, imports); 798716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (renamedViewType.erasure().isAssignableFrom(viewType)) { 79997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar setterCandidates.add(renamed.get(className).method); 800974a07824642fabd896930f20c7b176fd2333e31George Mount break; 801974a07824642fabd896930f20c7b176fd2333e31George Mount } 802974a07824642fabd896930f20c7b176fd2333e31George Mount } catch (Exception e) { 803e4b93061ac703e48fc2c9994c9059ed016f05559George Mount //printMessage(Diagnostic.Kind.NOTE, "Unknown class: " + className); 8043561e3e665698843b1c664385a842e779198960bGeorge Mount } 8053561e3e665698843b1c664385a842e779198960bGeorge Mount } 8063561e3e665698843b1c664385a842e779198960bGeorge Mount } 80797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar setterCandidates.add(getDefaultSetter(attribute)); 80897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar setterCandidates.add(trimAttributeNamespace(attribute)); 809e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount 81079fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount ModelMethod bestMethod = null; 811fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount ModelClass bestParameterType = null; 812fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount List<ModelClass> args = new ArrayList<ModelClass>(); 813fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount args.add(argumentType); 81497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar for (String name : setterCandidates) { 81597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar ModelMethod[] methods = viewType.getMethods(name, 1); 81697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 81797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar for (ModelMethod method : methods) { 81897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar ModelClass[] parameterTypes = method.getParameterTypes(); 819fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount ModelClass param = parameterTypes[0]; 820fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (method.isVoid() && 821fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount isBetterParameter(argumentType, param, bestParameterType, true, imports)) { 822fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount bestParameterType = param; 823fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount bestMethod = method; 8243561e3e665698843b1c664385a842e779198960bGeorge Mount } 8253561e3e665698843b1c664385a842e779198960bGeorge Mount } 8263561e3e665698843b1c664385a842e779198960bGeorge Mount } 8273561e3e665698843b1c664385a842e779198960bGeorge Mount return bestMethod; 828b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 82997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 830d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private InverseMethod getBestGetter(ModelClass viewType, ModelClass valueType, 831d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount String attribute, Map<String, String> imports) { 832d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (viewType.isGeneric()) { 833d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (valueType != null) { 834d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount valueType = eraseType(valueType, viewType.getTypeArguments()); 835d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 836d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount viewType = viewType.erasure(); 837d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 838d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount ModelClass bestReturnType = null; 839d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount InverseDescription bestDescription = null; 840d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount ModelClass bestViewType = null; 841d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount ModelMethod bestMethod = null; 842d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 843d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount HashMap<String, InverseDescription> inverseMethods = mStore.inverseMethods.get(attribute); 844d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (inverseMethods != null) { 845d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount for (String className : inverseMethods.keySet()) { 846d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount try { 847d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount ModelClass methodViewType = mClassAnalyzer.findClass(className, imports); 848d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (methodViewType.erasure().isAssignableFrom(viewType)) { 849d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount boolean isBetterViewType = bestViewType == null || 850d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount bestViewType.isAssignableFrom(methodViewType); 851d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount final InverseDescription inverseDescription = inverseMethods.get(className); 852d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount final String name = inverseDescription.method.isEmpty() ? 853d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount trimAttributeNamespace(attribute) : inverseDescription.method; 854d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount ModelMethod method = methodViewType.findInstanceGetter(name); 855d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount ModelClass returnType = method.getReturnType(null); // no parameters 856d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (valueType == null || bestReturnType == null || 857d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount isBetterParameter(returnType, valueType, bestReturnType, 858d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount isBetterViewType, imports)) { 859d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount bestDescription = inverseDescription; 860d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount bestReturnType = returnType; 861d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount bestViewType = methodViewType; 862d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount bestMethod = method; 863d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 864d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 865d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } catch (Exception e) { 866d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount //printMessage(Diagnostic.Kind.NOTE, "Unknown class: " + className); 867d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 868d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 869d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 870d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 871d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount BindingGetterCall call = null; 872d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (bestDescription != null) { 873d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount final ModelClass listenerType = ModelAnalyzer.getInstance().findClass( 874d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount InverseBindingListener.class); 875d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount SetterCall eventSetter = getSetterCall(bestDescription.event, viewType, 876d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount listenerType, imports); 877d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (eventSetter == null) { 878d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount List<MultiAttributeSetter> setters = getMultiAttributeSetterCalls( 879d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount new String[] {bestDescription.event}, viewType, 880d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount new ModelClass[] {listenerType}); 881d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (setters.size() != 1) { 882d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount L.e("Could not find event '%s' on View type '%s'", bestDescription.event, 883d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount viewType.getCanonicalName()); 884d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount bestViewType = null; 885d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount bestReturnType = null; 886d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } else { 887d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount call = new ViewGetterCall(bestDescription, bestMethod, setters.get(0)); 888d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 889d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } else { 890d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount call = new ViewGetterCall(bestDescription, bestMethod, eventSetter); 891d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 892d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 893d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return new InverseMethod(call, bestReturnType, bestViewType); 894d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 895d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 896b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount private static ModelClass eraseType(ModelClass type, List<ModelClass> typeParameters) { 897b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount List<ModelClass> typeArguments = type.getTypeArguments(); 898b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount if (typeArguments == null || typeParameters == null) { 899b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount return type; 900b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 901b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount for (ModelClass arg : typeArguments) { 902b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount if (typeParameters.contains(arg)) { 903b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount return type.erasure(); 904b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 905b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount } 906b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount return type; 90797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 90897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 90997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar private static String trimAttributeNamespace(String attribute) { 91097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar final int colonIndex = attribute.indexOf(':'); 91197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar return colonIndex == -1 ? attribute : attribute.substring(colonIndex + 1); 9123561e3e665698843b1c664385a842e779198960bGeorge Mount } 9133561e3e665698843b1c664385a842e779198960bGeorge Mount 9143561e3e665698843b1c664385a842e779198960bGeorge Mount private static String getDefaultSetter(String attribute) { 91597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar return "set" + StringUtils.capitalize(trimAttributeNamespace(attribute)); 9163561e3e665698843b1c664385a842e779198960bGeorge Mount } 9173561e3e665698843b1c664385a842e779198960bGeorge Mount 91879fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount private boolean isBetterParameter(ModelClass argument, ModelClass parameter, 919a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount ModelClass oldParameter, boolean isBetterViewTypeMatch, Map<String, String> imports) { 9203561e3e665698843b1c664385a842e779198960bGeorge Mount // Right view type. Check the value 9213561e3e665698843b1c664385a842e779198960bGeorge Mount if (!isBetterViewTypeMatch && oldParameter.equals(argument)) { 9223561e3e665698843b1c664385a842e779198960bGeorge Mount return false; 9233561e3e665698843b1c664385a842e779198960bGeorge Mount } else if (argument.equals(parameter)) { 9243561e3e665698843b1c664385a842e779198960bGeorge Mount // Exact match 9253561e3e665698843b1c664385a842e779198960bGeorge Mount return true; 926fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } else if (!isBetterViewTypeMatch && 927fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount ModelMethod.isBoxingConversion(oldParameter, argument)) { 9283561e3e665698843b1c664385a842e779198960bGeorge Mount return false; 929fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } else if (ModelMethod.isBoxingConversion(parameter, argument)) { 9303561e3e665698843b1c664385a842e779198960bGeorge Mount // Boxing/unboxing is second best 9313561e3e665698843b1c664385a842e779198960bGeorge Mount return true; 9323561e3e665698843b1c664385a842e779198960bGeorge Mount } else { 933fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount int oldConversionLevel = ModelMethod.getImplicitConversionLevel(oldParameter); 934fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (ModelMethod.isImplicitConversion(argument, parameter)) { 9353561e3e665698843b1c664385a842e779198960bGeorge Mount // Better implicit conversion 936fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount int conversionLevel = ModelMethod.getImplicitConversionLevel(parameter); 9373561e3e665698843b1c664385a842e779198960bGeorge Mount return oldConversionLevel < 0 || conversionLevel < oldConversionLevel; 9383561e3e665698843b1c664385a842e779198960bGeorge Mount } else if (oldConversionLevel >= 0) { 9393561e3e665698843b1c664385a842e779198960bGeorge Mount return false; 9403561e3e665698843b1c664385a842e779198960bGeorge Mount } else if (parameter.isAssignableFrom(argument)) { 9413561e3e665698843b1c664385a842e779198960bGeorge Mount // Right type, see if it is better than the current best match. 9423561e3e665698843b1c664385a842e779198960bGeorge Mount if (oldParameter == null) { 9433561e3e665698843b1c664385a842e779198960bGeorge Mount return true; 9443561e3e665698843b1c664385a842e779198960bGeorge Mount } else { 9453561e3e665698843b1c664385a842e779198960bGeorge Mount return oldParameter.isAssignableFrom(parameter); 9463561e3e665698843b1c664385a842e779198960bGeorge Mount } 9473561e3e665698843b1c664385a842e779198960bGeorge Mount } else { 948a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount MethodDescription conversionMethod = getConversionMethod(argument, parameter, 949a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount imports); 9505cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount if (conversionMethod != null) { 9515cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount return true; 9525cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 953a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount if (getConversionMethod(argument, oldParameter, imports) != null) { 9545cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount return false; 9555cd681c345db8f606d7d5a8662e20e059f21a86cGeorge Mount } 956e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount return argument.isObject() && !parameter.isPrimitive(); 9573561e3e665698843b1c664385a842e779198960bGeorge Mount } 9583561e3e665698843b1c664385a842e779198960bGeorge Mount } 9593561e3e665698843b1c664385a842e779198960bGeorge Mount } 9603561e3e665698843b1c664385a842e779198960bGeorge Mount 961a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount private MethodDescription getConversionMethod(ModelClass from, ModelClass to, 962a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount Map<String, String> imports) { 9633561e3e665698843b1c664385a842e779198960bGeorge Mount if (from != null && to != null) { 96497758524d3953793b50e3e0121ef3cbdc047b35bGeorge Mount if (to.isObject()) { 96597758524d3953793b50e3e0121ef3cbdc047b35bGeorge Mount return null; 96697758524d3953793b50e3e0121ef3cbdc047b35bGeorge Mount } 9674711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount for (String fromClassName : mStore.conversionMethods.keySet()) { 968974a07824642fabd896930f20c7b176fd2333e31George Mount try { 969a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount ModelClass convertFrom = mClassAnalyzer.findClass(fromClassName, imports); 970974a07824642fabd896930f20c7b176fd2333e31George Mount if (canUseForConversion(from, convertFrom)) { 971974a07824642fabd896930f20c7b176fd2333e31George Mount HashMap<String, MethodDescription> conversion = 972974a07824642fabd896930f20c7b176fd2333e31George Mount mStore.conversionMethods.get(fromClassName); 973974a07824642fabd896930f20c7b176fd2333e31George Mount for (String toClassName : conversion.keySet()) { 974974a07824642fabd896930f20c7b176fd2333e31George Mount try { 975a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount ModelClass convertTo = mClassAnalyzer.findClass(toClassName, 976a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount imports); 977974a07824642fabd896930f20c7b176fd2333e31George Mount if (canUseForConversion(convertTo, to)) { 978974a07824642fabd896930f20c7b176fd2333e31George Mount return conversion.get(toClassName); 979974a07824642fabd896930f20c7b176fd2333e31George Mount } 980974a07824642fabd896930f20c7b176fd2333e31George Mount } catch (Exception e) { 98197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar L.d(e, "Unknown class: %s", toClassName); 982974a07824642fabd896930f20c7b176fd2333e31George Mount } 9830935fcaf455ce6fc6916194da651b556e1ec0326George Mount } 9840935fcaf455ce6fc6916194da651b556e1ec0326George Mount } 985974a07824642fabd896930f20c7b176fd2333e31George Mount } catch (Exception e) { 98697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar L.d(e, "Unknown class: %s", fromClassName); 9873561e3e665698843b1c664385a842e779198960bGeorge Mount } 9883561e3e665698843b1c664385a842e779198960bGeorge Mount } 9893561e3e665698843b1c664385a842e779198960bGeorge Mount } 9903561e3e665698843b1c664385a842e779198960bGeorge Mount return null; 9913561e3e665698843b1c664385a842e779198960bGeorge Mount } 9923561e3e665698843b1c664385a842e779198960bGeorge Mount 99379fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount private boolean canUseForConversion(ModelClass from, ModelClass to) { 994bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount if (from.isIncomplete() || to.isIncomplete()) { 995bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount from = from.erasure(); 996bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount to = to.erasure(); 997bd42d20f70b1f88e27e3b3c9c3a9c55ec155d128George Mount } 998fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return from.equals(to) || ModelMethod.isBoxingConversion(from, to) || 999fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount to.isAssignableFrom(from); 10003561e3e665698843b1c664385a842e779198960bGeorge Mount } 10013561e3e665698843b1c664385a842e779198960bGeorge Mount 1002d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private static void merge(IntermediateV2 store, Intermediate dumpStore) { 1003d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount IntermediateV2 intermediateV2 = (IntermediateV2) dumpStore.upgrade(); 1004d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount merge(store.adapterMethods, intermediateV2.adapterMethods); 1005d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount merge(store.renamedMethods, intermediateV2.renamedMethods); 1006d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount merge(store.conversionMethods, intermediateV2.conversionMethods); 1007d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount store.multiValueAdapters.putAll(intermediateV2.multiValueAdapters); 1008d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount store.untaggableTypes.putAll(intermediateV2.untaggableTypes); 1009d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount merge(store.inverseAdapters, intermediateV2.inverseAdapters); 1010d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount merge(store.inverseMethods, intermediateV2.inverseMethods); 10113561e3e665698843b1c664385a842e779198960bGeorge Mount } 10123561e3e665698843b1c664385a842e779198960bGeorge Mount 1013d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private static <K, V, D> void merge(HashMap<K, HashMap<V, D>> first, 1014d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount HashMap<K, HashMap<V, D>> second) { 10153561e3e665698843b1c664385a842e779198960bGeorge Mount for (K key : second.keySet()) { 1016d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount HashMap<V, D> firstVals = first.get(key); 1017d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount HashMap<V, D> secondVals = second.get(key); 10183561e3e665698843b1c664385a842e779198960bGeorge Mount if (firstVals == null) { 10193561e3e665698843b1c664385a842e779198960bGeorge Mount first.put(key, secondVals); 10203561e3e665698843b1c664385a842e779198960bGeorge Mount } else { 10213561e3e665698843b1c664385a842e779198960bGeorge Mount for (V key2 : secondVals.keySet()) { 10223561e3e665698843b1c664385a842e779198960bGeorge Mount if (!firstVals.containsKey(key2)) { 10233561e3e665698843b1c664385a842e779198960bGeorge Mount firstVals.put(key2, secondVals.get(key2)); 10243561e3e665698843b1c664385a842e779198960bGeorge Mount } 10253561e3e665698843b1c664385a842e779198960bGeorge Mount } 10263561e3e665698843b1c664385a842e779198960bGeorge Mount } 10273561e3e665698843b1c664385a842e779198960bGeorge Mount } 10283561e3e665698843b1c664385a842e779198960bGeorge Mount } 10293561e3e665698843b1c664385a842e779198960bGeorge Mount 1030a128d1c99ea98bb48c45d648906652e3d618d513George Mount private static String createAdapterCall(MethodDescription adapter, 1031e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount String componentExpression, String viewExpression, String... args) { 1032e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount StringBuilder sb = new StringBuilder(); 1033e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 1034e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount if (adapter.isStatic) { 1035e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount sb.append(adapter.type); 1036e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } else { 1037a128d1c99ea98bb48c45d648906652e3d618d513George Mount final SetterStore setterStore = SetterStore.get(ModelAnalyzer.getInstance()); 1038a128d1c99ea98bb48c45d648906652e3d618d513George Mount final String binderCall = setterStore.getBindingAdapterCall(adapter.type); 1039a128d1c99ea98bb48c45d648906652e3d618d513George Mount sb.append(componentExpression).append('.').append(binderCall); 1040e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1041e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount sb.append('.').append(adapter.method).append('('); 1042e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount if (adapter.componentClass != null) { 1043e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount if (!"DataBindingComponent".equals(adapter.componentClass)) { 1044e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount sb.append('(').append(adapter.componentClass).append(") "); 1045e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1046e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount sb.append(componentExpression).append(", "); 1047e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1048e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount sb.append(viewExpression); 1049e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount for (String arg: args) { 1050e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount sb.append(", ").append(arg); 1051e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1052e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount sb.append(')'); 1053e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount return sb.toString(); 1054e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1055e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 1056cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount private static class MultiValueAdapterKey implements Serializable { 1057cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount private static final long serialVersionUID = 1; 1058cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 1059cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount public final String viewType; 1060cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 1061cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount public final String[] attributes; 1062cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 1063cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount public final String[] parameterTypes; 1064cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 106596b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount public final boolean requireAll; 106696b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount 1067cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount public final TreeMap<String, Integer> attributeIndices = new TreeMap<String, Integer>(); 1068cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 1069b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount public MultiValueAdapterKey(ProcessingEnvironment processingEnv, 107096b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount ExecutableElement method, String[] attributes, boolean takesComponent, 107196b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount boolean requireAll) { 1072cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount this.attributes = stripAttributes(attributes); 107396b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount this.requireAll = requireAll; 1074cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount List<? extends VariableElement> parameters = method.getParameters(); 1075e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount final int argStart = 1 + (takesComponent ? 1 : 0); 1076e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount this.viewType = getQualifiedName(eraseType(processingEnv, 1077e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount parameters.get(argStart - 1).asType())); 1078e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount this.parameterTypes = new String[parameters.size() - argStart]; 107920c7182163d99575d382e065f5a5fe45ed6b87e2George Mount for (int i = 0; i < attributes.length; i++) { 1080e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount TypeMirror typeMirror = eraseType(processingEnv, 1081e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount parameters.get(i + argStart).asType()); 1082b9e4aa96812692a7dcf468445e64bc5b30d3c79aGeorge Mount this.parameterTypes[i] = getQualifiedName(typeMirror); 1083cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount attributeIndices.put(this.attributes[i], i); 1084cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 1085cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 1086cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 1087cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount @Override 1088cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount public boolean equals(Object obj) { 1089cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (!(obj instanceof MultiValueAdapterKey)) { 1090cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return false; 1091cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 1092cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount final MultiValueAdapterKey that = (MultiValueAdapterKey) obj; 1093cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (!this.viewType.equals(that.viewType) || 1094cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount this.attributes.length != that.attributes.length || 1095cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount !this.attributeIndices.keySet().equals(that.attributeIndices.keySet())) { 1096cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return false; 1097cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 1098cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 1099cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount for (int i = 0; i < this.attributes.length; i++) { 1100cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount final int thatIndex = that.attributeIndices.get(this.attributes[i]); 1101cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount final String thisParameter = parameterTypes[i]; 1102cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount final String thatParameter = that.parameterTypes[thatIndex]; 1103cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount if (!thisParameter.equals(thatParameter)) { 1104cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return false; 1105cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 1106cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 1107cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount return true; 1108cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 1109cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 1110cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount @Override 1111cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount public int hashCode() { 11122611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar return mergedHashCode(viewType, attributeIndices.keySet()); 1113cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 1114cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 1115cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 11162611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar private static int mergedHashCode(Object... objects) { 11172611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar return Arrays.hashCode(objects); 11182611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar } 11192611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar 11203561e3e665698843b1c664385a842e779198960bGeorge Mount private static class MethodDescription implements Serializable { 11213561e3e665698843b1c664385a842e779198960bGeorge Mount 11223561e3e665698843b1c664385a842e779198960bGeorge Mount private static final long serialVersionUID = 1; 11233561e3e665698843b1c664385a842e779198960bGeorge Mount 11243561e3e665698843b1c664385a842e779198960bGeorge Mount public final String type; 11253561e3e665698843b1c664385a842e779198960bGeorge Mount 11263561e3e665698843b1c664385a842e779198960bGeorge Mount public final String method; 11273561e3e665698843b1c664385a842e779198960bGeorge Mount 112820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount public final boolean requiresOldValue; 112920c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 1130e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount public final boolean isStatic; 1131e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 1132e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount public final String componentClass; 1133e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 1134e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount public MethodDescription(String type, String method) { 11353561e3e665698843b1c664385a842e779198960bGeorge Mount this.type = type; 11363561e3e665698843b1c664385a842e779198960bGeorge Mount this.method = method; 1137e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount this.requiresOldValue = false; 1138e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount this.isStatic = true; 1139e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount this.componentClass = null; 114097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar L.d("BINARY created method desc 1 %s %s", type, method ); 11413561e3e665698843b1c664385a842e779198960bGeorge Mount } 11423561e3e665698843b1c664385a842e779198960bGeorge Mount 1143e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount public MethodDescription(ExecutableElement method, int numAttributes, 1144e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount boolean takesComponent) { 11453561e3e665698843b1c664385a842e779198960bGeorge Mount TypeElement enclosingClass = (TypeElement) method.getEnclosingElement(); 11463561e3e665698843b1c664385a842e779198960bGeorge Mount this.type = enclosingClass.getQualifiedName().toString(); 11473561e3e665698843b1c664385a842e779198960bGeorge Mount this.method = method.getSimpleName().toString(); 1148e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount final int argStart = 1 + (takesComponent ? 1 : 0); 1149e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount this.requiresOldValue = method.getParameters().size() - argStart == numAttributes * 2; 1150e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount this.isStatic = method.getModifiers().contains(Modifier.STATIC); 1151e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount this.componentClass = takesComponent 1152e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount ? getQualifiedName(method.getParameters().get(0).asType()) 1153e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount : null; 1154e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 115597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar L.d("BINARY created method desc 2 %s %s, %s", type, this.method, method); 11563561e3e665698843b1c664385a842e779198960bGeorge Mount } 11573561e3e665698843b1c664385a842e779198960bGeorge Mount 11583561e3e665698843b1c664385a842e779198960bGeorge Mount @Override 11593561e3e665698843b1c664385a842e779198960bGeorge Mount public boolean equals(Object obj) { 11603561e3e665698843b1c664385a842e779198960bGeorge Mount if (obj instanceof MethodDescription) { 11613561e3e665698843b1c664385a842e779198960bGeorge Mount MethodDescription that = (MethodDescription) obj; 11623561e3e665698843b1c664385a842e779198960bGeorge Mount return that.type.equals(this.type) && that.method.equals(this.method); 11633561e3e665698843b1c664385a842e779198960bGeorge Mount } else { 11643561e3e665698843b1c664385a842e779198960bGeorge Mount return false; 11653561e3e665698843b1c664385a842e779198960bGeorge Mount } 11663561e3e665698843b1c664385a842e779198960bGeorge Mount } 11673561e3e665698843b1c664385a842e779198960bGeorge Mount 11683561e3e665698843b1c664385a842e779198960bGeorge Mount @Override 11693561e3e665698843b1c664385a842e779198960bGeorge Mount public int hashCode() { 11702611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar return mergedHashCode(type, method); 11713561e3e665698843b1c664385a842e779198960bGeorge Mount } 11723561e3e665698843b1c664385a842e779198960bGeorge Mount 11733561e3e665698843b1c664385a842e779198960bGeorge Mount @Override 11743561e3e665698843b1c664385a842e779198960bGeorge Mount public String toString() { 11753561e3e665698843b1c664385a842e779198960bGeorge Mount return type + "." + method + "()"; 11763561e3e665698843b1c664385a842e779198960bGeorge Mount } 11773561e3e665698843b1c664385a842e779198960bGeorge Mount } 11783561e3e665698843b1c664385a842e779198960bGeorge Mount 1179d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private static class InverseDescription extends MethodDescription { 1180d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private static final long serialVersionUID = 1; 1181d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1182d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public final String event; 1183d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1184d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public InverseDescription(String type, String method, String event) { 1185d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount super(type, method); 1186d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount this.event = event; 1187d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1188d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1189d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public InverseDescription(ExecutableElement method, String event, boolean takesComponent) { 1190d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount super(method, 1, takesComponent); 1191d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount this.event = event; 1192d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1193d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1194d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1195d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public boolean equals(Object obj) { 1196d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (!super.equals(obj) || !(obj instanceof InverseDescription)) { 1197d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return false; 1198d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1199d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return event.equals(((InverseDescription) obj).event); 1200d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1201d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1202d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1203d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public int hashCode() { 1204d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return mergedHashCode(type, method, event); 1205d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1206d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1207d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 12083561e3e665698843b1c664385a842e779198960bGeorge Mount private static class AccessorKey implements Serializable { 12093561e3e665698843b1c664385a842e779198960bGeorge Mount 12103561e3e665698843b1c664385a842e779198960bGeorge Mount private static final long serialVersionUID = 1; 12113561e3e665698843b1c664385a842e779198960bGeorge Mount 12123561e3e665698843b1c664385a842e779198960bGeorge Mount public final String viewType; 12133561e3e665698843b1c664385a842e779198960bGeorge Mount 12143561e3e665698843b1c664385a842e779198960bGeorge Mount public final String valueType; 12153561e3e665698843b1c664385a842e779198960bGeorge Mount 12163561e3e665698843b1c664385a842e779198960bGeorge Mount public AccessorKey(String viewType, String valueType) { 12173561e3e665698843b1c664385a842e779198960bGeorge Mount this.viewType = viewType; 12183561e3e665698843b1c664385a842e779198960bGeorge Mount this.valueType = valueType; 12193561e3e665698843b1c664385a842e779198960bGeorge Mount } 12203561e3e665698843b1c664385a842e779198960bGeorge Mount 12213561e3e665698843b1c664385a842e779198960bGeorge Mount @Override 12223561e3e665698843b1c664385a842e779198960bGeorge Mount public int hashCode() { 12232611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar return mergedHashCode(viewType, valueType); 12243561e3e665698843b1c664385a842e779198960bGeorge Mount } 12253561e3e665698843b1c664385a842e779198960bGeorge Mount 12263561e3e665698843b1c664385a842e779198960bGeorge Mount @Override 12273561e3e665698843b1c664385a842e779198960bGeorge Mount public boolean equals(Object obj) { 12283561e3e665698843b1c664385a842e779198960bGeorge Mount if (obj instanceof AccessorKey) { 12293561e3e665698843b1c664385a842e779198960bGeorge Mount AccessorKey that = (AccessorKey) obj; 12303561e3e665698843b1c664385a842e779198960bGeorge Mount return viewType.equals(that.valueType) && valueType.equals(that.valueType); 12313561e3e665698843b1c664385a842e779198960bGeorge Mount } else { 12323561e3e665698843b1c664385a842e779198960bGeorge Mount return false; 12333561e3e665698843b1c664385a842e779198960bGeorge Mount } 12343561e3e665698843b1c664385a842e779198960bGeorge Mount } 12353561e3e665698843b1c664385a842e779198960bGeorge Mount 12363561e3e665698843b1c664385a842e779198960bGeorge Mount @Override 12373561e3e665698843b1c664385a842e779198960bGeorge Mount public String toString() { 12383561e3e665698843b1c664385a842e779198960bGeorge Mount return "AK(" + viewType + ", " + valueType + ")"; 12393561e3e665698843b1c664385a842e779198960bGeorge Mount } 12403561e3e665698843b1c664385a842e779198960bGeorge Mount } 12413561e3e665698843b1c664385a842e779198960bGeorge Mount 1242a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private interface Intermediate extends Serializable { 12434711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount Intermediate upgrade(); 12443561e3e665698843b1c664385a842e779198960bGeorge Mount } 12453561e3e665698843b1c664385a842e779198960bGeorge Mount 12464711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount private static class IntermediateV1 implements Serializable, Intermediate { 12474711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount private static final long serialVersionUID = 1; 12484711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount public final HashMap<String, HashMap<AccessorKey, MethodDescription>> adapterMethods = 1249895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar new HashMap<String, HashMap<AccessorKey, MethodDescription>>(); 12504711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount public final HashMap<String, HashMap<String, MethodDescription>> renamedMethods = 1251895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar new HashMap<String, HashMap<String, MethodDescription>>(); 12524711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount public final HashMap<String, HashMap<String, MethodDescription>> conversionMethods = 1253895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar new HashMap<String, HashMap<String, MethodDescription>>(); 1254895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar public final HashMap<String, String> untaggableTypes = new HashMap<String, String>(); 1255cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount public final HashMap<MultiValueAdapterKey, MethodDescription> multiValueAdapters = 1256cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount new HashMap<MultiValueAdapterKey, MethodDescription>(); 12573561e3e665698843b1c664385a842e779198960bGeorge Mount 12584711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount public IntermediateV1() { 12593561e3e665698843b1c664385a842e779198960bGeorge Mount } 1260d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 1261d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar @Override 12624711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount public Intermediate upgrade() { 1263d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount IntermediateV2 v2 = new IntermediateV2(); 1264d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount v2.adapterMethods.putAll(adapterMethods); 1265d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount v2.renamedMethods.putAll(renamedMethods); 1266d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount v2.conversionMethods.putAll(conversionMethods); 1267d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount v2.untaggableTypes.putAll(untaggableTypes); 1268d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount v2.multiValueAdapters.putAll(multiValueAdapters); 1269d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return v2; 1270d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1271d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1272d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1273d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private static class IntermediateV2 extends IntermediateV1 { 1274d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public final HashMap<String, HashMap<AccessorKey, InverseDescription>> inverseAdapters = 1275d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount new HashMap<String, HashMap<AccessorKey, InverseDescription>>(); 1276d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public final HashMap<String, HashMap<String, InverseDescription>> inverseMethods = 1277d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount new HashMap<String, HashMap<String, InverseDescription>>(); 1278d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1279d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1280d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public Intermediate upgrade() { 12814711e767639124a4e9720fb72f03d1175fa7312fGeorge Mount return this; 12823561e3e665698843b1c664385a842e779198960bGeorge Mount } 12833561e3e665698843b1c664385a842e779198960bGeorge Mount } 128497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 128597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public static class DummySetter extends SetterCall { 128697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar private String mMethodName; 128797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 128897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public DummySetter(String methodName) { 128997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar mMethodName = methodName; 129097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 129197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 129297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar @Override 1293e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount public String toJavaInternal(String componentExpression, String viewExpression, 1294e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount String valueExpression) { 129597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar return viewExpression + "." + mMethodName + "(" + valueExpression + ")"; 129697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 129797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 129897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar @Override 1299e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount public String toJavaInternal(String componentExpression, String viewExpression, 1300e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount String oldValue, String valueExpression) { 130120c7182163d99575d382e065f5a5fe45ed6b87e2George Mount return viewExpression + "." + mMethodName + "(" + valueExpression + ")"; 130220c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 130320c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 130420c7182163d99575d382e065f5a5fe45ed6b87e2George Mount @Override 130597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public int getMinApi() { 130697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar return 1; 130797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 130820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 130920c7182163d99575d382e065f5a5fe45ed6b87e2George Mount @Override 131020c7182163d99575d382e065f5a5fe45ed6b87e2George Mount public boolean requiresOldValue() { 131120c7182163d99575d382e065f5a5fe45ed6b87e2George Mount return false; 131220c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 1313716ba89e7f459f49ea85070d4710c1d79d715298George Mount 1314716ba89e7f459f49ea85070d4710c1d79d715298George Mount @Override 1315716ba89e7f459f49ea85070d4710c1d79d715298George Mount public ModelClass[] getParameterTypes() { 1316716ba89e7f459f49ea85070d4710c1d79d715298George Mount return new ModelClass[] { 1317716ba89e7f459f49ea85070d4710c1d79d715298George Mount ModelAnalyzer.getInstance().findClass(Object.class) 1318716ba89e7f459f49ea85070d4710c1d79d715298George Mount }; 1319716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 1320e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 1321e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount @Override 1322e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount public String getBindingAdapterInstanceClass() { 1323e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount return null; 1324e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 132597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 132697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 132797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public static class AdapterSetter extends SetterCall { 132897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar final MethodDescription mAdapter; 1329716ba89e7f459f49ea85070d4710c1d79d715298George Mount final ModelClass mParameterType; 133097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 1331716ba89e7f459f49ea85070d4710c1d79d715298George Mount public AdapterSetter(MethodDescription adapter, ModelClass parameterType) { 133297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar mAdapter = adapter; 1333716ba89e7f459f49ea85070d4710c1d79d715298George Mount mParameterType = parameterType; 133497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 133597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 133697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar @Override 1337e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount public String toJavaInternal(String componentExpression, String viewExpression, 1338e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount String valueExpression) { 1339a128d1c99ea98bb48c45d648906652e3d618d513George Mount return createAdapterCall(mAdapter, componentExpression, 1340e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount viewExpression, mCastString + valueExpression); 134197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 134297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 134397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar @Override 1344e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount protected String toJavaInternal(String componentExpression, String viewExpression, 1345e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount String oldValue, String valueExpression) { 1346a128d1c99ea98bb48c45d648906652e3d618d513George Mount return createAdapterCall(mAdapter, componentExpression, 1347e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount viewExpression, mCastString + oldValue, mCastString + valueExpression); 134820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 134920c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 135020c7182163d99575d382e065f5a5fe45ed6b87e2George Mount @Override 135197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public int getMinApi() { 135297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar return 1; 135397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 135420c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 135520c7182163d99575d382e065f5a5fe45ed6b87e2George Mount @Override 135620c7182163d99575d382e065f5a5fe45ed6b87e2George Mount public boolean requiresOldValue() { 135720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount return mAdapter.requiresOldValue; 135820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 1359716ba89e7f459f49ea85070d4710c1d79d715298George Mount 1360716ba89e7f459f49ea85070d4710c1d79d715298George Mount @Override 1361716ba89e7f459f49ea85070d4710c1d79d715298George Mount public ModelClass[] getParameterTypes() { 1362716ba89e7f459f49ea85070d4710c1d79d715298George Mount return new ModelClass[] { mParameterType }; 1363716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 1364e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 1365e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount @Override 1366e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount public String getBindingAdapterInstanceClass() { 1367e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount return mAdapter.isStatic ? null : mAdapter.type; 1368e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 136997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 137097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 137197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public static class ModelMethodSetter extends SetterCall { 137297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar final ModelMethod mModelMethod; 137397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 137497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public ModelMethodSetter(ModelMethod modelMethod) { 137597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar mModelMethod = modelMethod; 137697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 137797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 137897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar @Override 1379e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount public String toJavaInternal(String componentExpression, String viewExpression, 1380e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount String valueExpression) { 1381fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return viewExpression + "." + mModelMethod.getName() + "(" + mCastString + 1382fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount valueExpression + ")"; 138397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 138497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 138597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar @Override 1386e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount protected String toJavaInternal(String componentExpression, String viewExpression, 1387e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount String oldValue, String valueExpression) { 138820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount return viewExpression + "." + mModelMethod.getName() + "(" + 138920c7182163d99575d382e065f5a5fe45ed6b87e2George Mount mCastString + oldValue + ", " + mCastString + valueExpression + ")"; 139020c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 139120c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 139220c7182163d99575d382e065f5a5fe45ed6b87e2George Mount @Override 139397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public int getMinApi() { 139497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar return mModelMethod.getMinApi(); 139597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 139620c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 139720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount @Override 139820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount public boolean requiresOldValue() { 139920c7182163d99575d382e065f5a5fe45ed6b87e2George Mount return mModelMethod.getParameterTypes().length == 3; 140020c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 1401716ba89e7f459f49ea85070d4710c1d79d715298George Mount 1402716ba89e7f459f49ea85070d4710c1d79d715298George Mount @Override 1403716ba89e7f459f49ea85070d4710c1d79d715298George Mount public ModelClass[] getParameterTypes() { 1404716ba89e7f459f49ea85070d4710c1d79d715298George Mount return new ModelClass[] { mModelMethod.getParameterTypes()[0] }; 1405716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 1406e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 1407e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount @Override 1408e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount public String getBindingAdapterInstanceClass() { 1409e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount return null; 1410e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 141197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 141297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 141320c7182163d99575d382e065f5a5fe45ed6b87e2George Mount public interface BindingSetterCall { 1414e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount String toJava(String componentExpression, String viewExpression, 1415e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount String... valueExpressions); 1416e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar 1417e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar int getMinApi(); 141820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 141920c7182163d99575d382e065f5a5fe45ed6b87e2George Mount boolean requiresOldValue(); 1420716ba89e7f459f49ea85070d4710c1d79d715298George Mount 1421716ba89e7f459f49ea85070d4710c1d79d715298George Mount ModelClass[] getParameterTypes(); 1422e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 1423e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount String getBindingAdapterInstanceClass(); 1424e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar } 1425e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar 1426e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar public static abstract class SetterCall implements BindingSetterCall { 142797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar private MethodDescription mConverter; 1428fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount protected String mCastString = ""; 142997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 143097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public SetterCall() { 143197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 143297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 143397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public void setConverter(MethodDescription converter) { 143497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar mConverter = converter; 143597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 143697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 1437e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount protected abstract String toJavaInternal(String componentExpression, String viewExpression, 143820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount String converted); 143920c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 1440e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount protected abstract String toJavaInternal(String componentExpression, String viewExpression, 1441e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount String oldValue, String converted); 1442e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 1443e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar @Override 1444e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount public final String toJava(String componentExpression, String viewExpression, 1445e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount String... valueExpression) { 14462611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar Preconditions.check(valueExpression.length == 2, "value expressions size must be 2"); 144720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount if (requiresOldValue()) { 1448e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount return toJavaInternal(componentExpression, viewExpression, 1449e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount convertValue(valueExpression[0]), convertValue(valueExpression[1])); 145020c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } else { 1451e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount return toJavaInternal(componentExpression, viewExpression, 1452e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount convertValue(valueExpression[1])); 145320c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 145497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 145597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 145697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar protected String convertValue(String valueExpression) { 145797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar return mConverter == null ? valueExpression : 145897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar mConverter.type + "." + mConverter.method + "(" + valueExpression + ")"; 145997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 146097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 146197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar abstract public int getMinApi(); 1462fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 1463fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public void setCast(ModelClass castTo) { 1464fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount mCastString = "(" + castTo.toJavaCode() + ") "; 1465fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 146697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 1467cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 1468e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar public static class MultiAttributeSetter implements BindingSetterCall { 1469cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount public final String[] attributes; 1470cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount private final MethodDescription mAdapter; 1471cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount private final MethodDescription[] mConverters; 1472cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount private final String[] mCasts; 1473cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount private final MultiValueAdapterKey mKey; 147496b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount private final boolean[] mSupplied; 1475cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 147696b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount public MultiAttributeSetter(MultiValueAdapterKey key, boolean[] supplied, 1477cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount MethodDescription adapter, MethodDescription[] converters, String[] casts) { 14782611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar Preconditions.check(converters != null && 147996b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount converters.length == key.attributes.length && 148096b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount casts != null && casts.length == key.attributes.length && 148196b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount supplied.length == key.attributes.length, 14822611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar "invalid arguments to create multi attr setter"); 1483cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount this.mAdapter = adapter; 1484cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount this.mConverters = converters; 1485cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount this.mCasts = casts; 1486cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount this.mKey = key; 148796b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount this.mSupplied = supplied; 148896b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount if (key.requireAll) { 148996b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount this.attributes = key.attributes; 149096b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount } else { 149196b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount int numSupplied = 0; 149296b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount for (int i = 0; i < mKey.attributes.length; i++) { 149396b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount if (supplied[i]) { 149496b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount numSupplied++; 149596b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount } 149696b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount } 149796b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount if (numSupplied == key.attributes.length) { 149896b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount this.attributes = key.attributes; 149996b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount } else { 150096b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount this.attributes = new String[numSupplied]; 150196b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount int attrIndex = 0; 150296b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount for (int i = 0; i < key.attributes.length; i++) { 150396b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount if (supplied[i]) { 150496b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount attributes[attrIndex++] = key.attributes[i]; 150596b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount } 150696b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount } 150796b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount } 150896b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount } 1509cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 1510cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount 1511e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar @Override 1512e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount public final String toJava(String componentExpression, String viewExpression, 1513e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount String[] valueExpressions) { 15142611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar Preconditions.check(valueExpressions.length == attributes.length * 2, 1515e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar "MultiAttributeSetter needs %s items, received %s", 1516e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar Arrays.toString(attributes), Arrays.toString(valueExpressions)); 151796b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount final int numAttrs = mKey.attributes.length; 1518e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount String[] args = new String[numAttrs + (requiresOldValue() ? numAttrs : 0)]; 1519e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 152096b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount final int startIndex = mAdapter.requiresOldValue ? 0 : numAttrs; 152196b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount int attrIndex = mAdapter.requiresOldValue ? 0 : attributes.length; 152296b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount final ModelAnalyzer modelAnalyzer = ModelAnalyzer.getInstance(); 1523e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount StringBuilder argBuilder = new StringBuilder(); 152496b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount final int endIndex = numAttrs * 2; 152596b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount for (int i = startIndex; i < endIndex; i++) { 1526e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount argBuilder.setLength(0); 152796b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount if (!mSupplied[i % numAttrs]) { 152896b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount final String paramType = mKey.parameterTypes[i % numAttrs]; 152996b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount final String defaultValue = modelAnalyzer.getDefaultValue(paramType); 153096b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount argBuilder.append('(') 153196b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount .append(paramType) 153296b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount .append(')') 153396b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount .append(defaultValue); 1534cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } else { 153596b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount if (mConverters[i % numAttrs] != null) { 153696b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount final MethodDescription converter = mConverters[i % numAttrs]; 153796b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount argBuilder.append(converter.type) 153896b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount .append('.') 153996b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount .append(converter.method) 154096b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount .append('(') 154196b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount .append(valueExpressions[attrIndex]) 1542cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount .append(')'); 154396b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount } else { 154496b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount if (mCasts[i % numAttrs] != null) { 154596b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount argBuilder.append('(') 154696b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount .append(mCasts[i % numAttrs]) 154796b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount .append(')'); 154896b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount } 154996b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount argBuilder.append(valueExpressions[attrIndex]); 1550cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 155196b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount attrIndex++; 1552cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 1553793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount args[i - startIndex] = argBuilder.toString(); 1554cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 1555a128d1c99ea98bb48c45d648906652e3d618d513George Mount return createAdapterCall(mAdapter, componentExpression, viewExpression, args); 1556cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 1557e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar 1558e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar @Override 1559e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar public int getMinApi() { 1560e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar return 1; 1561e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar } 1562e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar 1563e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar @Override 156420c7182163d99575d382e065f5a5fe45ed6b87e2George Mount public boolean requiresOldValue() { 156520c7182163d99575d382e065f5a5fe45ed6b87e2George Mount return mAdapter.requiresOldValue; 156620c7182163d99575d382e065f5a5fe45ed6b87e2George Mount } 156720c7182163d99575d382e065f5a5fe45ed6b87e2George Mount 156820c7182163d99575d382e065f5a5fe45ed6b87e2George Mount @Override 1569716ba89e7f459f49ea85070d4710c1d79d715298George Mount public ModelClass[] getParameterTypes() { 1570716ba89e7f459f49ea85070d4710c1d79d715298George Mount ModelClass[] parameters = new ModelClass[attributes.length]; 1571716ba89e7f459f49ea85070d4710c1d79d715298George Mount String[] paramTypeStrings = mKey.parameterTypes; 1572716ba89e7f459f49ea85070d4710c1d79d715298George Mount ModelAnalyzer modelAnalyzer = ModelAnalyzer.getInstance(); 157396b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount int attrIndex = 0; 157496b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount for (int i = 0; i < mKey.attributes.length; i++) { 157596b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount if (mSupplied[i]) { 157696b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount parameters[attrIndex++] = modelAnalyzer.findClass(paramTypeStrings[i], null); 157796b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount } 1578716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 1579716ba89e7f459f49ea85070d4710c1d79d715298George Mount return parameters; 1580716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 1581716ba89e7f459f49ea85070d4710c1d79d715298George Mount 1582716ba89e7f459f49ea85070d4710c1d79d715298George Mount @Override 1583e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount public String getBindingAdapterInstanceClass() { 1584e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount return mAdapter.isStatic ? null : mAdapter.type; 1585e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 1586e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 1587e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount @Override 1588e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar public String toString() { 1589e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar return "MultiAttributeSetter{" + 1590e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar "attributes=" + Arrays.toString(attributes) + 1591e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar ", mAdapter=" + mAdapter + 1592e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar ", mConverters=" + Arrays.toString(mConverters) + 1593e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar ", mCasts=" + Arrays.toString(mCasts) + 1594e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar ", mKey=" + mKey + 1595e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar '}'; 1596e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar } 1597cffffe30fe53455856d3d41724b9d5dd21aebf9aGeorge Mount } 1598d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1599d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public static class ViewDataBindingEventSetter implements BindingSetterCall { 1600d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1601d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public ViewDataBindingEventSetter() { 1602d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1603d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1604d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1605d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public String toJava(String componentExpression, String viewExpression, 1606d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount String... valueExpressions) { 1607d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return "setBindingInverseListener(" + viewExpression + ", " + 1608d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount valueExpressions[0] + ", " + valueExpressions[1] + ")"; 1609d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1610d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1611d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1612d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public int getMinApi() { 1613d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return 0; 1614d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1615d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1616d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1617d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public boolean requiresOldValue() { 1618d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return true; 1619d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1620d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1621d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1622d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public ModelClass[] getParameterTypes() { 1623d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount ModelClass[] parameterTypes = new ModelClass[1]; 1624d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount parameterTypes[0] = ModelAnalyzer.getInstance().findClass( 1625d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount "android.databinding.ViewDataBinder.PropertyChangedInverseListener", null); 1626d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return parameterTypes; 1627d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1628d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1629d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1630d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public String getBindingAdapterInstanceClass() { 1631d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return null; 1632d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1633d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1634d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1635d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public interface BindingGetterCall { 1636d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount String toJava(String componentExpression, String viewExpression); 1637d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1638d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount int getMinApi(); 1639d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1640d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount String getBindingAdapterInstanceClass(); 1641d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1642d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount void setBindingAdapterCall(String method); 1643d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1644d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount BindingSetterCall getEvent(); 1645d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1646d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount String getEventAttribute(); 1647d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1648d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1649d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public static class ViewDataBindingGetterCall implements BindingGetterCall { 1650d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private final String mGetter; 1651d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private final BindingSetterCall mEventSetter; 1652d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private final String mAttribute; 1653d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1654d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public ViewDataBindingGetterCall(String attribute) { 1655d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount final int colonIndex = attribute.indexOf(':'); 1656d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mAttribute = attribute.substring(colonIndex + 1); 1657d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mGetter = "get" + StringUtils.capitalize(mAttribute); 1658d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mEventSetter = new ViewDataBindingEventSetter(); 1659d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1660d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1661d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1662d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public String toJava(String componentExpression, String viewExpression) { 1663d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return viewExpression + "." + mGetter + "()"; 1664d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1665d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1666d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1667d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public int getMinApi() { 1668d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return 0; 1669d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1670d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1671d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1672d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public String getBindingAdapterInstanceClass() { 1673d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return null; 1674d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1675d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1676d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1677d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public void setBindingAdapterCall(String method) { 1678d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1679d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1680d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1681d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public BindingSetterCall getEvent() { 1682d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return mEventSetter; 1683d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1684d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1685d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1686d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public String getEventAttribute() { 1687d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return mAttribute; 1688d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1689d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1690d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1691d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public static class ViewGetterCall implements BindingGetterCall { 1692d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private final InverseDescription mInverseDescription; 1693d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private final BindingSetterCall mEventCall; 1694d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private final ModelMethod mMethod; 1695d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1696d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public ViewGetterCall(InverseDescription inverseDescription, ModelMethod method, 1697d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount BindingSetterCall eventCall) { 1698d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mInverseDescription = inverseDescription; 1699d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mEventCall = eventCall; 1700d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mMethod = method; 1701d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1702d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1703d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1704d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public BindingSetterCall getEvent() { 1705d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return mEventCall; 1706d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1707d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1708d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1709d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public String getEventAttribute() { 1710d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return mInverseDescription.event; 1711d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1712d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1713d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1714d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public String toJava(String componentExpression, String viewExpression) { 1715d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return viewExpression + "." + mMethod.getName() + "()"; 1716d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1717d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1718d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1719d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public int getMinApi() { 1720d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return mMethod.getMinApi(); 1721d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1722d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1723d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1724d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public String getBindingAdapterInstanceClass() { 1725d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return null; 1726d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1727d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1728d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1729d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public void setBindingAdapterCall(String method) { 1730d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1731d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1732d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1733d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public static class AdapterGetter implements BindingGetterCall { 1734d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private final InverseDescription mInverseDescription; 1735d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private String mBindingAdapterCall; 1736d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private final BindingSetterCall mEventCall; 1737d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1738d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public AdapterGetter(InverseDescription description, BindingSetterCall eventCall) { 1739d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mInverseDescription = description; 1740d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mEventCall = eventCall; 1741d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1742d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1743d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1744d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public String toJava(String componentExpression, String viewExpression) { 1745d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount StringBuilder sb = new StringBuilder(); 1746d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1747d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (mInverseDescription.isStatic) { 1748d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount sb.append(mInverseDescription.type); 1749d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } else { 1750d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount sb.append(componentExpression).append('.').append(mBindingAdapterCall); 1751d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1752d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount sb.append('.').append(mInverseDescription.method).append('('); 1753d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (mInverseDescription.componentClass != null) { 1754d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (!"DataBindingComponent".equals(mInverseDescription.componentClass)) { 1755d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount sb.append('(').append(mInverseDescription.componentClass).append(") "); 1756d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1757d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount sb.append(componentExpression).append(", "); 1758d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1759d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount sb.append(viewExpression).append(')'); 1760d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return sb.toString(); 1761d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1762d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1763d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1764d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public int getMinApi() { 1765d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return 1; 1766d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1767d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1768d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1769d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public String getBindingAdapterInstanceClass() { 1770d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return mInverseDescription.isStatic ? null : mInverseDescription.type; 1771d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1772d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1773d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1774d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public void setBindingAdapterCall(String method) { 1775d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mBindingAdapterCall = method; 1776d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1777d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1778d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1779d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public BindingSetterCall getEvent() { 1780d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return mEventCall; 1781d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1782d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1783d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 1784d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public String getEventAttribute() { 1785d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return mInverseDescription.event; 1786d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1787d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1788d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1789d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private static class InverseMethod { 1790d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public BindingGetterCall call; 1791d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public ModelClass returnType; 1792d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public ModelClass viewType; 1793d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 1794d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public InverseMethod(BindingGetterCall call, ModelClass returnType, ModelClass viewType) { 1795d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount this.call = call; 1796d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount this.returnType = returnType; 1797d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount this.viewType = viewType; 1798d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 1799d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 18003561e3e665698843b1c664385a842e779198960bGeorge Mount} 1801