diff options
author | George Mount <mount@google.com> | 2016-02-18 14:33:37 -0800 |
---|---|---|
committer | George Mount <mount@google.com> | 2016-03-08 15:38:00 -0800 |
commit | bb4a033fcd5cd20e5be46ef8ead442dc7db2454d (patch) | |
tree | a6eebe0a848983d8dad5662f674959e7e76b2c80 /compiler/src/main/java/android/databinding/tool/CompilerChef.java | |
parent | b7eeedbfadec03792551014e9dfa2bd384fc21a3 (diff) | |
download | data-binding-bb4a033fcd5cd20e5be46ef8ead442dc7db2454d.tar.gz |
Have two-way binding use localized variables to prevent NPE.
Bug 26962999
Two-way binding was using the inverted expressions directly
without localizing variables. That meant that if there was
a variable set to null during evaluation, it may get a
NullPointerException even though it checked for null
on the value previously. This CL localizes the variables
so that cannot happen.
Change-Id: Ia55955ce0f1cb750e6a678e72e0cda03f0e3c9b6
Diffstat (limited to 'compiler/src/main/java/android/databinding/tool/CompilerChef.java')
-rw-r--r-- | compiler/src/main/java/android/databinding/tool/CompilerChef.java | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/compiler/src/main/java/android/databinding/tool/CompilerChef.java b/compiler/src/main/java/android/databinding/tool/CompilerChef.java index b7456da0..278492ad 100644 --- a/compiler/src/main/java/android/databinding/tool/CompilerChef.java +++ b/compiler/src/main/java/android/databinding/tool/CompilerChef.java @@ -23,6 +23,7 @@ import android.databinding.tool.writer.DataBinderWriter; import android.databinding.tool.writer.DynamicUtilWriter; import android.databinding.tool.writer.JavaFileWriter; +import java.util.HashMap; import java.util.Set; /** @@ -69,6 +70,7 @@ public class CompilerChef { chef.mResourceBundle = bundle; chef.mFileWriter = fileWriter; chef.mResourceBundle.validateMultiResLayouts(); + chef.pushClassesToAnalyzer(); return chef; } @@ -89,6 +91,42 @@ public class CompilerChef { return mResourceBundle != null && mResourceBundle.getLayoutBundles().size() > 0; } + /** + * Injects ViewDataBinding subclasses to the ModelAnalyzer so that they can be + * analyzed prior to creation. This is useful for resolving variable setters and + * View fields during compilation. + */ + private void pushClassesToAnalyzer() { + ModelAnalyzer analyzer = ModelAnalyzer.getInstance(); + for (String layoutName : mResourceBundle.getLayoutBundles().keySet()) { + ResourceBundle.LayoutFileBundle layoutFileBundle = + mResourceBundle.getLayoutBundles().get(layoutName).get(0); + final HashMap<String, String> imports = new HashMap<String, String>(); + for (ResourceBundle.NameTypeLocation imp : layoutFileBundle.getImports()) { + imports.put(imp.name, imp.type); + } + final HashMap<String, String> variables = new HashMap<String, String>(); + for (ResourceBundle.VariableDeclaration variable : layoutFileBundle.getVariables()) { + final String variableName = variable.name; + String type = variable.type; + if (imports.containsKey(type)) { + type = imports.get(type); + } + variables.put(variableName, type); + } + final HashMap<String, String> fields = new HashMap<String, String>(); + for (ResourceBundle.BindingTargetBundle bindingTargetBundle : + layoutFileBundle.getBindingTargetBundles()) { + if (bindingTargetBundle.getId() != null) { + fields.put(bindingTargetBundle.getId(), bindingTargetBundle.getInterfaceType()); + } + } + final String className = layoutFileBundle.getBindingClassPackage() + "." + + layoutFileBundle.getBindingClassName(); + analyzer.injectViewDataBinding(className, variables, fields); + } + } + public void writeDataBinderMapper(int minSdk, BRWriter brWriter) { ensureDataBinder(); final String pkg = "android.databinding"; |