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; 26731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyarimport android.databinding.tool.processing.Scope; 27731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyarimport android.databinding.tool.processing.scopes.FileScopeProvider; 28c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport android.databinding.tool.store.Location; 29fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.store.ResourceBundle; 3034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport android.databinding.tool.store.ResourceBundle.BindingTargetBundle; 312611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyarimport android.databinding.tool.util.Preconditions; 32fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.writer.LayoutBinderWriter; 3334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport android.databinding.tool.writer.WriterPackage; 34d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 35d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.ArrayList; 3634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport java.util.Collections; 3734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport java.util.Comparator; 385bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyarimport java.util.HashMap; 39d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.List; 40d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 41d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar/** 42d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Keeps all information about the bindings per layout file 43d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar */ 44731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyarpublic class LayoutBinder implements ResolveListenersCallback, FileScopeProvider { 4534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount private static final Comparator<BindingTarget> COMPARE_FIELD_NAME = new Comparator<BindingTarget>() { 4634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount @Override 4734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount public int compare(BindingTarget first, BindingTarget second) { 4834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount final String fieldName1 = WriterPackage.getFieldName(first); 4934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount final String fieldName2 = WriterPackage.getFieldName(second); 5034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount return fieldName1.compareTo(fieldName2); 5134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount } 5234a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount }; 533bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar 54d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar /* 55d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * val pkg: String, val projectPackage: String, val baseClassName: String, 56d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val layoutName:String, val lb: LayoutExprBinding*/ 57d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar private final ExprModel mExprModel; 58d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar private final ExpressionParser mExpressionParser; 59d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar private final List<BindingTarget> mBindingTargets; 6096e1c821dd446d1ed78f8ae61131550588f60a24George Mount private final List<BindingTarget> mSortedBindingTargets; 61a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private String mModulePackage; 62895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar private final HashMap<String, String> mUserDefinedVariables = new HashMap<String, String>(); 63d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 6443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar private LayoutBinderWriter mWriter; 653bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar private ResourceBundle.LayoutFileBundle mBundle; 66c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount private static final String[] sJavaLangClasses = { 67c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Deprecated", 68c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Override", 69c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "SafeVarargs", 70c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "SuppressWarnings", 71c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Appendable", 72c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "AutoCloseable", 73c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "CharSequence", 74c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Cloneable", 75c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Comparable", 76c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Iterable", 77c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Readable", 78c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Runnable", 79c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Thread.UncaughtExceptionHandler", 80c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Boolean", 81c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Byte", 82c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Character", 83c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Character.Subset", 84c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Character.UnicodeBlock", 85c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Class", 86c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ClassLoader", 87c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Compiler", 88c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Double", 89c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Enum", 90c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Float", 91c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "InheritableThreadLocal", 92c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Integer", 93c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Long", 94c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Math", 95c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Number", 96c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Object", 97c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Package", 98c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Process", 99c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ProcessBuilder", 100c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Runtime", 101c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "RuntimePermission", 102c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "SecurityManager", 103c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Short", 104c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "StackTraceElement", 105c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "StrictMath", 106c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "String", 107c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "StringBuffer", 108c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "StringBuilder", 109c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "System", 110c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Thread", 111c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ThreadGroup", 112c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ThreadLocal", 113c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Throwable", 114c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Void", 115c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Thread.State", 116c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ArithmeticException", 117c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ArrayIndexOutOfBoundsException", 118c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ArrayStoreException", 119c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ClassCastException", 120c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ClassNotFoundException", 121c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "CloneNotSupportedException", 122c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "EnumConstantNotPresentException", 123c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Exception", 124c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "IllegalAccessException", 125c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "IllegalArgumentException", 126c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "IllegalMonitorStateException", 127c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "IllegalStateException", 128c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "IllegalThreadStateException", 129c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "IndexOutOfBoundsException", 130c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "InstantiationException", 131c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "InterruptedException", 132c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "NegativeArraySizeException", 133c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "NoSuchFieldException", 134c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "NoSuchMethodException", 135c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "NullPointerException", 136c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "NumberFormatException", 137c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ReflectiveOperationException", 138c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "RuntimeException", 139c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "SecurityException", 140c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "StringIndexOutOfBoundsException", 141c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "TypeNotPresentException", 142c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "UnsupportedOperationException", 143c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "AbstractMethodError", 144c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "AssertionError", 145c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ClassCircularityError", 146c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ClassFormatError", 147c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "Error", 148c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ExceptionInInitializerError", 149c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "IllegalAccessError", 150c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "IncompatibleClassChangeError", 151c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "InstantiationError", 152c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "InternalError", 153c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "LinkageError", 154c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "NoClassDefFoundError", 155c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "NoSuchFieldError", 156c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "NoSuchMethodError", 157c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "OutOfMemoryError", 158c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "StackOverflowError", 159c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "ThreadDeath", 160c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "UnknownError", 161c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "UnsatisfiedLinkError", 162c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "UnsupportedClassVersionError", 163c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "VerifyError", 164c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount "VirtualMachineError", 165c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount }; 16643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 1677ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount public LayoutBinder(ResourceBundle.LayoutFileBundle layoutBundle) { 168731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar try { 169731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar Scope.enter(this); 170731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar mExprModel = new ExprModel(); 171731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar mExpressionParser = new ExpressionParser(mExprModel); 172731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar mBindingTargets = new ArrayList<BindingTarget>(); 173731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar mBundle = layoutBundle; 174731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar mModulePackage = layoutBundle.getModulePackage(); 175731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar // copy over data. 176731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar for (ResourceBundle.NameTypeLocation variable : mBundle.getVariables()) { 177731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar addVariable(variable.name, variable.type, variable.location); 178731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar } 1793bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar 180731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar for (ResourceBundle.NameTypeLocation userImport : mBundle.getImports()) { 181731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar mExprModel.addImport(userImport.name, userImport.type, userImport.location); 182731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar } 183731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar for (String javaLangClass : sJavaLangClasses) { 184731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar mExprModel.addImport(javaLangClass, "java.lang." + javaLangClass, null); 1853bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar } 186731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar for (BindingTargetBundle targetBundle : mBundle.getBindingTargetBundles()) { 187731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar try { 188731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar Scope.enter(targetBundle); 189731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar final BindingTarget bindingTarget = createBindingTarget(targetBundle); 190731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar for (BindingTargetBundle.BindingBundle bindingBundle : targetBundle 191731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar .getBindingBundleList()) { 192731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar bindingTarget.addBinding(bindingBundle.getName(), 193731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar parse(bindingBundle.getExpr(), bindingBundle.getValueLocation())); 194731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar } 195731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar bindingTarget.resolveMultiSetters(); 196731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar } finally { 197731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar Scope.exit(); 198731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar } 199731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar } 200731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar mSortedBindingTargets = new ArrayList<BindingTarget>(mBindingTargets); 201731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar Collections.sort(mSortedBindingTargets, COMPARE_FIELD_NAME); 202731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar } finally { 203731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar Scope.exit(); 2043bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar } 205d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 206d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 2075bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar public void resolveWhichExpressionsAreUsed() { 208895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar List<Expr> used = new ArrayList<Expr>(); 2095bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar for (BindingTarget target : mBindingTargets) { 2105bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar for (Binding binding : target.getBindings()) { 2115bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar binding.getExpr().setIsUsed(true); 2125bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar used.add(binding.getExpr()); 2135bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 2145bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 2155bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar while (!used.isEmpty()) { 2165bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar Expr e = used.remove(used.size() - 1); 2175bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar for (Dependency dep : e.getDependencies()) { 2185bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar if (!dep.getOther().isUsed()) { 2195bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar used.add(dep.getOther()); 2205bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar dep.getOther().setIsUsed(true); 2215bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 2225bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 2235bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 2245bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 2255bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 226c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar public IdentifierExpr addVariable(String name, String type, Location location) { 2272611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar Preconditions.check(!mUserDefinedVariables.containsKey(name), 2285bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar "%s has already been defined as %s", name, type); 229d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar final IdentifierExpr id = mExprModel.identifier(name); 230d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar id.setUserDefinedType(type); 231d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar id.enableDirectInvalidation(); 232c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar if (location != null) { 233c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar id.addLocation(location); 234c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar } 2355bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar mUserDefinedVariables.put(name, type); 236d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return id; 237d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 238d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 2395bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar public HashMap<String, String> getUserDefinedVariables() { 2405bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar return mUserDefinedVariables; 2415bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 2425bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 2433bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar public BindingTarget createBindingTarget(ResourceBundle.BindingTargetBundle targetBundle) { 2443bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar final BindingTarget target = new BindingTarget(targetBundle); 245d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mBindingTargets.add(target); 246d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar target.setModel(mExprModel); 247d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return target; 248d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 249d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 250c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar public Expr parse(String input, @Nullable Location locationInFile) { 251c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar final Expr parsed = mExpressionParser.parse(input, locationInFile); 252d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar parsed.setBindingExpression(true); 253d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return parsed; 254d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 255d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 256d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public List<BindingTarget> getBindingTargets() { 257d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return mBindingTargets; 258d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 259d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 26096e1c821dd446d1ed78f8ae61131550588f60a24George Mount public List<BindingTarget> getSortedTargets() { 26196e1c821dd446d1ed78f8ae61131550588f60a24George Mount return mSortedBindingTargets; 26296e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 26396e1c821dd446d1ed78f8ae61131550588f60a24George Mount 264d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public boolean isEmpty() { 265d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return mExprModel.size() == 0; 266d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 267d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 268d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public ExprModel getModel() { 269d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return mExprModel; 270d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 271d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 27243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar private void ensureWriter() { 27343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar if (mWriter == null) { 27443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar mWriter = new LayoutBinderWriter(this); 27543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 27643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 2773bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar 278e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount public void sealModel() { 279e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount mExprModel.seal(this); 280e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount } 281e4cd38824a6627b9fef229c549c636e35ad63b5fGeorge Mount 2828b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar public String writeViewBinderBaseClass(boolean forLibrary) { 28343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar ensureWriter(); 2848b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar return mWriter.writeBaseClass(forLibrary); 28543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 28643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar 28796e1c821dd446d1ed78f8ae61131550588f60a24George Mount public String writeViewBinder(int minSdk) { 28843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar ensureWriter(); 2897ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount Preconditions.checkNotNull(getPackage(), "package cannot be null"); 2907ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount Preconditions.checkNotNull(getClassName(), "base class name cannot be null"); 29196e1c821dd446d1ed78f8ae61131550588f60a24George Mount return mWriter.write(minSdk); 292d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 293d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 294d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public String getPackage() { 2957ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount return mBundle.getBindingClassPackage(); 296d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 297d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 29896e1c821dd446d1ed78f8ae61131550588f60a24George Mount public boolean isMerge() { 29996e1c821dd446d1ed78f8ae61131550588f60a24George Mount return mBundle.isMerge(); 30096e1c821dd446d1ed78f8ae61131550588f60a24George Mount } 30196e1c821dd446d1ed78f8ae61131550588f60a24George Mount 302a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public String getModulePackage() { 303a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar return mModulePackage; 304a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 305a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 306d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public String getLayoutname() { 3073bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar return mBundle.getFileName(); 308d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 309d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 310dea555cf42dc3583604699c8c018d22681f56166George Mount public String getImplementationName() { 3115bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar if (hasVariations()) { 3127ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount return mBundle.getBindingClassName() + mBundle.getConfigName() + "Impl"; 3135bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } else { 3147ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount return mBundle.getBindingClassName(); 3155bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 316d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 3173bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar 318dea555cf42dc3583604699c8c018d22681f56166George Mount public String getClassName() { 3197ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount return mBundle.getBindingClassName(); 32043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 3215bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 3220390898cf7c4fcad255e8cfd6802f722b516cb2cGeorge Mount public String getTag() { 3230390898cf7c4fcad255e8cfd6802f722b516cb2cGeorge Mount return mBundle.getDirectory() + "/" + mBundle.getFileName(); 3245bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 3255bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar 3265bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar public boolean hasVariations() { 3273bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar return mBundle.hasVariations(); 3285bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar } 329716ba89e7f459f49ea85070d4710c1d79d715298George Mount 330716ba89e7f459f49ea85070d4710c1d79d715298George Mount @Override 331716ba89e7f459f49ea85070d4710c1d79d715298George Mount public void resolveListeners() { 332716ba89e7f459f49ea85070d4710c1d79d715298George Mount for (BindingTarget target : mBindingTargets) { 333716ba89e7f459f49ea85070d4710c1d79d715298George Mount for (Binding binding : target.getBindings()) { 334716ba89e7f459f49ea85070d4710c1d79d715298George Mount binding.resolveListeners(); 335716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 336716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 337716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 338731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar 339731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar @Override 340731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar public String provideScopeFilePath() { 341731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar return mBundle.getAbsoluteFilePath(); 342731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar } 343d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 344