summaryrefslogtreecommitdiff
path: root/compiler/src/main/java/android/databinding
diff options
context:
space:
mode:
authorYigit Boyar <yboyar@google.com>2018-03-20 11:08:44 -0700
committerYigit Boyar <yboyar@google.com>2018-03-30 16:13:06 -0700
commit38a2cc526274fa18ea807ca9b807a632a119dd54 (patch)
treecb554719d61439143cbc449fa98187be22326d97 /compiler/src/main/java/android/databinding
parentb7bc711dd022e5338d0d58595148cbacc792d9d9 (diff)
downloaddata-binding-38a2cc526274fa18ea807ca9b807a632a119dd54.tar.gz
Data Binding Android X support
This CL adds partial support for Android X. We duplicate baseLibrary and extensions (runtime libs) to have copies that are in the androidX namespace. Gradle picks the right version to include based on shared androidX flag. Right now, we have only 1 test that use androidX (DataBindingIncrementalTest) so all other tests still use the old package. I'll add testing for androidX in a followup CL. Bug: 77166878 Test: existing tests pass Change-Id: I77ec65b872cae0821513ca78ef9b6ab1b0300ed1
Diffstat (limited to 'compiler/src/main/java/android/databinding')
-rw-r--r--compiler/src/main/java/android/databinding/annotationprocessor/ProcessBindable.java17
-rw-r--r--compiler/src/main/java/android/databinding/annotationprocessor/ProcessDataBinding.java8
-rw-r--r--compiler/src/main/java/android/databinding/annotationprocessor/ProcessMethodAdapters.java206
-rw-r--r--compiler/src/main/java/android/databinding/tool/Binding.java6
-rw-r--r--compiler/src/main/java/android/databinding/tool/CompilerChef.java33
-rw-r--r--compiler/src/main/java/android/databinding/tool/Context.kt27
-rw-r--r--compiler/src/main/java/android/databinding/tool/DataBinder.java13
-rw-r--r--compiler/src/main/java/android/databinding/tool/LayoutBinder.java3
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/BracketExpr.java10
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/ExprModel.java6
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java6
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/TwoWayListenerExpr.java5
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/ViewFieldExpr.java2
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/Callable.java7
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/InjectedClass.java6
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/InjectedField.java5
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/InjectedMethod.java5
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/ModelAnalyzer.java109
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/ModelClass.java17
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/ModelField.java8
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/ModelMethod.java10
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationAnalyzer.java5
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationField.java11
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationMethod.java11
-rw-r--r--compiler/src/main/java/android/databinding/tool/store/SetterStore.java14
-rw-r--r--compiler/src/main/java/android/databinding/tool/writer/ComponentWriter.java10
26 files changed, 285 insertions, 275 deletions
diff --git a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessBindable.java b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessBindable.java
index 4b96b3f0..8ae354ca 100644
--- a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessBindable.java
+++ b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessBindable.java
@@ -16,9 +16,10 @@
package android.databinding.annotationprocessor;
-import android.databinding.Bindable;
import android.databinding.tool.CompilerChef.BindableHolder;
import android.databinding.tool.DataBindingCompilerArgs;
+import android.databinding.tool.LibTypes;
+import android.databinding.tool.reflection.ModelAnalyzer;
import android.databinding.tool.util.GenerationalClassUtil;
import android.databinding.tool.util.L;
import android.databinding.tool.util.LoggedErrorException;
@@ -26,8 +27,6 @@ import android.databinding.tool.util.Preconditions;
import android.databinding.tool.writer.BRWriter;
import android.databinding.tool.writer.JavaFileWriter;
-import com.google.common.collect.Sets;
-
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
@@ -39,16 +38,10 @@ import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.util.Types;
-import java.io.File;
import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
import java.util.Set;
-import java.util.function.Consumer;
// binding app info and library info are necessary to trigger this.
public class ProcessBindable extends ProcessDataBinding.ProcessingStep implements BindableHolder {
@@ -62,11 +55,13 @@ public class ProcessBindable extends ProcessDataBinding.ProcessingStep implement
mProperties = new IntermediateV1(args.getModulePackage());
mergeLayoutVariables();
mLayoutVariables.clear();
+ LibTypes libTypes = ModelAnalyzer.getInstance().libTypes;
TypeElement observableType = processingEnv.getElementUtils().
- getTypeElement("android.databinding.Observable");
+ getTypeElement(libTypes.getObservable());
Types typeUtils = processingEnv.getTypeUtils();
+
for (Element element : AnnotationUtil
- .getElementsAnnotatedWith(roundEnv, Bindable.class)) {
+ .getElementsAnnotatedWith(roundEnv, libTypes.getBindableClass())) {
try {
Element enclosingElement = element.getEnclosingElement();
ElementKind kind = enclosingElement.getKind();
diff --git a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessDataBinding.java b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessDataBinding.java
index 8382d127..5912c5b7 100644
--- a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessDataBinding.java
+++ b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessDataBinding.java
@@ -43,6 +43,14 @@ import java.util.Set;
import java.util.stream.Collectors;
@SupportedAnnotationTypes({
+ "androidx.databinding.BindingAdapter",
+ "androidx.databinding.InverseBindingMethods",
+ "androidx.databinding.InverseBindingAdapter",
+ "androidx.databinding.InverseMethod",
+ "androidx.databinding.Untaggable",
+ "androidx.databinding.BindingMethods",
+ "androidx.databinding.BindingConversion",
+ "androidx.databinding.BindingBuildInfo",
"android.databinding.BindingAdapter",
"android.databinding.InverseBindingMethods",
"android.databinding.InverseBindingAdapter",
diff --git a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessMethodAdapters.java b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessMethodAdapters.java
index 4fcfca34..53a03be9 100644
--- a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessMethodAdapters.java
+++ b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessMethodAdapters.java
@@ -15,28 +15,21 @@
*/
package android.databinding.annotationprocessor;
-import android.databinding.BindingAdapter;
-import android.databinding.BindingConversion;
-import android.databinding.BindingMethod;
-import android.databinding.BindingMethods;
-import android.databinding.InverseBindingAdapter;
-import android.databinding.InverseBindingMethod;
-import android.databinding.InverseBindingMethods;
-import android.databinding.InverseMethod;
-import android.databinding.Untaggable;
+import android.databinding.tool.BindingAdapterCompat;
+import android.databinding.tool.BindingMethodsCompat;
import android.databinding.tool.DataBindingCompilerArgs;
+import android.databinding.tool.InverseBindingAdapterCompat;
+import android.databinding.tool.InverseBindingMethodsCompat;
+import android.databinding.tool.InverseMethodCompat;
+import android.databinding.tool.LibTypes;
+import android.databinding.tool.UntaggableCompat;
import android.databinding.tool.reflection.ModelAnalyzer;
-import android.databinding.tool.reflection.annotation.AnnotationTypeUtil;
import android.databinding.tool.store.SetterStore;
import android.databinding.tool.util.L;
import android.databinding.tool.util.LoggedErrorException;
import android.databinding.tool.util.Preconditions;
import android.databinding.tool.util.StringUtils;
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.List;
-
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
@@ -45,21 +38,22 @@ 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.MirroredTypeException;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.util.HashSet;
+import java.util.List;
public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
private final static String INVERSE_BINDING_EVENT_ATTR_SUFFIX = "AttrChanged";
- public ProcessMethodAdapters() {
- }
-
@Override
public boolean onHandleStep(RoundEnvironment roundEnv,
- ProcessingEnvironment processingEnvironment, DataBindingCompilerArgs args) {
+ ProcessingEnvironment processingEnvironment,
+ DataBindingCompilerArgs args) {
L.d("processing adapters");
final ModelAnalyzer modelAnalyzer = ModelAnalyzer.getInstance();
Preconditions.checkNotNull(modelAnalyzer, "Model analyzer should be"
@@ -89,25 +83,28 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
@Override
public void onProcessingOver(RoundEnvironment roundEnvironment,
- ProcessingEnvironment processingEnvironment, DataBindingCompilerArgs args) {
+ ProcessingEnvironment processingEnvironment,
+ DataBindingCompilerArgs args) {
}
private void addBindingAdapters(RoundEnvironment roundEnv, ProcessingEnvironment
processingEnv, SetterStore store) {
+ LibTypes libTypes = ModelAnalyzer.getInstance().libTypes;
+ Class<? extends Annotation> adapterAnnotation = libTypes.getBindingAdapterClass();
for (Element element : AnnotationUtil
- .getElementsAnnotatedWith(roundEnv, BindingAdapter.class)) {
+ .getElementsAnnotatedWith(roundEnv, adapterAnnotation)) {
try {
if (element.getKind() != ElementKind.METHOD ||
!element.getModifiers().contains(Modifier.PUBLIC)) {
L.e(element, "@BindingAdapter on invalid element: %s", element);
continue;
}
- BindingAdapter bindingAdapter = element.getAnnotation(BindingAdapter.class);
+ BindingAdapterCompat bindingAdapter = BindingAdapterCompat.create(element);
ExecutableElement executableElement = (ExecutableElement) element;
List<? extends VariableElement> parameters = executableElement.getParameters();
- if (bindingAdapter.value().length == 0) {
+ if (bindingAdapter.getAttributes().length == 0) {
L.e(element, "@BindingAdapter requires at least one attribute. %s",
element);
continue;
@@ -115,7 +112,7 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
final boolean takesComponent = takesComponent(executableElement, processingEnv);
final int startIndex = 1 + (takesComponent ? 1 : 0);
- final int numAttributes = bindingAdapter.value().length;
+ final int numAttributes = bindingAdapter.getAttributes().length;
final int numAdditionalArgs = parameters.size() - startIndex;
if (numAdditionalArgs == (2 * numAttributes)) {
// This BindingAdapter takes old and new values. Make sure they are properly ordered
@@ -126,9 +123,9 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
parameters.get(i + numAttributes).asType())) {
L.e(executableElement,
"BindingAdapter %s: old values should be followed " +
- "by new values. Parameter %d must be the same type as parameter "
- +
- "%d.", executableElement, i + 1, i + numAttributes + 1);
+ "by new values. Parameter %d must be the same type " +
+ "as parameter %d.",
+ executableElement, i + 1, i + numAttributes + 1);
hasParameterError = true;
break;
}
@@ -139,19 +136,19 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
} else if (numAdditionalArgs != numAttributes) {
L.e(element, "@BindingAdapter %s has %d attributes and %d value " +
"parameters. There should be %d or %d value parameters.",
- executableElement, numAttributes, numAdditionalArgs, numAttributes,
- numAttributes * 2);
+ executableElement, numAttributes, numAdditionalArgs,
+ numAttributes, numAttributes * 2);
continue;
}
- warnAttributeNamespaces(element, bindingAdapter.value());
+ warnAttributeNamespaces(element, bindingAdapter.getAttributes());
try {
if (numAttributes == 1) {
- final String attribute = bindingAdapter.value()[0];
+ final String attribute = bindingAdapter.getAttributes()[0];
store.addBindingAdapter(processingEnv, attribute, executableElement,
takesComponent);
} else {
- store.addBindingAdapter(processingEnv, bindingAdapter.value(),
- executableElement, takesComponent, bindingAdapter.requireAll());
+ store.addBindingAdapter(processingEnv, bindingAdapter.getAttributes(),
+ executableElement, takesComponent, bindingAdapter.getRequireAll());
}
} catch (IllegalArgumentException e) {
L.e(element, "@BindingAdapter for duplicate View and parameter type: %s",
@@ -164,10 +161,11 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
}
private static boolean takesComponent(ExecutableElement executableElement,
- ProcessingEnvironment processingEnvironment) {
+ ProcessingEnvironment processingEnvironment) {
List<? extends VariableElement> parameters = executableElement.getParameters();
Elements elementUtils = processingEnvironment.getElementUtils();
- TypeMirror viewElement = elementUtils.getTypeElement("android.view.View").asType();
+ TypeMirror viewElement = elementUtils
+ .getTypeElement("android.view.View").asType();
if (parameters.size() < 2) {
return false; // Validation will fail in the caller
}
@@ -177,12 +175,13 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
typeUtils.isAssignable(parameter1, viewElement)) {
return false; // first parameter is a View
}
+ ModelAnalyzer analyzer = ModelAnalyzer.getInstance();
if (parameters.size() < 3) {
TypeMirror viewStubProxy = elementUtils.
- getTypeElement("android.databinding.ViewStubProxy").asType();
+ getTypeElement(analyzer.libTypes.getViewStubProxy()).asType();
if (!typeUtils.isAssignable(parameter1, viewStubProxy)) {
- L.e(executableElement, "@BindingAdapter %s is applied to a method that has two " +
- "parameters, the first must be a View type", executableElement);
+ L.e(executableElement, "@BindingAdapter %s is applied to a method that has" +
+ " two parameters, the first must be a View type:", executableElement);
}
return false;
}
@@ -190,10 +189,10 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
if (typeUtils.isAssignable(parameter2, viewElement)) {
return true; // second parameter is a View
}
- L.e(executableElement, "@BindingAdapter %s is applied to a method that doesn't take a " +
- "View subclass as the first or second parameter. When a BindingAdapter uses a " +
- "DataBindingComponent, the component parameter is first and the View " +
- "parameter is second, otherwise the View parameter is first.",
+ L.e(executableElement, "@BindingAdapter %s is applied to a method that doesn't take " +
+ "a View subclass as the first or second parameter. When a BindingAdapter" +
+ " uses a DataBindingComponent, the component parameter is first and the " +
+ "View parameter is second, otherwise the View parameter is first.",
executableElement);
return false;
}
@@ -211,21 +210,19 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
}
private void addRenamed(RoundEnvironment roundEnv, SetterStore store) {
+ LibTypes libTypes = ModelAnalyzer.getInstance().libTypes;
+ Class<? extends Annotation> bindingMethodsClass = libTypes.getBindingMethodsClass();
for (Element element : AnnotationUtil
- .getElementsAnnotatedWith(roundEnv, BindingMethods.class)) {
- BindingMethods bindingMethods = element.getAnnotation(BindingMethods.class);
+ .getElementsAnnotatedWith(roundEnv, bindingMethodsClass)) {
+ BindingMethodsCompat bindingMethods = BindingMethodsCompat.create(element);
- for (BindingMethod bindingMethod : bindingMethods.value()) {
+ for (BindingMethodsCompat.BindingMethodCompat bindingMethod :
+ bindingMethods.getMethods()) {
try {
- final String attribute = bindingMethod.attribute();
- final String method = bindingMethod.method();
+ final String attribute = bindingMethod.getAttribute();
+ final String method = bindingMethod.getMethod();
warnAttributeNamespace(element, attribute);
- String type;
- try {
- type = bindingMethod.type().getCanonicalName();
- } catch (MirroredTypeException e) {
- type = AnnotationTypeUtil.getInstance().toJava(e.getTypeMirror());
- }
+ String type = bindingMethod.getType();
store.addRenamedMethod(attribute, type, method, (TypeElement) element);
} catch (LoggedErrorException e) {
// this will be logged later
@@ -235,14 +232,16 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
}
private void addConversions(RoundEnvironment roundEnv, SetterStore store) {
+ Class<? extends Annotation> bindingConversionClass = ModelAnalyzer.getInstance()
+ .libTypes.getBindingConversionClass();
for (Element element : AnnotationUtil
- .getElementsAnnotatedWith(roundEnv, BindingConversion.class)) {
+ .getElementsAnnotatedWith(roundEnv, bindingConversionClass)) {
try {
if (element.getKind() != ElementKind.METHOD ||
!element.getModifiers().contains(Modifier.STATIC) ||
!element.getModifiers().contains(Modifier.PUBLIC)) {
- L.e(element, "@BindingConversion is only allowed on public static methods %s",
- element);
+ L.e(element, "@BindingConversion is only allowed on public static " +
+ "methods %s", element);
continue;
}
@@ -264,12 +263,16 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
}
private void addInverseAdapters(RoundEnvironment roundEnv,
- ProcessingEnvironment processingEnv, SetterStore store) {
+ ProcessingEnvironment processingEnv, SetterStore store) {
+ LibTypes libTypes = ModelAnalyzer.getInstance().libTypes;
+ Class<? extends Annotation> inverseBindingAdapterClass =
+ libTypes.getInverseBindingAdapterClass();
for (Element element : AnnotationUtil
- .getElementsAnnotatedWith(roundEnv, InverseBindingAdapter.class)) {
+ .getElementsAnnotatedWith(roundEnv, inverseBindingAdapterClass)) {
try {
if (!element.getModifiers().contains(Modifier.PUBLIC)) {
- L.e(element, "@InverseBindingAdapter must be associated with a public method");
+ L.e(element,
+ "@InverseBindingAdapter must be associated with a public method");
continue;
}
ExecutableElement executableElement = (ExecutableElement) element;
@@ -277,19 +280,19 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
L.e(element, "@InverseBindingAdapter must have a non-void return type");
continue;
}
- final InverseBindingAdapter inverseBindingAdapter =
- executableElement.getAnnotation(InverseBindingAdapter.class);
- final String attribute = inverseBindingAdapter.attribute();
+ final InverseBindingAdapterCompat inverseBindingAdapter =
+ InverseBindingAdapterCompat.create(executableElement);
+ final String attribute = inverseBindingAdapter.getAttribute();
warnAttributeNamespace(element, attribute);
- final String event = inverseBindingAdapter.event().isEmpty()
- ? inverseBindingAdapter.attribute() + INVERSE_BINDING_EVENT_ATTR_SUFFIX
- : inverseBindingAdapter.event();
+ final String event = inverseBindingAdapter.getEvent().isEmpty()
+ ? inverseBindingAdapter.getAttribute() + INVERSE_BINDING_EVENT_ATTR_SUFFIX
+ : inverseBindingAdapter.getEvent();
warnAttributeNamespace(element, event);
final boolean takesComponent = takesComponent(executableElement, processingEnv);
final int expectedArgs = takesComponent ? 2 : 1;
final int numParameters = executableElement.getParameters().size();
if (numParameters != expectedArgs) {
- L.e(element,"@InverseBindingAdapter %s takes %s parameters, but %s "
+ L.e(element, "@InverseBindingAdapter %s takes %s parameters, but %s "
+ "parameters were expected", element, numParameters, expectedArgs);
continue;
}
@@ -298,7 +301,7 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
takesComponent);
} catch (IllegalArgumentException e) {
L.e(element, "@InverseBindingAdapter for duplicate View and parameter "
- + "type: %s", element);
+ + "type: %s", element);
}
} catch (LoggedErrorException e) {
// This will be logged later
@@ -307,26 +310,25 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
}
private void addInverseBindingMethods(RoundEnvironment roundEnv, SetterStore store) {
+ LibTypes libTypes = ModelAnalyzer.getInstance().libTypes;
+ Class<? extends Annotation> inverseBindingMethodsClass = libTypes
+ .getInverseBindingMethodsClass();
for (Element element : AnnotationUtil
- .getElementsAnnotatedWith(roundEnv, InverseBindingMethods.class)) {
- InverseBindingMethods bindingMethods =
- element.getAnnotation(InverseBindingMethods.class);
+ .getElementsAnnotatedWith(roundEnv, inverseBindingMethodsClass)) {
+ InverseBindingMethodsCompat bindingMethods =
+ InverseBindingMethodsCompat.create(element);
- for (InverseBindingMethod bindingMethod : bindingMethods.value()) {
+ for (InverseBindingMethodsCompat.InverseBindingMethodCompat bindingMethod :
+ bindingMethods.getMethods()) {
try {
- final String attribute = bindingMethod.attribute();
- final String method = bindingMethod.method();
- final String event = bindingMethod.event().isEmpty()
- ? bindingMethod.attribute() + INVERSE_BINDING_EVENT_ATTR_SUFFIX
- : bindingMethod.event();
+ final String attribute = bindingMethod.getAttribute();
+ final String method = bindingMethod.getMethod();
+ final String event = bindingMethod.getEvent().isEmpty()
+ ? bindingMethod.getAttribute() + INVERSE_BINDING_EVENT_ATTR_SUFFIX
+ : bindingMethod.getEvent();
warnAttributeNamespace(element, attribute);
warnAttributeNamespace(element, event);
- String type;
- try {
- type = bindingMethod.type().getCanonicalName();
- } catch (MirroredTypeException e) {
- type = AnnotationTypeUtil.getInstance().toJava(e.getTypeMirror());
- }
+ String type = bindingMethod.getType();
store.addInverseBindingMethod(attribute, event, type, method,
(TypeElement) element);
} catch (LoggedErrorException e) {
@@ -337,9 +339,11 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
}
private void addInverseMethods(RoundEnvironment roundEnv, ProcessingEnvironment processingEnv,
- SetterStore store) {
+ SetterStore store) {
+ LibTypes libTypes = ModelAnalyzer.getInstance().libTypes;
+ Class<? extends Annotation> inverseMethodClass = libTypes.getInverseMethodClass();
for (Element element : AnnotationUtil
- .getElementsAnnotatedWith(roundEnv, InverseMethod.class)) {
+ .getElementsAnnotatedWith(roundEnv, inverseMethodClass)) {
try {
if (!element.getModifiers().contains(Modifier.PUBLIC)) {
L.e(element, "@InverseMethods must be associated with a public method");
@@ -350,12 +354,12 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
L.e(element, "@InverseMethods must have a non-void return type");
continue;
}
- final InverseMethod inverseMethod =
- executableElement.getAnnotation(InverseMethod.class);
- final String target = inverseMethod.value();
+ final InverseMethodCompat inverseMethod =
+ InverseMethodCompat.create(executableElement);
+ final String target = inverseMethod.getValue();
if (!StringUtils.isNotBlank(target)) {
- L.e(element, "@InverseMethod must supply a value containing the name of the " +
- "method to call when going from View value to bound value");
+ L.e(element, "@InverseMethod must supply a value containing the name of " +
+ "the method to call when going from View value to bound value");
continue;
}
if (executableElement.getParameters().isEmpty()) {
@@ -364,7 +368,7 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
}
try {
ExecutableElement inverse = findInverseOf(processingEnv, executableElement,
- inverseMethod.value());
+ inverseMethod.getValue());
store.addInverseMethod(processingEnv, executableElement, inverse);
} catch (IllegalArgumentException e) {
L.e(element, "%s", e.getMessage());
@@ -376,7 +380,7 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
}
private ExecutableElement findInverseOf(ProcessingEnvironment env, ExecutableElement method,
- String name) throws IllegalArgumentException {
+ String name) throws IllegalArgumentException {
TypeElement enclosingType = (TypeElement) method.getEnclosingElement();
List<? extends VariableElement> params = method.getParameters();
Types typeUtil = env.getTypeUtils();
@@ -449,11 +453,13 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
}
private void addUntaggable(RoundEnvironment roundEnv, SetterStore store) {
+ LibTypes libTypes = ModelAnalyzer.getInstance().libTypes;
+ Class<? extends Annotation> untaggableClass = libTypes.getUntaggableClass();
for (Element element : AnnotationUtil.
- getElementsAnnotatedWith(roundEnv, Untaggable.class)) {
+ getElementsAnnotatedWith(roundEnv, untaggableClass)) {
try {
- Untaggable untaggable = element.getAnnotation(Untaggable.class);
- store.addUntaggableTypes(untaggable.value(), (TypeElement) element);
+ UntaggableCompat untaggable = UntaggableCompat.create(element);
+ store.addUntaggableTypes(untaggable.getValue(), (TypeElement) element);
} catch (LoggedErrorException e) {
// This will be logged later
}
@@ -461,24 +467,24 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
}
private void clearIncrementalClasses(RoundEnvironment roundEnv, SetterStore store) {
- HashSet<String> classes = new HashSet<String>();
-
+ HashSet<String> classes = new HashSet<>();
+ LibTypes libTypes = ModelAnalyzer.getInstance().libTypes;
for (Element element : AnnotationUtil
- .getElementsAnnotatedWith(roundEnv, BindingAdapter.class)) {
+ .getElementsAnnotatedWith(roundEnv, libTypes.getBindingAdapterClass())) {
TypeElement containingClass = (TypeElement) element.getEnclosingElement();
classes.add(containingClass.getQualifiedName().toString());
}
for (Element element : AnnotationUtil
- .getElementsAnnotatedWith(roundEnv, BindingMethods.class)) {
+ .getElementsAnnotatedWith(roundEnv, libTypes.getBindingMethodsClass())) {
classes.add(((TypeElement) element).getQualifiedName().toString());
}
for (Element element : AnnotationUtil
- .getElementsAnnotatedWith(roundEnv, BindingConversion.class)) {
+ .getElementsAnnotatedWith(roundEnv, libTypes.getBindingConversionClass())) {
classes.add(((TypeElement) element.getEnclosingElement()).getQualifiedName().
toString());
}
for (Element element : AnnotationUtil.
- getElementsAnnotatedWith(roundEnv, Untaggable.class)) {
+ getElementsAnnotatedWith(roundEnv, libTypes.getUntaggableClass())) {
classes.add(((TypeElement) element).getQualifiedName().toString());
}
store.clear(classes);
diff --git a/compiler/src/main/java/android/databinding/tool/Binding.java b/compiler/src/main/java/android/databinding/tool/Binding.java
index fe222fdb..19884201 100644
--- a/compiler/src/main/java/android/databinding/tool/Binding.java
+++ b/compiler/src/main/java/android/databinding/tool/Binding.java
@@ -126,8 +126,7 @@ public class Binding implements LocationScopeProvider {
mExpr = mExpr.unwrapObservableField();
if (isListenerAttribute(mName)) {
ModelAnalyzer modelAnalyzer = ModelAnalyzer.getInstance();
- ModelClass viewStubProxy = modelAnalyzer.
- findClass("android.databinding.ViewStubProxy", null);
+ ModelClass viewStubProxy = modelAnalyzer.getViewStubProxyType();
mSetterCall = SetterStore.get().getSetterCall(mName,
viewStubProxy, mExpr.getResolvedType(), mExpr.getModel().getImports());
} else if (isViewStubAttribute(mName)) {
@@ -167,8 +166,7 @@ public class Binding implements LocationScopeProvider {
SetterStore setterStore = SetterStore.get();
if (viewType != null && viewType.extendsViewStub()) {
if (isListenerAttribute(name)) {
- ModelClass viewStubProxy = modelAnalyzer.
- findClass("android.databinding.ViewStubProxy", null);
+ ModelClass viewStubProxy = modelAnalyzer.getViewStubProxyType();
setterCall = SetterStore.get().getSetterCall(name,
viewStubProxy, objectParameter, model.getImports());
} else if (isViewStubAttribute(name)) {
diff --git a/compiler/src/main/java/android/databinding/tool/CompilerChef.java b/compiler/src/main/java/android/databinding/tool/CompilerChef.java
index 45638966..13728dae 100644
--- a/compiler/src/main/java/android/databinding/tool/CompilerChef.java
+++ b/compiler/src/main/java/android/databinding/tool/CompilerChef.java
@@ -17,26 +17,21 @@ import android.databinding.tool.processing.Scope;
import android.databinding.tool.processing.ScopedException;
import android.databinding.tool.reflection.InjectedClass;
import android.databinding.tool.reflection.ModelAnalyzer;
-import android.databinding.tool.store.GenClassInfoLog;
-import android.databinding.tool.store.ResourceBundle;
-import android.databinding.tool.util.L;
-import android.databinding.tool.writer.BRWriter;
-import android.databinding.tool.reflection.ModelClass;
import android.databinding.tool.store.FeatureInfoList;
import android.databinding.tool.store.GenClassInfoLog;
import android.databinding.tool.store.ResourceBundle;
import android.databinding.tool.util.L;
-import android.databinding.tool.util.Preconditions;
import android.databinding.tool.writer.BindingMapperWriter;
import android.databinding.tool.writer.BindingMapperWriterV2;
import android.databinding.tool.writer.JavaFileWriter;
import android.databinding.tool.writer.MergedBindingMapperWriter;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
-
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.TypeSpec;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.TypeElement;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
@@ -45,12 +40,8 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.function.Predicate;
import java.util.stream.Collectors;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.TypeElement;
-
/**
* Chef class for compiler.
*
@@ -118,7 +109,8 @@ public class CompilerChef {
public void ensureDataBinder() {
if (mDataBinder == null) {
- mDataBinder = new DataBinder(mResourceBundle, mEnableV2);
+ LibTypes libTypes = ModelAnalyzer.getInstance().libTypes;
+ mDataBinder = new DataBinder(mResourceBundle, mEnableV2, libTypes);
mDataBinder.setFileWriter(mFileWriter);
}
}
@@ -146,7 +138,7 @@ public class CompilerChef {
+ bundles.get(0).getBindingClassName();
// inject base class
InjectedClass bindingClass =
- new InjectedClass(className, ModelAnalyzer.VIEW_DATA_BINDING);
+ new InjectedClass(className, analyzer.libTypes.getViewDataBinding());
analyzer.injectClass(bindingClass);
for (ResourceBundle.LayoutFileBundle layoutFileBundle : bundles) {
@@ -223,8 +215,9 @@ public class CompilerChef {
final String mapperName = "DataBinderMapperImpl";
ensureDataBinder();
+ LibTypes libTypes = ModelAnalyzer.getInstance().libTypes;
BindingMapperWriter dbr = new BindingMapperWriter(pkg, mapperName,
- mDataBinder.getLayoutBinders(), compilerArgs);
+ mDataBinder.getLayoutBinders(), compilerArgs, libTypes);
mFileWriter.writeToFile(
pkg + "." + dbr.getClassName(),
dbr.write(brValueLookup));
@@ -234,11 +227,13 @@ public class CompilerChef {
private void writeMapperForV1Compat(
DataBindingCompilerArgs compilerArgs,
Map<String, Integer> brValueLookup) {
+ LibTypes libTypes = ModelAnalyzer.getInstance().libTypes;
BindingMapperWriter dbr = new BindingMapperWriter(
BindingMapperWriter.V1_COMPAT_MAPPER_PKG,
BindingMapperWriter.V1_COMPAT_MAPPER_NAME,
mV1CompatChef.getLayoutBinders(),
- compilerArgs);
+ compilerArgs,
+ libTypes);
mFileWriter.writeToFile(
BindingMapperWriter.V1_COMPAT_MAPPER_PKG + "." + dbr.getClassName(),
dbr.write(brValueLookup));
@@ -271,12 +266,14 @@ public class CompilerChef {
}).collect(Collectors.toList());
Set<String> featurePackageIds = loadFeaturePackageIds(compilerArgs);
StringBuilder sb = new StringBuilder();
+ LibTypes libTypes = ModelAnalyzer.getInstance().libTypes;
MergedBindingMapperWriter mergedBindingMapperWriter =
new MergedBindingMapperWriter(
availableDependencyModules,
compilerArgs,
featurePackageIds,
- mV1CompatChef != null);
+ mV1CompatChef != null,
+ libTypes);
TypeSpec mergedMapperSpec = mergedBindingMapperWriter.write();
try {
JavaFile.builder(mergedBindingMapperWriter.getPkg(), mergedMapperSpec)
@@ -317,9 +314,11 @@ public class CompilerChef {
}
GenClassInfoLog infoLogInThisModule = infoLog
.createPackageInfoLog(compilerArgs.getModulePackage());
+ LibTypes libTypes = ModelAnalyzer.getInstance().libTypes;
BindingMapperWriterV2 v2 = new BindingMapperWriterV2(
infoLogInThisModule,
- compilerArgs);
+ compilerArgs,
+ libTypes);
TypeSpec spec = v2.write(brValueLookup);
StringBuilder sb = new StringBuilder();
try {
diff --git a/compiler/src/main/java/android/databinding/tool/Context.kt b/compiler/src/main/java/android/databinding/tool/Context.kt
index 8691a880..07019c07 100644
--- a/compiler/src/main/java/android/databinding/tool/Context.kt
+++ b/compiler/src/main/java/android/databinding/tool/Context.kt
@@ -40,12 +40,30 @@ object Context {
@JvmStatic
fun init(processingEnvironment: ProcessingEnvironment,
args : DataBindingCompilerArgs) {
+ L.setClient(logger)
+ val hasAndroidXBinding = discoverAndroidX(processingEnvironment)
+ libTypes = LibTypes(hasAndroidXBinding)
generationalClassUtil = GenerationalClassUtil.create(args)
- modelAnalyzer = AnnotationAnalyzer(processingEnvironment)
+ modelAnalyzer = AnnotationAnalyzer(processingEnvironment, libTypes)
typeUtil = modelAnalyzer!!.createTypeUtil()
setterStore = SetterStore.create(modelAnalyzer, generationalClassUtil)
sdkUtil = SdkUtil.create(File(args.sdkDir), args.minApi)
- L.setClient(logger)
+
+ }
+
+ private fun discoverAndroidX(processingEnvironment: ProcessingEnvironment): Boolean {
+ val hasSupportBinding = processingEnvironment
+ .elementUtils
+ .getTypeElement("android.databinding.Observable") != null
+ val hasAndroidXBinding = processingEnvironment
+ .elementUtils
+ .getTypeElement("androidx.databinding.Observable") != null
+ if (hasAndroidXBinding && hasSupportBinding) {
+ L.e("AndroidX Error: Both old and new data binding packages are available in dependencies. Make sure" +
+ " you've setup jettifier for any data binding dependencies and also set android.useAndroidx in" +
+ " your gradle.properties file.")
+ }
+ return hasAndroidXBinding
}
@JvmStatic
@@ -76,6 +94,10 @@ object Context {
private set
@JvmStatic
+ var libTypes : LibTypes? = null
+ private set
+
+ @JvmStatic
fun fullClear(processingEnvironment: ProcessingEnvironment) {
logger.flushMessages(processingEnvironment)
modelAnalyzer = null
@@ -83,6 +105,7 @@ object Context {
generationalClassUtil = null
typeUtil = null
sdkUtil = null
+ libTypes = null
L.setClient(null)
cleanLazyProps()
}
diff --git a/compiler/src/main/java/android/databinding/tool/DataBinder.java b/compiler/src/main/java/android/databinding/tool/DataBinder.java
index fa2f256c..f9f7567b 100644
--- a/compiler/src/main/java/android/databinding/tool/DataBinder.java
+++ b/compiler/src/main/java/android/databinding/tool/DataBinder.java
@@ -38,16 +38,19 @@ import java.util.Set;
*/
public class DataBinder {
List<LayoutBinder> mLayoutBinders = new ArrayList<LayoutBinder>();
- private static final String COMPONENT_CLASS = "android.databinding.DataBindingComponent";
+ private final String mComponentClass;
private JavaFileWriter mFileWriter;
Set<String> mClassesToBeStripped = new HashSet<String>();
private final boolean mEnableV2;
+ private final LibTypes mLibTypes;
- public DataBinder(ResourceBundle resourceBundle, boolean enableV2) {
+ public DataBinder(ResourceBundle resourceBundle, boolean enableV2, LibTypes libTypes) {
L.d("reading resource bundle into data binder");
+ mLibTypes = libTypes;
mEnableV2 = enableV2;
+ mComponentClass = mLibTypes.getBindingPackage() + ".DataBindingComponent";
if (mEnableV2) {
for(ResourceBundle.LayoutFileBundle bundle :
resourceBundle.getLayoutFileBundlesInSource()) {
@@ -190,10 +193,10 @@ public class DataBinder {
}
public void writeComponent() {
- ComponentWriter componentWriter = new ComponentWriter();
+ ComponentWriter componentWriter = new ComponentWriter(mLibTypes);
- mClassesToBeStripped.add(COMPONENT_CLASS);
- mFileWriter.writeToFile(COMPONENT_CLASS, componentWriter.createComponent());
+ mClassesToBeStripped.add(mComponentClass);
+ mFileWriter.writeToFile(mComponentClass, componentWriter.createComponent());
}
public Set<String> getClassesToBeStripped() {
diff --git a/compiler/src/main/java/android/databinding/tool/LayoutBinder.java b/compiler/src/main/java/android/databinding/tool/LayoutBinder.java
index 98d9f918..b8024c3b 100644
--- a/compiler/src/main/java/android/databinding/tool/LayoutBinder.java
+++ b/compiler/src/main/java/android/databinding/tool/LayoutBinder.java
@@ -22,6 +22,7 @@ import android.databinding.tool.expr.ExprModel;
import android.databinding.tool.expr.IdentifierExpr;
import android.databinding.tool.processing.Scope;
import android.databinding.tool.processing.scopes.FileScopeProvider;
+import android.databinding.tool.reflection.ModelAnalyzer;
import android.databinding.tool.store.Location;
import android.databinding.tool.store.ResourceBundle;
import android.databinding.tool.store.ResourceBundle.BindingTargetBundle;
@@ -339,7 +340,7 @@ public class LayoutBinder implements FileScopeProvider {
private void ensureWriter() {
if (mWriter == null) {
- mWriter = new LayoutBinderWriter(this);
+ mWriter = new LayoutBinderWriter(this, ModelAnalyzer.getInstance().libTypes);
}
}
diff --git a/compiler/src/main/java/android/databinding/tool/expr/BracketExpr.java b/compiler/src/main/java/android/databinding/tool/expr/BracketExpr.java
index 63543614..1016093a 100644
--- a/compiler/src/main/java/android/databinding/tool/expr/BracketExpr.java
+++ b/compiler/src/main/java/android/databinding/tool/expr/BracketExpr.java
@@ -19,6 +19,7 @@ package android.databinding.tool.expr;
import android.databinding.tool.reflection.ModelAnalyzer;
import android.databinding.tool.reflection.ModelClass;
import android.databinding.tool.solver.ExecutionPath;
+import android.databinding.tool.util.L;
import android.databinding.tool.writer.KCode;
import com.google.common.collect.Lists;
@@ -50,9 +51,11 @@ public class BracketExpr extends Expr {
} else if (targetType.isMap()) {
mAccessor = BracketAccessor.MAP;
} else {
- throw new IllegalArgumentException("Cannot determine variable type used in [] " +
+ IllegalArgumentException exception = new IllegalArgumentException(
+ "Cannot determine variable type used in [] " +
"expression. Cast the value to List, Map, " +
"or array. Type detected: " + targetType.toJavaCode());
+ L.e(exception, "Failed to resolve Bracked Expr %s, target: %s", this, targetType);
}
return targetType.getComponentType();
}
@@ -169,9 +172,6 @@ public class BracketExpr extends Expr {
arg = argCastsInteger()
? model.castExpr("int", model.castExpr("Integer", arg))
: arg;
- StaticIdentifierExpr viewDataBinding =
- model.staticIdentifier(ModelAnalyzer.VIEW_DATA_BINDING);
- viewDataBinding.setUserDefinedType(ModelAnalyzer.VIEW_DATA_BINDING);
ModelClass targetType = getTarget().getResolvedType();
if ((targetType.isList() || targetType.isMap()) &&
value.getResolvedType().isPrimitive()) {
@@ -179,7 +179,7 @@ public class BracketExpr extends Expr {
value = model.castExpr(boxed.toJavaCode(), value);
}
List<Expr> args = Lists.newArrayList(getTarget().cloneToModel(model), arg, value);
- MethodCallExpr setter = model.methodCall(viewDataBinding, "setTo", args);
+ MethodCallExpr setter = model.methodCall(model.viewDataBinding(), "setTo", args);
setter.setAllowProtected();
return setter;
}
diff --git a/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java b/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java
index 53ed1e7d..1aa57b08 100644
--- a/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java
+++ b/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java
@@ -210,8 +210,10 @@ public class ExprModel {
}
public IdentifierExpr viewDataBinding() {
- IdentifierExpr viewDataBinding = staticIdentifier(ModelAnalyzer.VIEW_DATA_BINDING);
- viewDataBinding.setUserDefinedType(ModelAnalyzer.VIEW_DATA_BINDING);
+ ModelAnalyzer analyzer = ModelAnalyzer.getInstance();
+ String qualifiedName = analyzer.libTypes.getViewDataBinding();
+ IdentifierExpr viewDataBinding = staticIdentifier(qualifiedName);
+ viewDataBinding.setUserDefinedType(qualifiedName);
return viewDataBinding;
}
diff --git a/compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java b/compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java
index 7a41d30f..88017f5b 100644
--- a/compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java
+++ b/compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java
@@ -189,17 +189,17 @@ public class FieldAccessExpr extends MethodBaseExpr {
if (mGetter != null && mGetter.canBeInvalidated()) {
if (mGetter.type == Type.FIELD) {
if (mGetter.bindableAnnotation != null &&
- mGetter.bindableAnnotation.value().length != 0) {
+ mGetter.bindableAnnotation.getDependencies().length != 0) {
L.e("Bindable annotation with property names is only supported on methods. " +
"Field '%s.%s' has @Bindable(\"%s\")",
getTarget().getResolvedType().toJavaCode(), mGetter.name,
- StringUtils.join(mGetter.bindableAnnotation.value(), "\", \""));
+ StringUtils.join(mGetter.bindableAnnotation.getDependencies(), "\", \""));
}
} else if (mGetter.method != null && mGetter.canBeInvalidated() &&
mGetter.bindableAnnotation != null) {
try {
Scope.enter(this);
- String[] dependencyArray = mGetter.bindableAnnotation.value();
+ String[] dependencyArray = mGetter.bindableAnnotation.getDependencies();
Expr target = getTarget();
ModelClass resolvedType = target.getResolvedType();
diff --git a/compiler/src/main/java/android/databinding/tool/expr/TwoWayListenerExpr.java b/compiler/src/main/java/android/databinding/tool/expr/TwoWayListenerExpr.java
index c2f91b3b..9444c3cc 100644
--- a/compiler/src/main/java/android/databinding/tool/expr/TwoWayListenerExpr.java
+++ b/compiler/src/main/java/android/databinding/tool/expr/TwoWayListenerExpr.java
@@ -15,13 +15,13 @@
*/
package android.databinding.tool.expr;
-import android.databinding.InverseBindingListener;
import android.databinding.tool.InverseBinding;
import android.databinding.tool.reflection.ModelAnalyzer;
import android.databinding.tool.reflection.ModelClass;
import android.databinding.tool.writer.KCode;
import android.databinding.tool.writer.LayoutBinderWriterKt;
+import java.util.Collections;
import java.util.List;
/**
@@ -36,7 +36,8 @@ public class TwoWayListenerExpr extends Expr {
@Override
protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) {
- return modelAnalyzer.findClass(InverseBindingListener.class);
+ return modelAnalyzer.findClass(modelAnalyzer.libTypes.getInverseBindingListener(),
+ Collections.emptyMap());
}
@Override
diff --git a/compiler/src/main/java/android/databinding/tool/expr/ViewFieldExpr.java b/compiler/src/main/java/android/databinding/tool/expr/ViewFieldExpr.java
index 59c0dbeb..0c723fa6 100644
--- a/compiler/src/main/java/android/databinding/tool/expr/ViewFieldExpr.java
+++ b/compiler/src/main/java/android/databinding/tool/expr/ViewFieldExpr.java
@@ -43,7 +43,7 @@ public class ViewFieldExpr extends BuiltInVariableExpr {
protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) {
final ModelClass type = modelAnalyzer.findClass(mBindingTarget.getInterfaceType(), null);
if (type == null) {
- return modelAnalyzer.findClass(ModelAnalyzer.VIEW_DATA_BINDING, null);
+ return modelAnalyzer.findClass(modelAnalyzer.libTypes.getViewDataBinding(), null);
}
return type;
}
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/Callable.java b/compiler/src/main/java/android/databinding/tool/reflection/Callable.java
index 54db94e3..910990b4 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/Callable.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/Callable.java
@@ -15,7 +15,7 @@
*/
package android.databinding.tool.reflection;
-import android.databinding.Bindable;
+import android.databinding.tool.BindableCompat;
import org.jetbrains.annotations.Nullable;
@@ -44,10 +44,11 @@ public class Callable {
private final int mParameterCount;
- public final Bindable bindableAnnotation;
+ @Nullable
+ public final BindableCompat bindableAnnotation;
public Callable(Type type, String name, String setterName, ModelClass resolvedType,
- int parameterCount, int flags, ModelMethod method, Bindable bindable) {
+ int parameterCount, int flags, ModelMethod method, @Nullable BindableCompat bindable) {
this.type = type;
this.name = name;
this.resolvedType = resolvedType;
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/InjectedClass.java b/compiler/src/main/java/android/databinding/tool/reflection/InjectedClass.java
index ca7f3e5a..45bedcb0 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/InjectedClass.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/InjectedClass.java
@@ -231,7 +231,11 @@ public class InjectedClass extends ModelClass {
@Override
public TypeName getTypeName() {
- return ExtKt.toTypeName(mClassName);
+ ModelAnalyzer instance = ModelAnalyzer.getInstance();
+ if (instance == null) {
+ return ExtKt.toTypeName(mClassName, false);
+ }
+ return ExtKt.toTypeName(mClassName, instance.libTypes);
}
@Override
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/InjectedField.java b/compiler/src/main/java/android/databinding/tool/reflection/InjectedField.java
index 7d975ce0..956247e6 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/InjectedField.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/InjectedField.java
@@ -34,11 +34,6 @@ public class InjectedField extends ModelField {
}
@Override
- public boolean isBindable() {
- return false;
- }
-
- @Override
public String getName() {
return mName;
}
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/InjectedMethod.java b/compiler/src/main/java/android/databinding/tool/reflection/InjectedMethod.java
index a6616518..be1f8d79 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/InjectedMethod.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/InjectedMethod.java
@@ -106,11 +106,6 @@ public class InjectedMethod extends ModelMethod {
}
@Override
- public boolean isBindable() {
- return false;
- }
-
- @Override
public int getMinApi() {
return 0;
}
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/ModelAnalyzer.java b/compiler/src/main/java/android/databinding/tool/reflection/ModelAnalyzer.java
index e8be90db..5b48b79f 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/ModelAnalyzer.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/ModelAnalyzer.java
@@ -16,14 +16,16 @@
package android.databinding.tool.reflection;
import android.databinding.tool.Context;
-import android.databinding.tool.reflection.annotation.AnnotationAnalyzer;
+import android.databinding.tool.LibTypes;
import android.databinding.tool.util.L;
import android.databinding.tool.util.Preconditions;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
-
-import javax.annotation.processing.ProcessingEnvironment;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.stream.Collectors;
/**
* This is the base class for several implementations of something that
@@ -32,52 +34,16 @@ import javax.annotation.processing.ProcessingEnvironment;
*/
public abstract class ModelAnalyzer {
public static final String GENERATED_ANNOTATION = "javax.annotation.Generated";
- public static final String[] LIST_CLASS_NAMES = {
- "java.util.List",
- "android.util.SparseArray",
- "android.util.SparseBooleanArray",
- "android.util.SparseIntArray",
- "android.util.SparseLongArray",
- "android.util.LongSparseArray",
- "android.support.v4.util.LongSparseArray",
- };
-
- public static final String MAP_CLASS_NAME = "java.util.Map";
-
- public static final String STRING_CLASS_NAME = "java.lang.String";
-
- public static final String OBJECT_CLASS_NAME = "java.lang.Object";
-
- public static final String OBSERVABLE_CLASS_NAME = "android.databinding.Observable";
-
- public static final String OBSERVABLE_LIST_CLASS_NAME = "android.databinding.ObservableList";
-
- public static final String OBSERVABLE_MAP_CLASS_NAME = "android.databinding.ObservableMap";
-
- public static final String LIVE_DATA_CLASS_NAME = "android.arch.lifecycle.LiveData";
- public static final String MUTABLE_LIVE_DATA_CLASS_NAME =
- "android.arch.lifecycle.MutableLiveData";
+ private static final String MAP_CLASS_NAME = "java.util.Map";
- public static final String[] OBSERVABLE_FIELDS = {
- "android.databinding.ObservableBoolean",
- "android.databinding.ObservableByte",
- "android.databinding.ObservableChar",
- "android.databinding.ObservableShort",
- "android.databinding.ObservableInt",
- "android.databinding.ObservableLong",
- "android.databinding.ObservableFloat",
- "android.databinding.ObservableDouble",
- "android.databinding.ObservableField",
- "android.databinding.ObservableParcelable",
- };
+ private static final String STRING_CLASS_NAME = "java.lang.String";
- public static final String VIEW_DATA_BINDING =
- "android.databinding.ViewDataBinding";
+ private static final String OBJECT_CLASS_NAME = "java.lang.Object";
- public static final String VIEW_STUB_CLASS_NAME = "android.view.ViewStub";
+ private static final String VIEW_STUB_CLASS_NAME = "android.view.ViewStub";
- private ModelClass[] mListTypes;
+ private List<ModelClass> mListTypes;
private ModelClass mMapType;
private ModelClass mStringType;
private ModelClass mObjectType;
@@ -86,9 +52,12 @@ public abstract class ModelAnalyzer {
private ModelClass mObservableMapType;
private ModelClass mLiveDataType;
private ModelClass mMutableLiveDataType;
- private ModelClass[] mObservableFieldTypes;
+ private List<ModelClass> mObservableFieldTypes;
private ModelClass mViewBindingType;
private ModelClass mViewStubType;
+ private ModelClass mViewStubProxyType;
+
+ public final LibTypes libTypes;
/**
* If it is present, we annotate generated classes with @Generated.
@@ -98,6 +67,10 @@ public abstract class ModelAnalyzer {
private final Map<String, InjectedClass> mInjectedClasses =
new HashMap<String, InjectedClass>();
+ protected ModelAnalyzer(LibTypes libTypes) {
+ this.libTypes = libTypes;
+ }
+
public ModelClass findCommonParentOf(ModelClass modelClass1, ModelClass modelClass2) {
return findCommonParentOf(modelClass1, modelClass2, true);
}
@@ -238,15 +211,13 @@ public abstract class ModelAnalyzer {
return injectedClass;
}
- ModelClass[] getListTypes() {
+ List<ModelClass> getListTypes() {
if (mListTypes == null) {
- mListTypes = new ModelClass[LIST_CLASS_NAMES.length];
- for (int i = 0; i < mListTypes.length; i++) {
- final ModelClass modelClass = findClass(LIST_CLASS_NAMES[i], null);
- if (modelClass != null) {
- mListTypes[i] = modelClass.erasure();
- }
- }
+ mListTypes = libTypes.getListClassNames()
+ .stream()
+ .map(this::loadClassErasure)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
}
return mListTypes;
}
@@ -274,54 +245,62 @@ public abstract class ModelAnalyzer {
ModelClass getObservableType() {
if (mObservableType == null) {
- mObservableType = findClass(OBSERVABLE_CLASS_NAME, null);
+ mObservableType = findClass(libTypes.getObservable(), null);
}
return mObservableType;
}
ModelClass getObservableListType() {
if (mObservableListType == null) {
- mObservableListType = loadClassErasure(OBSERVABLE_LIST_CLASS_NAME);
+ mObservableListType = loadClassErasure(libTypes.getObservableList());
}
return mObservableListType;
}
ModelClass getObservableMapType() {
if (mObservableMapType == null) {
- mObservableMapType = loadClassErasure(OBSERVABLE_MAP_CLASS_NAME);
+ mObservableMapType = loadClassErasure(libTypes.getObservableMap());
}
return mObservableMapType;
}
ModelClass getLiveDataType() {
if (mLiveDataType == null) {
- mLiveDataType = loadClassErasure(LIVE_DATA_CLASS_NAME);
+ mLiveDataType = loadClassErasure(libTypes.getLiveData());
}
return mLiveDataType;
}
ModelClass getMutableLiveDataType() {
if (mMutableLiveDataType == null) {
- mMutableLiveDataType = loadClassErasure(MUTABLE_LIVE_DATA_CLASS_NAME);
+ mMutableLiveDataType = loadClassErasure(libTypes.getMutableLiveData());
}
return mMutableLiveDataType;
}
ModelClass getViewDataBindingType() {
if (mViewBindingType == null) {
- mViewBindingType = findClass(VIEW_DATA_BINDING, null);
+ mViewBindingType = findClass(libTypes.getViewDataBinding(), null);
}
Preconditions.checkNotNull(mViewBindingType, "Cannot find %s class. Something is wrong "
- + "in the classpath, please submit a bug report", VIEW_DATA_BINDING);
+ + "in the classpath, please submit a bug report", libTypes.getViewDataBinding());
return mViewBindingType;
}
- protected ModelClass[] getObservableFieldTypes() {
+ public ModelClass getViewStubProxyType() {
+ if (mViewStubProxyType == null) {
+ mViewStubProxyType = findClass(libTypes.getViewStubProxy(), null);
+ }
+ return mViewStubProxyType;
+ }
+
+ protected List<ModelClass> getObservableFieldTypes() {
if (mObservableFieldTypes == null) {
- mObservableFieldTypes = new ModelClass[OBSERVABLE_FIELDS.length];
- for (int i = 0; i < OBSERVABLE_FIELDS.length; i++) {
- mObservableFieldTypes[i] = loadClassErasure(OBSERVABLE_FIELDS[i]);
- }
+ mObservableFieldTypes = libTypes.getObservableFields()
+ .stream()
+ .map(this::loadClassErasure)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
}
return mObservableFieldTypes;
}
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/ModelClass.java b/compiler/src/main/java/android/databinding/tool/reflection/ModelClass.java
index b7920936..10218782 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/ModelClass.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/ModelClass.java
@@ -15,17 +15,17 @@
*/
package android.databinding.tool.reflection;
-import android.databinding.Bindable;
+import android.databinding.tool.BindableCompat;
import android.databinding.tool.ext.ExtKt;
import android.databinding.tool.reflection.Callable.Type;
import android.databinding.tool.util.L;
import android.databinding.tool.util.StringUtils;
import com.google.common.collect.ImmutableMap;
-import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.TypeName;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
@@ -78,10 +78,8 @@ public abstract class ModelClass {
*/
public boolean isList() {
for (ModelClass listType : ModelAnalyzer.getInstance().getListTypes()) {
- if (listType != null) {
- if (listType.isAssignableFrom(this)) {
- return true;
- }
+ if (listType.isAssignableFrom(this)) {
+ return true;
}
}
return false;
@@ -504,7 +502,8 @@ public abstract class ModelClass {
if (method.isStatic()) {
flags |= STATIC;
}
- final Bindable bindable;
+ @Nullable
+ final BindableCompat bindable;
if (method.isBindable()) {
flags |= CAN_BE_INVALIDATED;
bindable = method.getBindableAnnotation();
@@ -685,7 +684,9 @@ public abstract class ModelClass {
public TypeName getTypeName() {
// implementation only so that PSI model doesn't break
- return ExtKt.toTypeName(toJavaCode());
+ return ExtKt.toTypeName(
+ toJavaCode(),
+ false);
}
@Override
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/ModelField.java b/compiler/src/main/java/android/databinding/tool/reflection/ModelField.java
index 2baef1e8..1d4e8af1 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/ModelField.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/ModelField.java
@@ -15,14 +15,16 @@
*/
package android.databinding.tool.reflection;
-import android.databinding.Bindable;
+import android.databinding.tool.BindableCompat;
public abstract class ModelField {
/**
* @return Whether this field has been annotated with Bindable.
*/
- public abstract boolean isBindable();
+ public final boolean isBindable() {
+ return getBindableAnnotation() != null;
+ }
/**
* @return The field name.
@@ -52,7 +54,7 @@ public abstract class ModelField {
/**
* @return the Bindable annotation on the field or null if there isn't one.
*/
- public Bindable getBindableAnnotation() {
+ public BindableCompat getBindableAnnotation() {
return null;
}
}
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/ModelMethod.java b/compiler/src/main/java/android/databinding/tool/reflection/ModelMethod.java
index f8c57a0f..c54b505e 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/ModelMethod.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/ModelMethod.java
@@ -15,7 +15,7 @@
*/
package android.databinding.tool.reflection;
-import android.databinding.Bindable;
+import android.databinding.tool.BindableCompat;
import java.util.Collections;
import java.util.List;
@@ -44,14 +44,16 @@ public abstract class ModelMethod {
public abstract boolean isAbstract();
/**
- * @return whether or not this method has been given the {@link Bindable} annotation.
+ * @return whether or not this method has been given the {@code Bindable} annotation.
*/
- public abstract boolean isBindable();
+ public final boolean isBindable() {
+ return getBindableAnnotation() != null;
+ }
/**
* @return the Bindable annotation on the method or null if it doesn't exist.
*/
- public Bindable getBindableAnnotation() {
+ public BindableCompat getBindableAnnotation() {
return null;
}
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationAnalyzer.java b/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationAnalyzer.java
index 115fb442..a3763ce7 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationAnalyzer.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationAnalyzer.java
@@ -15,6 +15,7 @@
*/
package android.databinding.tool.reflection.annotation;
+import android.databinding.tool.LibTypes;
import android.databinding.tool.reflection.ModelAnalyzer;
import android.databinding.tool.reflection.ModelClass;
import android.databinding.tool.reflection.TypeUtil;
@@ -24,7 +25,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
-import javax.annotation.Generated;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
@@ -50,7 +50,8 @@ public class AnnotationAnalyzer extends ModelAnalyzer {
public final ProcessingEnvironment mProcessingEnv;
- public AnnotationAnalyzer(ProcessingEnvironment processingEnvironment) {
+ public AnnotationAnalyzer(ProcessingEnvironment processingEnvironment, LibTypes libTypes) {
+ super(libTypes);
mProcessingEnv = processingEnvironment;
}
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationField.java b/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationField.java
index 25684b64..e6a79572 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationField.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationField.java
@@ -15,7 +15,7 @@
*/
package android.databinding.tool.reflection.annotation;
-import android.databinding.Bindable;
+import android.databinding.tool.BindableCompat;
import android.databinding.tool.reflection.ModelClass;
import android.databinding.tool.reflection.ModelField;
@@ -42,11 +42,6 @@ class AnnotationField extends ModelField {
}
@Override
- public boolean isBindable() {
- return mField.getAnnotation(Bindable.class) != null;
- }
-
- @Override
public String getName() {
return mField.getSimpleName().toString();
}
@@ -74,8 +69,8 @@ class AnnotationField extends ModelField {
}
@Override
- public Bindable getBindableAnnotation() {
- return mField.getAnnotation(Bindable.class);
+ public BindableCompat getBindableAnnotation() {
+ return BindableCompat.extractFrom(mField);
}
@Override
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationMethod.java b/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationMethod.java
index dfff98bb..78567455 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationMethod.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationMethod.java
@@ -15,7 +15,7 @@
*/
package android.databinding.tool.reflection.annotation;
-import android.databinding.Bindable;
+import android.databinding.tool.BindableCompat;
import android.databinding.tool.reflection.ModelClass;
import android.databinding.tool.reflection.ModelMethod;
import android.databinding.tool.reflection.SdkUtil;
@@ -147,13 +147,8 @@ class AnnotationMethod extends ModelMethod {
}
@Override
- public boolean isBindable() {
- return mExecutableElement.getAnnotation(Bindable.class) != null;
- }
-
- @Override
- public Bindable getBindableAnnotation() {
- return mExecutableElement.getAnnotation(Bindable.class);
+ public BindableCompat getBindableAnnotation() {
+ return BindableCompat.extractFrom(mExecutableElement);
}
@Override
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 d427a698..f745d64c 100644
--- a/compiler/src/main/java/android/databinding/tool/store/SetterStore.java
+++ b/compiler/src/main/java/android/databinding/tool/store/SetterStore.java
@@ -15,9 +15,7 @@
*/
package android.databinding.tool.store;
-import android.databinding.InverseBindingListener;
import android.databinding.tool.Context;
-import android.databinding.tool.processing.ErrorMessages;
import android.databinding.tool.reflection.ModelAnalyzer;
import android.databinding.tool.reflection.ModelClass;
import android.databinding.tool.reflection.ModelMethod;
@@ -52,7 +50,6 @@ 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.ExecutableType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Types;
@@ -785,8 +782,10 @@ public class SetterStore {
bestMethod.viewType = adapterViewType;
bestMethod.returnType = adapterValueType;
InverseDescription inverseDescription = adapters.get(key);
- ModelClass listenerType = ModelAnalyzer.getInstance().findClass(
- InverseBindingListener.class);
+ ModelAnalyzer modelAnalyzer = ModelAnalyzer.getInstance();
+ ModelClass listenerType = modelAnalyzer.findClass(
+ modelAnalyzer.libTypes.getInverseBindingListener(),
+ Collections.emptyMap());
BindingSetterCall eventCall = getSetterCall(
inverseDescription.event, viewType, listenerType, imports);
if (eventCall == null) {
@@ -916,8 +915,9 @@ public class SetterStore {
BindingGetterCall call = null;
if (bestDescription != null) {
- final ModelClass listenerType = ModelAnalyzer.getInstance().findClass(
- InverseBindingListener.class);
+ ModelAnalyzer modelAnalyzer = ModelAnalyzer.getInstance();
+ final ModelClass listenerType = modelAnalyzer.findClass(
+ modelAnalyzer.libTypes.getInverseBindingListener(), Collections.emptyMap());
SetterCall eventSetter = getSetterCall(bestDescription.event, viewType,
listenerType, imports);
if (eventSetter == null) {
diff --git a/compiler/src/main/java/android/databinding/tool/writer/ComponentWriter.java b/compiler/src/main/java/android/databinding/tool/writer/ComponentWriter.java
index f2a647f1..8bafece3 100644
--- a/compiler/src/main/java/android/databinding/tool/writer/ComponentWriter.java
+++ b/compiler/src/main/java/android/databinding/tool/writer/ComponentWriter.java
@@ -15,6 +15,7 @@
*/
package android.databinding.tool.writer;
+import android.databinding.tool.LibTypes;
import android.databinding.tool.store.SetterStore;
import java.util.List;
@@ -25,13 +26,16 @@ import java.util.Map;
*/
public class ComponentWriter {
private static final String INDENT = " ";
-
- public ComponentWriter() {
+ private final LibTypes mLibTypes;
+ public ComponentWriter(LibTypes libTypes) {
+ mLibTypes = libTypes;
}
public String createComponent() {
final StringBuilder builder = new StringBuilder();
- builder.append("package android.databinding;\n\n");
+ builder.append("package ");
+ builder.append(mLibTypes.getBindingPackage());
+ builder.append(";\n\n");
builder.append("public interface DataBindingComponent {\n");
final SetterStore setterStore = SetterStore.get();
Map<String, List<String>> bindingAdapters = setterStore.getComponentBindingAdapters();