summaryrefslogtreecommitdiff
path: root/compiler/src/main/java/android/databinding/tool/CompilerChef.java
diff options
context:
space:
mode:
authorGeorge Mount <mount@google.com>2016-02-18 14:33:37 -0800
committerGeorge Mount <mount@google.com>2016-03-08 15:38:00 -0800
commitbb4a033fcd5cd20e5be46ef8ead442dc7db2454d (patch)
treea6eebe0a848983d8dad5662f674959e7e76b2c80 /compiler/src/main/java/android/databinding/tool/CompilerChef.java
parentb7eeedbfadec03792551014e9dfa2bd384fc21a3 (diff)
downloaddata-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.java38
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";