LayoutBinder.java revision c1560e6b00b398867da12fbdc5a1fcd1d50b801c
1d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar/* 2d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Copyright (C) 2015 The Android Open Source Project 3d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * 4d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 5d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * you may not use this file except in compliance with the License. 6d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * You may obtain a copy of the License at 7d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * 8d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 9d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * 10d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Unless required by applicable law or agreed to in writing, software 11d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 12d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * See the License for the specific language governing permissions and 14d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * limitations under the License. 15d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar */ 16d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 17fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.tool; 18d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 19c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport org.antlr.v4.runtime.misc.Nullable; 20c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar 21fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.Dependency; 22fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.Expr; 23fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ExprModel; 24716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport android.databinding.tool.expr.ExprModel.ResolveListenersCallback; 25fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.IdentifierExpr; 26c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport android.databinding.tool.store.Location; 27fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.store.ResourceBundle; 2834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport android.databinding.tool.store.ResourceBundle.BindingTargetBundle; 292611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyarimport android.databinding.tool.util.Preconditions; 30fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.writer.LayoutBinderWriter; 3134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport android.databinding.tool.writer.WriterPackage; 32d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 33d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.ArrayList; 3434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport java.util.Collections; 3534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport java.util.Comparator; 365bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyarimport java.util.HashMap; 37d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.List; 385bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyarimport java.util.Map; 39d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 40d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar/** 41d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Keeps all information about the bindings per layout file 42d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar */ 43716ba89e7f459f49ea85070d4710c1d79d715298George Mountpublic class LayoutBinder implements ResolveListenersCallback { 4434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount private static final Comparator<BindingTarget> COMPARE_FIELD_NAME = new Comparator<BindingTarget>() { 4534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount @Override 4634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount public int compare(BindingTarget first, BindingTarget second) { 4734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount final String fieldName1 = WriterPackage.getFieldName(first); 4834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount final String fieldName2 = WriterPackage.getFieldName(second); 4934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount return fieldName1.compareTo(fieldName2); 5034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 5134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount }; 523bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar 53d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar /* 54d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * val pkg: String, val projectPackage: String, val baseClassName: String, 55d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val layoutName:String, val lb: LayoutExprBinding*/ 56d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar private final ExprModel mExprModel; 57d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar private final ExpressionParser mExpressionParser; 58d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar private final List<BindingTarget> mBindingTargets; 5996e1c821dd446d1ed78f8ae61131550588f60a24George Mount private final List<BindingTarget> mSortedBindingTargets; 60a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private String mModulePackage; 61895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar private final HashMap<String, String> mUserDefinedVariables = new HashMap<String, String>(); 62d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 6343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar private LayoutBinderWriter mWriter; 643bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar private ResourceBundle.LayoutFileBundle mBundle; 65c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount private static final String[] sJavaLangClasses = { 66c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Deprecated", 67c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Override", 68c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "SafeVarargs", 69c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "SuppressWarnings", 70c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Appendable", 71c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "AutoCloseable", 72c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "CharSequence", 73c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Cloneable", 74c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Comparable", 75c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Iterable", 76c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Readable", 77c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Runnable", 78c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Thread.UncaughtExceptionHandler", 79c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Boolean", 80c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Byte", 81c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Character", 82c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Character.Subset", 83c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Character.UnicodeBlock", 84c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Class", 85c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ClassLoader", 86c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Compiler", 87c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Double", 88c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Enum", 89c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Float", 90c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "InheritableThreadLocal", 91c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Integer", 92c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Long", 93c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Math", 94c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Number", 95c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Object", 96c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Package", 97c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Process", 98c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ProcessBuilder", 99c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Runtime", 100c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "RuntimePermission", 101c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "SecurityManager", 102c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Short", 103c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "StackTraceElement", 104c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "StrictMath", 105c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "String", 106c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "StringBuffer", 107c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "StringBuilder", 108c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "System", 109c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Thread", 110c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ThreadGroup", 111c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ThreadLocal", 112c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Throwable", 113c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Void", 114c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Thread.State", 115c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ArithmeticException", 116c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ArrayIndexOutOfBoundsException", 117c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ArrayStoreException", 118c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ClassCastException", 119c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ClassNotFoundException", 120c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "CloneNotSupportedException", 121c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "EnumConstantNotPresentException", 122c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Exception", 123c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "IllegalAccessException", 124c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "IllegalArgumentException", 125c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "IllegalMonitorStateException", 126c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "IllegalStateException", 127c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "IllegalThreadStateException", 128c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "IndexOutOfBoundsException", 129c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "InstantiationException", 130c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "InterruptedException", 131c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "NegativeArraySizeException", 132c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "NoSuchFieldException", 133c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "NoSuchMethodException", 134c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "NullPointerException", 135c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "NumberFormatException", 136c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ReflectiveOperationException", 137c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "RuntimeException", 138c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "SecurityException", 139c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "StringIndexOutOfBoundsException", 140c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "TypeNotPresentException", 141c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "UnsupportedOperationException", 142c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "AbstractMethodError", 143c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "AssertionError", 144c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ClassCircularityError", 145c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ClassFormatError", 146c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Error", 147c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ExceptionInInitializerError", 148c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "IllegalAccessError", 149c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "IncompatibleClassChangeError", 150c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "InstantiationError", 151c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "InternalError", 152c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "LinkageError", 153c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "NoClassDefFoundError", 154c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "NoSuchFieldError", 155c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "NoSuchMethodError", 156c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "OutOfMemoryError", 157c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "StackOverflowError", 158c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ThreadDeath", 159c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "UnknownError", 160c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "UnsatisfiedLinkError", 161c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "UnsupportedClassVersionError", 162c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "VerifyError", 163c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "VirtualMachineError", 164c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount }; 16543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 1667ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount public LayoutBinder(ResourceBundle.LayoutFileBundle layoutBundle) { 167d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mExprModel = new ExprModel(); 168d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mExpressionParser = new ExpressionParser(mExprModel); 169895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar mBindingTargets = new ArrayList<BindingTarget>(); 1703bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar mBundle = layoutBundle; 171a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar mModulePackage = layoutBundle.getModulePackage(); 1723bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar // copy over data. 173c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar for (ResourceBundle.NameTypeLocation variable : mBundle.getVariables()) { 174c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar addVariable(variable.name, variable.type, variable.location); 1753bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar } 1763bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar 177c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar for (ResourceBundle.NameTypeLocation userImport : mBundle.getImports()) { 178c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar mExprModel.addImport(userImport.name, userImport.type, userImport.location); 1793bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar } 180c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount for (String javaLangClass : sJavaLangClasses) { 181c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar mExprModel.addImport(javaLangClass, "java.lang." + javaLangClass, null); 182c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount } 18334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount for (BindingTargetBundle targetBundle : mBundle.getBindingTargetBundles()) { 1843bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar final BindingTarget bindingTarget = createBindingTarget(targetBundle); 1853bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar for (ResourceBundle.BindingTargetBundle.BindingBundle bindingBundle : targetBundle 1863bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar .getBindingBundleList()) { 187c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar bindingTarget.addBinding(bindingBundle.getName(), parse(bindingBundle.getExpr(), 188c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar targetBundle.getLocation())); 1893bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar } 190e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar bindingTarget.resolveMultiSetters(); 1913bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar } 19296e1c821dd446d1ed78f8ae61131550588f60a24George Mount mSortedBindingTargets = new ArrayList<BindingTarget>(mBindingTargets); 19396e1c821dd446d1ed78f8ae61131550588f60a24George Mount Collections.sort(mSortedBindingTargets, COMPARE_FIELD_NAME); 194d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 195d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 1965bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar public void resolveWhichExpressionsAreUsed() { 197895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar List<Expr> used = new ArrayList<Expr>(); 1985bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar for (BindingTarget target : mBindingTargets) { 1995bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar for (Binding binding : target.getBindings()) { 2005bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar binding.getExpr().setIsUsed(true); 2015bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar used.add(binding.getExpr()); 2025bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 2035bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 2045bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar while (!used.isEmpty()) { 2055bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar Expr e = used.remove(used.size() - 1); 2065bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar for (Dependency dep : e.getDependencies()) { 2075bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar if (!dep.getOther().isUsed()) { 2085bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar used.add(dep.getOther()); 2095bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar dep.getOther().setIsUsed(true); 2105bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 2115bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 2125bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 2135bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 2145bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 215c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar public IdentifierExpr addVariable(String name, String type, Location location) { 2162611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar Preconditions.check(!mUserDefinedVariables.containsKey(name), 2175bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar "%s has already been defined as %s", name, type); 218d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar final IdentifierExpr id = mExprModel.identifier(name); 219d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar id.setUserDefinedType(type); 220d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar id.enableDirectInvalidation(); 221c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar if (location != null) { 222c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar id.addLocation(location); 223c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar } 2245bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar mUserDefinedVariables.put(name, type); 225d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return id; 226d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 227d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 2285bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar public HashMap<String, String> getUserDefinedVariables() { 2295bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar return mUserDefinedVariables; 2305bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 2315bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 2323bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar public BindingTarget createBindingTarget(ResourceBundle.BindingTargetBundle targetBundle) { 2333bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar final BindingTarget target = new BindingTarget(targetBundle); 234d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mBindingTargets.add(target); 235d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar target.setModel(mExprModel); 236d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return target; 237d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 238d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 239c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar public Expr parse(String input, @Nullable Location locationInFile) { 240c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar final Expr parsed = mExpressionParser.parse(input, locationInFile); 241d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar parsed.setBindingExpression(true); 242d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return parsed; 243d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 244d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 245d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public List<BindingTarget> getBindingTargets() { 246d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return mBindingTargets; 247d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 248d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 24996e1c821dd446d1ed78f8ae61131550588f60a24George Mount public List<BindingTarget> getSortedTargets() { 25096e1c821dd446d1ed78f8ae61131550588f60a24George Mount return mSortedBindingTargets; 25196e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 25296e1c821dd446d1ed78f8ae61131550588f60a24George Mount 253d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public boolean isEmpty() { 254d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return mExprModel.size() == 0; 255d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 256d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 257d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public ExprModel getModel() { 258d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return mExprModel; 259d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 260d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 26143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar private void ensureWriter() { 26243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar if (mWriter == null) { 26343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar mWriter = new LayoutBinderWriter(this); 26443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 26543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 2663bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar 2678b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar public String writeViewBinderBaseClass(boolean forLibrary) { 26843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar ensureWriter(); 2698b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar return mWriter.writeBaseClass(forLibrary); 27043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 27143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 27243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 27396e1c821dd446d1ed78f8ae61131550588f60a24George Mount public String writeViewBinder(int minSdk) { 274716ba89e7f459f49ea85070d4710c1d79d715298George Mount mExprModel.seal(this); 27543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar ensureWriter(); 2767ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount Preconditions.checkNotNull(getPackage(), "package cannot be null"); 2777ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount Preconditions.checkNotNull(getClassName(), "base class name cannot be null"); 27896e1c821dd446d1ed78f8ae61131550588f60a24George Mount return mWriter.write(minSdk); 279d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 280d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 281d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public String getPackage() { 2827ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount return mBundle.getBindingClassPackage(); 283d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 284d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 28596e1c821dd446d1ed78f8ae61131550588f60a24George Mount public boolean isMerge() { 28696e1c821dd446d1ed78f8ae61131550588f60a24George Mount return mBundle.isMerge(); 28796e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 28896e1c821dd446d1ed78f8ae61131550588f60a24George Mount 289a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public String getModulePackage() { 290a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar return mModulePackage; 291a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 292a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 293d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public String getLayoutname() { 2943bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar return mBundle.getFileName(); 295d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 296d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 297dea555cf42dc3583604699c8c018d22681f56166George Mount public String getImplementationName() { 2985bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar if (hasVariations()) { 2997ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount return mBundle.getBindingClassName() + mBundle.getConfigName() + "Impl"; 3005bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } else { 3017ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount return mBundle.getBindingClassName(); 3025bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 303d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 3043bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar 305dea555cf42dc3583604699c8c018d22681f56166George Mount public String getClassName() { 3067ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount return mBundle.getBindingClassName(); 30743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 3085bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 3090390898cf7c4fcad255e8cfd6802f722b516cb2cGeorge Mount public String getTag() { 3100390898cf7c4fcad255e8cfd6802f722b516cb2cGeorge Mount return mBundle.getDirectory() + "/" + mBundle.getFileName(); 3115bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 3125bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 3135bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar public boolean hasVariations() { 3143bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar return mBundle.hasVariations(); 3155bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 316716ba89e7f459f49ea85070d4710c1d79d715298George Mount 317716ba89e7f459f49ea85070d4710c1d79d715298George Mount @Override 318716ba89e7f459f49ea85070d4710c1d79d715298George Mount public void resolveListeners() { 319716ba89e7f459f49ea85070d4710c1d79d715298George Mount for (BindingTarget target : mBindingTargets) { 320716ba89e7f459f49ea85070d4710c1d79d715298George Mount for (Binding binding : target.getBindings()) { 321716ba89e7f459f49ea85070d4710c1d79d715298George Mount binding.resolveListeners(); 322716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 323716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 324716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 325d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 326