diff options
author | Yigit Boyar <yboyar@google.com> | 2019-08-26 17:24:09 -0700 |
---|---|---|
committer | Yigit Boyar <yboyar@google.com> | 2019-08-27 13:23:08 -0700 |
commit | 6aa6469d2eda6dd0b845d4d6c0c303924fffdb91 (patch) | |
tree | b253507f9272f6f5920dbdee980e284ca2fc2c11 /compiler | |
parent | 2e17092004912bd9c6b5ccfd0e46b262166f7a24 (diff) | |
download | data-binding-6aa6469d2eda6dd0b845d4d6c0c303924fffdb91.tar.gz |
Allow setters/adapters in <include tags for binding
This CL fixes a missing feature/bug where if an <include tag resolves to a Binding
class, it would not support any binding adapters but worked perfectly if included
layout is not a binding layout.
This CL moves it to use a common architecture where if a binding target is a view
binding, we'll try to unroll it to its getRoot method if a setter cannot be found
in the binding class.
Bug: 133390436
Test: IncludeTagTest.java
Change-Id: I26e5b458303a185f1f3fa42c3e4fd0790d601dd7
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/src/main/java/android/databinding/tool/Binding.java | 46 | ||||
-rw-r--r-- | compiler/src/main/java/android/databinding/tool/store/SetterStore.java | 86 |
2 files changed, 75 insertions, 57 deletions
diff --git a/compiler/src/main/java/android/databinding/tool/Binding.java b/compiler/src/main/java/android/databinding/tool/Binding.java index 3c2ed67e..530b6b7c 100644 --- a/compiler/src/main/java/android/databinding/tool/Binding.java +++ b/compiler/src/main/java/android/databinding/tool/Binding.java @@ -120,9 +120,7 @@ public class Binding implements LocationScopeProvider { private void resolveSetterCall() { ModelClass viewType = mTarget.getResolvedType(); - if ("android:visibility".equals(mName) && viewType != null && viewType.isViewDataBinding()) { - mSetterCall = new IncludeVisibilityCall(); - } else if (viewType != null && viewType.getExtendsViewStub()) { + if (viewType != null && viewType.getExtendsViewStub()) { mExpr = mExpr.unwrapObservableField(); if (isListenerAttribute(mName)) { ModelAnalyzer modelAnalyzer = ModelAnalyzer.getInstance(); @@ -361,46 +359,4 @@ public class Binding implements LocationScopeProvider { return mWrappedCall.getDescription(); } } - - private static class IncludeVisibilityCall extends SetterCall { - - @Override - public boolean requiresOldValue() { - return false; - } - - @Override - public ModelClass[] getParameterTypes() { - return new ModelClass[] { - ModelAnalyzer.getInstance().loadPrimitive("int") - }; - } - - @Override - public String getBindingAdapterInstanceClass() { - return null; - } - - @Override - public String getDescription() { - return "setVisibility(value)"; - } - - @Override - protected String toJavaInternal(String componentExpression, String viewExpression, - String converted) { - return viewExpression + ".getRoot().setVisibility(" + converted + ")"; - } - - @Override - protected String toJavaInternal(String componentExpression, String viewExpression, - String oldValue, String converted) { - return null; - } - - @Override - public int getMinApi() { - return 0; - } - } } diff --git a/compiler/src/main/java/android/databinding/tool/store/SetterStore.java b/compiler/src/main/java/android/databinding/tool/store/SetterStore.java index c04d73db..12a397c0 100644 --- a/compiler/src/main/java/android/databinding/tool/store/SetterStore.java +++ b/compiler/src/main/java/android/databinding/tool/store/SetterStore.java @@ -25,10 +25,19 @@ import android.databinding.tool.util.GenerationalClassUtil; import android.databinding.tool.util.L; import android.databinding.tool.util.Preconditions; import android.databinding.tool.util.StringUtils; - import com.android.annotations.NonNull; import com.android.annotations.Nullable; +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.ArrayType; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.Types; import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; @@ -45,17 +54,6 @@ import java.util.Set; import java.util.TreeMap; import java.util.stream.Collectors; -import javax.annotation.processing.ProcessingEnvironment; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.ArrayType; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Types; - public class SetterStore { private static final int ASSIGNABLE_CONVERSION = 1; private final BindingAdapterStore mStore; @@ -625,6 +623,18 @@ public class SetterStore { bestSetter.setterCall.setConverter(conversionMethod); } + if (bestSetter.setterCall == null && viewType.isViewDataBinding()) { + // if it is a binding, try to find setter on the view class. + SetterCall rootViewSetter = getSetterCall( + attribute, + viewType.findInstanceGetter("getRoot").getReturnType(), + valueType, + imports); + if (rootViewSetter != null) { + // replace with a root view getter and return it + return new ViewBindingRootViewSetterCall(rootViewSetter); + } + } return bestSetter.setterCall; } @@ -2091,4 +2101,56 @@ public class SetterStore { this.viewType = viewType; } } + + /** + * A ViewBinding can support setters on its root view. This wrapper is injected when include tag + * has a binding on directly its view. + */ + private static class ViewBindingRootViewSetterCall extends SetterCall { + + private final SetterCall mWrapped; + + public ViewBindingRootViewSetterCall(SetterCall wrapped) { + mWrapped = wrapped; + } + + @Override + public boolean requiresOldValue() { + return mWrapped.requiresOldValue(); + } + + @Override + public ModelClass[] getParameterTypes() { + return mWrapped.getParameterTypes(); + } + + @Override + public String getBindingAdapterInstanceClass() { + return mWrapped.getBindingAdapterInstanceClass(); + } + + @Override + public String getDescription() { + return mWrapped.getDescription(); + } + + @Override + protected String toJavaInternal(String componentExpression, String viewExpression, + String converted) { + return mWrapped.toJavaInternal(componentExpression, viewExpression + ".getRoot()", + converted); + } + + @Override + protected String toJavaInternal(String componentExpression, String viewExpression, + String oldValue, String converted) { + return mWrapped.toJavaInternal(componentExpression, viewExpression + ".getRoot()", + oldValue, converted); + } + + @Override + public int getMinApi() { + return mWrapped.getMinApi(); + } + } } |