summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/src/main/java/android/databinding/tool/DataBinder.java2
-rw-r--r--compiler/src/main/java/android/databinding/tool/LayoutBinder.java30
-rw-r--r--compiler/src/main/java/android/databinding/tool/store/LayoutFileParser.java22
-rw-r--r--compiler/src/main/java/android/databinding/tool/store/ResourceBundle.java138
-rw-r--r--compiler/src/main/kotlin/android/databinding/tool/util/XmlEditor.kt2
-rw-r--r--compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt6
-rw-r--r--compiler/src/test/java/android/databinding/tool/MockLayoutBinder.java3
-rw-r--r--library/src/main/java/android/databinding/ViewDataBinding.java2
8 files changed, 139 insertions, 66 deletions
diff --git a/compiler/src/main/java/android/databinding/tool/DataBinder.java b/compiler/src/main/java/android/databinding/tool/DataBinder.java
index 368b83e5..49acdb8f 100644
--- a/compiler/src/main/java/android/databinding/tool/DataBinder.java
+++ b/compiler/src/main/java/android/databinding/tool/DataBinder.java
@@ -39,7 +39,7 @@ public class DataBinder {
for (Map.Entry<String, List<ResourceBundle.LayoutFileBundle>> entry :
resourceBundle.getLayoutBundles().entrySet()) {
for (ResourceBundle.LayoutFileBundle bundle : entry.getValue()) {
- mLayoutBinders.add(new LayoutBinder(resourceBundle, bundle));
+ mLayoutBinders.add(new LayoutBinder(bundle));
}
}
}
diff --git a/compiler/src/main/java/android/databinding/tool/LayoutBinder.java b/compiler/src/main/java/android/databinding/tool/LayoutBinder.java
index 8271d6d9..d8669271 100644
--- a/compiler/src/main/java/android/databinding/tool/LayoutBinder.java
+++ b/compiler/src/main/java/android/databinding/tool/LayoutBinder.java
@@ -55,25 +55,18 @@ public class LayoutBinder {
private final ExpressionParser mExpressionParser;
private final List<BindingTarget> mBindingTargets;
private final List<BindingTarget> mSortedBindingTargets;
- private String mPackage;
private String mModulePackage;
- private String mProjectPackage;
- private String mBaseClassName;
private final HashMap<String, String> mUserDefinedVariables = new HashMap<String, String>();
private LayoutBinderWriter mWriter;
private ResourceBundle.LayoutFileBundle mBundle;
- public LayoutBinder(ResourceBundle resourceBundle,
- ResourceBundle.LayoutFileBundle layoutBundle) {
+ public LayoutBinder(ResourceBundle.LayoutFileBundle layoutBundle) {
mExprModel = new ExprModel();
mExpressionParser = new ExpressionParser(mExprModel);
mBindingTargets = new ArrayList<BindingTarget>();
mBundle = layoutBundle;
- mProjectPackage = resourceBundle.getAppPackage();
mModulePackage = layoutBundle.getModulePackage();
- mPackage = layoutBundle.getModulePackage() + ".databinding";
- mBaseClassName = ParserHelper.INSTANCE$.toClassName(layoutBundle.getFileName()) + "Binding";
// copy over data.
for (Map.Entry<String, String> variable : mBundle.getVariables().entrySet()) {
addVariable(variable.getKey(), variable.getValue());
@@ -170,14 +163,13 @@ public class LayoutBinder {
public String writeViewBinder(int minSdk) {
mExprModel.seal();
ensureWriter();
- Preconditions.checkNotNull(mPackage, "package cannot be null");
- Preconditions.checkNotNull(mProjectPackage, "project package cannot be null");
- Preconditions.checkNotNull(mBaseClassName, "base class name cannot be null");
+ Preconditions.checkNotNull(getPackage(), "package cannot be null");
+ Preconditions.checkNotNull(getClassName(), "base class name cannot be null");
return mWriter.write(minSdk);
}
public String getPackage() {
- return mPackage;
+ return mBundle.getBindingClassPackage();
}
public boolean isMerge() {
@@ -188,28 +180,20 @@ public class LayoutBinder {
return mModulePackage;
}
- public void setPackage(String aPackage) {
- mPackage = aPackage;
- }
-
- public String getProjectPackage() {
- return mProjectPackage;
- }
-
public String getLayoutname() {
return mBundle.getFileName();
}
public String getImplementationName() {
if (hasVariations()) {
- return mBaseClassName + mBundle.getConfigName() + "Impl";
+ return mBundle.getBindingClassName() + mBundle.getConfigName() + "Impl";
} else {
- return mBaseClassName;
+ return mBundle.getBindingClassName();
}
}
public String getClassName() {
- return mBaseClassName;
+ return mBundle.getBindingClassName();
}
public String getTag() {
diff --git a/compiler/src/main/java/android/databinding/tool/store/LayoutFileParser.java b/compiler/src/main/java/android/databinding/tool/store/LayoutFileParser.java
index 05bcdd73..192ec77e 100644
--- a/compiler/src/main/java/android/databinding/tool/store/LayoutFileParser.java
+++ b/compiler/src/main/java/android/databinding/tool/store/LayoutFileParser.java
@@ -24,7 +24,6 @@ import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
-import android.databinding.tool.store.ResourceBundle.BindingTargetBundle;
import android.databinding.tool.util.L;
import android.databinding.tool.util.ParserHelper;
import android.databinding.tool.util.XmlEditor;
@@ -120,7 +119,7 @@ public class LayoutFileParser {
for (Node parent : bindingNodes) {
NamedNodeMap attributes = parent.getAttributes();
String nodeName = parent.getNodeName();
- String className;
+ String viewName = null;
String includedLayoutName = null;
final Node id = attributes.getNamedItem("android:id");
final String tag;
@@ -133,25 +132,23 @@ public class LayoutFileParser {
// if user is binding something there, there MUST be a layout file to be
// generated.
String layoutName = includeValue.substring(LAYOUT_PREFIX.length());
- className = pkg + ".databinding." +
- ParserHelper.INSTANCE$.toClassName(layoutName) + "Binding";
includedLayoutName = layoutName;
tag = nodeTagMap.get(parent.getParentNode());
} else {
- className = getFullViewClassName(parent);
+ viewName = getViewName(parent);
if (doc.getDocumentElement() == parent || "merge".equals(parent.getParentNode().getNodeName())) {
int index = rootDone ? tagNumber++ : 0;
rootDone = true;
tag = newTag + "_" + index;
} else {
- tag = "bindingTag" + tagNumber;
+ tag = "binding_" + tagNumber;
tagNumber++;
}
}
final Node originalTag = attributes.getNamedItem("android:tag");
final ResourceBundle.BindingTargetBundle bindingTargetBundle =
bundle.createBindingTarget(id == null ? null : id.getNodeValue(),
- className, true, tag, originalTag == null ? null : originalTag.getNodeValue());
+ viewName, true, tag, originalTag == null ? null : originalTag.getNodeValue());
nodeTagMap.put(parent, tag);
bindingTargetBundle.setIncludedLayout(includedLayoutName);
@@ -171,7 +168,7 @@ public class LayoutFileParser {
for (Node node : idNodes) {
if (!bindingNodes.contains(node) && !"include".equals(node.getNodeName())) {
final Node id = node.getAttributes().getNamedItem("android:id");
- final String className = getFullViewClassName(node);
+ final String className = getViewName(node);
bundle.createBindingTarget(id.getNodeValue(), className, true, null, null);
}
}
@@ -217,7 +214,7 @@ public class LayoutFileParser {
return result;
}
- private String getFullViewClassName(Node viewNode) {
+ private String getViewName(Node viewNode) {
String viewName = viewNode.getNodeName();
if ("view".equals(viewName)) {
Node classNode = viewNode.getAttributes().getNamedItem("class");
@@ -227,13 +224,6 @@ public class LayoutFileParser {
viewName = classNode.getNodeValue();
}
}
- if (viewName.indexOf('.') == -1) {
- if (ObjectUtils.equals(viewName, "View") || ObjectUtils.equals(viewName, "ViewGroup") ||
- ObjectUtils.equals(viewName, "ViewStub")) {
- return "android.view." + viewName;
- }
- return "android.widget." + viewName;
- }
return viewName;
}
diff --git a/compiler/src/main/java/android/databinding/tool/store/ResourceBundle.java b/compiler/src/main/java/android/databinding/tool/store/ResourceBundle.java
index d79d1d90..0de1d53c 100644
--- a/compiler/src/main/java/android/databinding/tool/store/ResourceBundle.java
+++ b/compiler/src/main/java/android/databinding/tool/store/ResourceBundle.java
@@ -17,8 +17,6 @@ import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
-import android.databinding.tool.reflection.ModelAnalyzer;
-import android.databinding.tool.reflection.ModelClass;
import android.databinding.tool.util.L;
import android.databinding.tool.util.ParserHelper;
@@ -78,6 +76,23 @@ public class ResourceBundle implements Serializable {
}
public void validateMultiResLayouts() {
+ for (List<LayoutFileBundle> layoutFileBundles : mLayoutBundles.values()) {
+ for (LayoutFileBundle layoutFileBundle : layoutFileBundles) {
+ for (BindingTargetBundle target : layoutFileBundle.getBindingTargetBundles()) {
+ if (target.isBinder()) {
+ List<LayoutFileBundle> boundTo =
+ mLayoutBundles.get(target.getIncludedLayout());
+ if (boundTo == null || boundTo.isEmpty()) {
+ L.e("There is no binding for %s", target.getIncludedLayout());
+ } else {
+ String binding = boundTo.get(0).getFullBindingClass();
+ target.setInterfaceType(binding);
+ }
+ }
+ }
+ }
+ }
+
final Iterable<Map.Entry<String, List<LayoutFileBundle>>> multiResLayouts = Iterables
.filter(mLayoutBundles.entrySet(),
new Predicate<Map.Entry<String, List<LayoutFileBundle>>>() {
@@ -92,9 +107,20 @@ public class ResourceBundle implements Serializable {
// and all variables have the same name
Map<String, String> variableTypes = new HashMap<String, String>();
Map<String, String> importTypes = new HashMap<String, String>();
+ String bindingClass = null;
for (LayoutFileBundle bundle : bundles.getValue()) {
bundle.mHasVariations = true;
+ if (bindingClass == null) {
+ bindingClass = bundle.getFullBindingClass();
+ } else {
+ if (!bindingClass.equals(bundle.getFullBindingClass())) {
+ L.e("Binding class names must match. Layout file for %s have " +
+ "different binding class names %s and %s",
+ bundle.getFileName(),
+ bindingClass, bundle.getFullBindingClass());
+ }
+ }
for (Map.Entry<String, String> variable : bundle.mVariables.entrySet()) {
String existing = variableTypes.get(variable.getKey());
Preconditions
@@ -140,28 +166,28 @@ public class ResourceBundle implements Serializable {
L.d("validating ids for %s", bundles.getKey());
for (LayoutFileBundle bundle : bundles.getValue()) {
for (BindingTargetBundle target : bundle.mBindingTargetBundles) {
- L.d("checking %s %s %s", target.getId(), target.mFullClassName,
+ L.d("checking %s %s %s", target.getId(), target.getFullClassName(),
target.isBinder());
if (target.mId != null) {
if (target.isBinder()) {
- Preconditions.checkState(!viewBindingIds.contains(target.mFullClassName),
+ Preconditions.checkState(!viewBindingIds.contains(target.getFullClassName()),
"Cannot use the same id for a View and an include tag. Error " +
"in file %s / %s", bundle.mFileName, bundle.mConfigName);
- includeBindingIds.add(target.mFullClassName);
+ includeBindingIds.add(target.getFullClassName());
} else {
- Preconditions.checkState(!includeBindingIds.contains(target.mFullClassName),
+ Preconditions.checkState(!includeBindingIds.contains(target.getFullClassName()),
"Cannot use the same id for a View and an include tag. Error in "
+ "file %s / %s", bundle.mFileName, bundle.mConfigName);
- viewBindingIds.add(target.mFullClassName);
+ viewBindingIds.add(target.getFullClassName());
}
String existingType = viewTypes.get(target.mId);
if (existingType == null) {
- L.d("assigning %s as %s", target.getId(), target.mFullClassName);
- viewTypes.put(target.mId, target.mFullClassName);
+ L.d("assigning %s as %s", target.getId(), target.getFullClassName());
+ viewTypes.put(target.mId, target.getFullClassName());
if (target.isBinder()) {
includes.put(target.mId, target.getIncludedLayout());
}
- } else if (!existingType.equals(target.mFullClassName)) {
+ } else if (!existingType.equals(target.getFullClassName())) {
if (target.isBinder()) {
L.d("overriding %s as base binder", target.getId());
viewTypes.put(target.mId,
@@ -180,10 +206,18 @@ public class ResourceBundle implements Serializable {
for (Map.Entry<String, String> viewType : viewTypes.entrySet()) {
BindingTargetBundle target = bundle.getBindingTargetById(viewType.getKey());
if (target == null) {
- bundle.createBindingTarget(viewType.getKey(), viewType.getValue(), false,
- null, null).setIncludedLayout(includes.get(viewType.getKey()));
+ String include = includes.get(viewType.getKey());
+ if (include == null) {
+ bundle.createBindingTarget(viewType.getKey(), viewType.getValue(),
+ false, null, null);
+ } else {
+ BindingTargetBundle bindingTargetBundle = bundle.createBindingTarget(
+ viewType.getKey(), null, false, null, null);
+ bindingTargetBundle.setIncludedLayout(includes.get(viewType.getKey()));
+ bindingTargetBundle.setInterfaceType(viewType.getValue());
+ }
} else {
- L.d("setting interface type on %s (%s) as %s", target.mId, target.mFullClassName, viewType.getValue());
+ L.d("setting interface type on %s (%s) as %s", target.mId, target.getFullClassName(), viewType.getValue());
target.setInterfaceType(viewType.getValue());
}
}
@@ -219,6 +253,19 @@ public class ResourceBundle implements Serializable {
public String mModulePackage;
private String mConfigName;
+ // The binding class as given by the user
+ @XmlAttribute(name="bindingClass", required = false)
+ public String mBindingClass;
+
+ // The full package and class name as determined from mBindingClass and mModulePackage
+ private String mFullBindingClass;
+
+ // The simple binding class name as determined from mBindingClass and mModulePackage
+ private String mBindingClassName;
+
+ // The package of the binding class as determined from mBindingClass and mModulePackage
+ private String mBindingPackage;
+
@XmlAttribute(name="directory", required = true)
public String mDirectory;
public boolean mHasVariations;
@@ -258,9 +305,9 @@ public class ResourceBundle implements Serializable {
mImports.put(alias, type);
}
- public BindingTargetBundle createBindingTarget(String id, String fullClassName,
+ public BindingTargetBundle createBindingTarget(String id, String viewName,
boolean used, String tag, String originalTag) {
- BindingTargetBundle target = new BindingTargetBundle(id, fullClassName, used, tag,
+ BindingTargetBundle target = new BindingTargetBundle(id, viewName, used, tag,
originalTag);
mBindingTargetBundles.add(target);
return target;
@@ -307,6 +354,40 @@ public class ResourceBundle implements Serializable {
return mIsMerge;
}
+ public String getBindingClassName() {
+ if (mBindingClassName == null) {
+ String fullClass = getFullBindingClass();
+ int dotIndex = fullClass.lastIndexOf('.');
+ mBindingClassName = fullClass.substring(dotIndex + 1);
+ }
+ return mBindingClassName;
+ }
+
+ public String getBindingClassPackage() {
+ if (mBindingPackage == null) {
+ String fullClass = getFullBindingClass();
+ int dotIndex = fullClass.lastIndexOf('.');
+ mBindingPackage = fullClass.substring(0, dotIndex);
+ }
+ return mBindingPackage;
+ }
+
+ private String getFullBindingClass() {
+ if (mFullBindingClass == null) {
+ if (mBindingClass == null) {
+ mFullBindingClass = getModulePackage() + ".databinding." +
+ ParserHelper.INSTANCE$.toClassName(getFileName()) + "Binding";
+ } else if (mBindingClass.startsWith(".")) {
+ mFullBindingClass = getModulePackage() + mBindingClass;
+ } else if (mBindingClass.indexOf('.') < 0) {
+ mFullBindingClass = getModulePackage() + ".databinding." + mBindingClass;
+ } else {
+ mFullBindingClass = mBindingClass;
+ }
+ }
+ return mFullBindingClass;
+ }
+
public List<BindingTargetBundle> getBindingTargetBundles() {
return mBindingTargetBundles;
}
@@ -385,8 +466,9 @@ public class ResourceBundle implements Serializable {
public String mTag;
@XmlAttribute(name="originalTag")
public String mOriginalTag;
- @XmlAttribute(name="boundClass", required = true)
- public String mFullClassName;
+ @XmlAttribute(name="view", required = false)
+ public String mViewName;
+ private String mFullClassName;
public boolean mUsed = true;
@XmlElementWrapper(name="Expressions")
@XmlElement(name="Expression")
@@ -398,10 +480,10 @@ public class ResourceBundle implements Serializable {
// For XML serialization
public BindingTargetBundle() {}
- public BindingTargetBundle(String id, String fullClassName, boolean used,
+ public BindingTargetBundle(String id, String viewName, boolean used,
String tag, String originalTag) {
mId = id;
- mFullClassName = fullClassName;
+ mViewName = viewName;
mUsed = used;
mTag = tag;
mOriginalTag = originalTag;
@@ -440,6 +522,24 @@ public class ResourceBundle implements Serializable {
}
public String getFullClassName() {
+ if (mFullClassName == null) {
+ if (isBinder()) {
+ mFullClassName = mInterfaceType;
+ } else if (mViewName.indexOf('.') == -1) {
+ if ("View".equals(mViewName) || "ViewGroup".equals(mViewName) ||
+ "ViewStub".equals(mViewName)) {
+ mFullClassName = "android.view." + mViewName;
+ } else {
+ mFullClassName = "android.widget." + mViewName;
+ }
+ } else {
+ mFullClassName = mViewName;
+ }
+ }
+ if (mFullClassName == null) {
+ L.e("Unexpected full class name = null. view = %s, interface = %s, layout = %s",
+ mViewName, mInterfaceType, mIncludedLayout);
+ }
return mFullClassName;
}
diff --git a/compiler/src/main/kotlin/android/databinding/tool/util/XmlEditor.kt b/compiler/src/main/kotlin/android/databinding/tool/util/XmlEditor.kt
index 9b7b3a93..01a25aa9 100644
--- a/compiler/src/main/kotlin/android/databinding/tool/util/XmlEditor.kt
+++ b/compiler/src/main/kotlin/android/databinding/tool/util/XmlEditor.kt
@@ -204,7 +204,7 @@ object XmlEditor {
tag = ""
} else {
val index = bindingIndex++;
- tag = "android:tag=\"bindingTag${index}\"";
+ tag = "android:tag=\"binding_${index}\"";
}
it.attributes?.forEach {
if (!replaced && tagWillFit(it.start, it.end, tag)) {
diff --git a/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt b/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt
index 4f8183b3..d5fade48 100644
--- a/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt
+++ b/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt
@@ -316,8 +316,8 @@ fun <T> FlagSet.mapOr(other : FlagSet, cb : (suffix : String, index : Int) -> T)
fun indexFromTag(tag : String) : kotlin.Int {
val startIndex : kotlin.Int
- if (tag.startsWith("bindingTag")) {
- startIndex = "bindingTag".length();
+ if (tag.startsWith("binding_")) {
+ startIndex = "binding_".length();
} else {
startIndex = tag.lastIndexOf('_') + 1
}
@@ -512,7 +512,7 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
tab("this.${it.fieldName}.setContainingBinding(this);")
}
if (it.supportsTag() && it.getTag() != null &&
- (rootTagsSupported || it.getTag().startsWith("bindingTag"))) {
+ (rootTagsSupported || it.getTag().startsWith("binding_"))) {
val originalTag = it.getOriginalTag();
var tagValue = "null"
if (originalTag != null) {
diff --git a/compiler/src/test/java/android/databinding/tool/MockLayoutBinder.java b/compiler/src/test/java/android/databinding/tool/MockLayoutBinder.java
index a172ca59..36b92fe0 100644
--- a/compiler/src/test/java/android/databinding/tool/MockLayoutBinder.java
+++ b/compiler/src/test/java/android/databinding/tool/MockLayoutBinder.java
@@ -18,7 +18,6 @@ import android.databinding.tool.store.ResourceBundle;
public class MockLayoutBinder extends LayoutBinder {
public MockLayoutBinder() {
- super(new ResourceBundle("com.test"),
- new ResourceBundle.LayoutFileBundle("blah.xml", "layout", "com.test.submodule", false));
+ super(new ResourceBundle.LayoutFileBundle("blah.xml", "layout", "com.test.submodule", false));
}
}
diff --git a/library/src/main/java/android/databinding/ViewDataBinding.java b/library/src/main/java/android/databinding/ViewDataBinding.java
index 8fa5fa98..b2dbd6a8 100644
--- a/library/src/main/java/android/databinding/ViewDataBinding.java
+++ b/library/src/main/java/android/databinding/ViewDataBinding.java
@@ -43,7 +43,7 @@ public abstract class ViewDataBinding {
* Prefix for android:tag on Views with binding. The root View and include tags will not have
* android:tag attributes and will use ids instead.
*/
- public static final String BINDING_TAG_PREFIX = "bindingTag";
+ public static final String BINDING_TAG_PREFIX = "binding_";
// The length of BINDING_TAG_PREFIX prevents calling length repeatedly.
private static final int BINDING_NUMBER_START = BINDING_TAG_PREFIX.length();