summaryrefslogtreecommitdiff
path: root/compiler/src/main/java/android/databinding
diff options
context:
space:
mode:
authorYigit Boyar <yboyar@google.com>2018-01-24 17:33:32 -0800
committerYigit Boyar <yboyar@google.com>2018-01-25 09:51:43 -0800
commitc769d69b744d69f6de0a0a952add174f6e98a9b1 (patch)
tree6942b8153f2d88e543795b6937193def4fc058a1 /compiler/src/main/java/android/databinding
parent8b97b676dbb5d496f25ba247458f24cd78740c3e (diff)
downloaddata-binding-c769d69b744d69f6de0a0a952add174f6e98a9b1.tar.gz
Hacky solution to clear singletons from data binding.
Bug: 68339615 Test: existing tests pass Change-Id: I8a9004bc7b2e7c9cfe3b0ad914c721d77069d46e
Diffstat (limited to 'compiler/src/main/java/android/databinding')
-rw-r--r--compiler/src/main/java/android/databinding/annotationprocessor/ProcessBindable.java4
-rw-r--r--compiler/src/main/java/android/databinding/annotationprocessor/ProcessDataBinding.java17
-rw-r--r--compiler/src/main/java/android/databinding/annotationprocessor/ProcessExpressions.java5
-rw-r--r--compiler/src/main/java/android/databinding/annotationprocessor/ProcessMethodAdapters.java2
-rw-r--r--compiler/src/main/java/android/databinding/tool/Binding.java12
-rw-r--r--compiler/src/main/java/android/databinding/tool/BindingTarget.java6
-rw-r--r--compiler/src/main/java/android/databinding/tool/Context.kt87
-rw-r--r--compiler/src/main/java/android/databinding/tool/InverseBinding.java2
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java7
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/MethodCallExpr.java5
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/ModelAnalyzer.java17
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/ModelClass.java2
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/SdkUtil.java50
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/TypeUtil.java9
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationAnalyzer.java2
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationLogger.java16
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationMethod.java2
-rw-r--r--compiler/src/main/java/android/databinding/tool/store/SetterStore.java23
-rw-r--r--compiler/src/main/java/android/databinding/tool/util/GenerationalClassUtil.java65
-rw-r--r--compiler/src/main/java/android/databinding/tool/writer/ComponentWriter.java3
20 files changed, 218 insertions, 118 deletions
diff --git a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessBindable.java b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessBindable.java
index 6f22e0d4..15197eb7 100644
--- a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessBindable.java
+++ b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessBindable.java
@@ -88,7 +88,7 @@ public class ProcessBindable extends ProcessDataBinding.ProcessingStep implement
// We'll get them later when we do the messages
}
}
- GenerationalClassUtil.writeIntermediateFile(mProperties.getPackage(),
+ GenerationalClassUtil.get().writeIntermediateFile(mProperties.getPackage(),
createIntermediateFileName(mProperties.getPackage()), mProperties);
generateBRClasses(args, mProperties.getPackage());
}
@@ -248,7 +248,7 @@ public class ProcessBindable extends ProcessDataBinding.ProcessingStep implement
@SuppressWarnings("CodeBlock2Expr")
private Collection<Intermediate> loadPreviousBRFiles(String... excludePackages) {
- List<Intermediate> brFiles = GenerationalClassUtil
+ List<Intermediate> brFiles = GenerationalClassUtil.get()
.loadObjects(GenerationalClassUtil.ExtensionFilter.BR);
Set<String> excludeMap = Sets.newHashSet(excludePackages);
// dedupe
diff --git a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessDataBinding.java b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessDataBinding.java
index d0dd5433..0a9863e2 100644
--- a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessDataBinding.java
+++ b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessDataBinding.java
@@ -17,6 +17,7 @@
package android.databinding.annotationprocessor;
import android.databinding.tool.CompilerChef;
+import android.databinding.tool.Context;
import android.databinding.tool.DataBindingCompilerArgs;
import android.databinding.tool.processing.Scope;
import android.databinding.tool.processing.ScopedException;
@@ -60,6 +61,16 @@ public class ProcessDataBinding extends AbstractProcessor {
private DataBindingCompilerArgs mCompilerArgs;
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ try {
+ return doProcess(roundEnv);
+ } finally {
+ if (roundEnv.processingOver()) {
+ Context.fullClear(processingEnv);
+ }
+ }
+ }
+
+ private boolean doProcess(RoundEnvironment roundEnv) {
if (mProcessingSteps == null) {
readArguments();
initProcessingSteps();
@@ -73,6 +84,7 @@ public class ProcessDataBinding extends AbstractProcessor {
return false;
}
boolean done = true;
+ Context.init(processingEnv, mCompilerArgs);
for (ProcessingStep step : mProcessingSteps) {
try {
done = step.runStep(roundEnv, processingEnv, mCompilerArgs) && done;
@@ -86,7 +98,6 @@ public class ProcessDataBinding extends AbstractProcessor {
}
}
if (roundEnv.processingOver()) {
- L.flushMessages();
Scope.assertNoError();
}
return done;
@@ -155,7 +166,7 @@ public class ProcessDataBinding extends AbstractProcessor {
* use this instead of init method so that we won't become a problem when data binding happens
* to be in annotation processor classpath by chance
*/
- public synchronized void readArguments() {
+ private synchronized void readArguments() {
try {
mCompilerArgs = DataBindingCompilerArgs
.readFromOptions(processingEnv.getOptions());
@@ -168,8 +179,6 @@ public class ProcessDataBinding extends AbstractProcessor {
throw new RuntimeException("Failed to parse data binding compiler options. Params:\n"
+ allParam, t);
}
- GenerationalClassUtil.init(mCompilerArgs);
- ModelAnalyzer.setProcessingEnvironment(processingEnv);
}
@Override
diff --git a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessExpressions.java b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessExpressions.java
index 90a440ab..6ff47705 100644
--- a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessExpressions.java
+++ b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessExpressions.java
@@ -68,7 +68,6 @@ public class ProcessExpressions extends ProcessDataBinding.ProcessingStep {
throws JAXBException {
try {
ResourceBundle resourceBundle;
- SdkUtil.initialize(args.getMinApi(), new File(args.getSdkDir()));
resourceBundle = new ResourceBundle(args.getModulePackage());
final List<IntermediateV2> intermediateList;
if (args.isEnableV2()) {
@@ -120,7 +119,7 @@ public class ProcessExpressions extends ProcessDataBinding.ProcessingStep {
}
private List<IntermediateV2> loadDependencyIntermediates() {
- final List<Intermediate> original = GenerationalClassUtil.loadObjects(
+ final List<Intermediate> original = GenerationalClassUtil.get().loadObjects(
GenerationalClassUtil.ExtensionFilter.LAYOUT);
final List<IntermediateV2> upgraded = new ArrayList<IntermediateV2>(original.size());
for (Intermediate intermediate : original) {
@@ -136,7 +135,7 @@ public class ProcessExpressions extends ProcessDataBinding.ProcessingStep {
private void saveIntermediate(ProcessingEnvironment processingEnvironment,
DataBindingCompilerArgs args, IntermediateV2 intermediate) {
- GenerationalClassUtil.writeIntermediateFile(args.getModulePackage(),
+ GenerationalClassUtil.get().writeIntermediateFile(args.getModulePackage(),
args.getModulePackage() +
GenerationalClassUtil.ExtensionFilter.LAYOUT.getExtension(),
intermediate);
diff --git a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessMethodAdapters.java b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessMethodAdapters.java
index 2968e35c..4fcfca34 100644
--- a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessMethodAdapters.java
+++ b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessMethodAdapters.java
@@ -64,7 +64,7 @@ public class ProcessMethodAdapters extends ProcessDataBinding.ProcessingStep {
final ModelAnalyzer modelAnalyzer = ModelAnalyzer.getInstance();
Preconditions.checkNotNull(modelAnalyzer, "Model analyzer should be"
+ " initialized first");
- SetterStore store = SetterStore.get(modelAnalyzer);
+ SetterStore store = SetterStore.get();
clearIncrementalClasses(roundEnv, store);
addBindingAdapters(roundEnv, processingEnvironment, store);
diff --git a/compiler/src/main/java/android/databinding/tool/Binding.java b/compiler/src/main/java/android/databinding/tool/Binding.java
index 467a4cad..fe222fdb 100644
--- a/compiler/src/main/java/android/databinding/tool/Binding.java
+++ b/compiler/src/main/java/android/databinding/tool/Binding.java
@@ -128,7 +128,7 @@ public class Binding implements LocationScopeProvider {
ModelAnalyzer modelAnalyzer = ModelAnalyzer.getInstance();
ModelClass viewStubProxy = modelAnalyzer.
findClass("android.databinding.ViewStubProxy", null);
- mSetterCall = SetterStore.get(modelAnalyzer).getSetterCall(mName,
+ mSetterCall = SetterStore.get().getSetterCall(mName,
viewStubProxy, mExpr.getResolvedType(), mExpr.getModel().getImports());
} else if (isViewStubAttribute(mName)) {
mSetterCall = new ViewStubDirectCall(mName, viewType, mExpr.getResolvedType(),
@@ -141,7 +141,7 @@ public class Binding implements LocationScopeProvider {
if (mExpr.getResolvedType().getObservableGetterName() != null) {
// If it is an ObservableField, try with the contents of it first.
Expr expr = mExpr.unwrapObservableField();
- mSetterCall = SetterStore.get(modelAnalyzer).getSetterCall(mName,
+ mSetterCall = SetterStore.get().getSetterCall(mName,
viewType, expr.getResolvedType(), mExpr.getModel().getImports());
if (mSetterCall != null) {
mExpr = expr;
@@ -149,7 +149,7 @@ public class Binding implements LocationScopeProvider {
}
if (mSetterCall == null) {
// Now try with the value object directly
- mSetterCall = SetterStore.get(modelAnalyzer).getSetterCall(mName,
+ mSetterCall = SetterStore.get().getSetterCall(mName,
viewType, mExpr.getResolvedType(), mExpr.getModel().getImports());
}
}
@@ -164,12 +164,12 @@ public class Binding implements LocationScopeProvider {
SetterCall setterCall;
ModelAnalyzer modelAnalyzer = ModelAnalyzer.getInstance();
ModelClass objectParameter = modelAnalyzer.findClass(Object.class);
- SetterStore setterStore = SetterStore.get(modelAnalyzer);
+ SetterStore setterStore = SetterStore.get();
if (viewType != null && viewType.extendsViewStub()) {
if (isListenerAttribute(name)) {
ModelClass viewStubProxy = modelAnalyzer.
findClass("android.databinding.ViewStubProxy", null);
- setterCall = SetterStore.get(modelAnalyzer).getSetterCall(name,
+ setterCall = SetterStore.get().getSetterCall(name,
viewStubProxy, objectParameter, model.getImports());
} else if (isViewStubAttribute(name)) {
setterCall = null; // view stub attrs are not callbacks
@@ -317,7 +317,7 @@ public class Binding implements LocationScopeProvider {
public ViewStubDirectCall(String name, ModelClass viewType, ModelClass resolvedType,
Map<String, String> imports) {
- mWrappedCall = SetterStore.get(ModelAnalyzer.getInstance()).getSetterCall(name,
+ mWrappedCall = SetterStore.get().getSetterCall(name,
viewType, resolvedType, imports);
if (mWrappedCall == null) {
L.e("Cannot find the setter for attribute '%s' on %s with parameter type %s.",
diff --git a/compiler/src/main/java/android/databinding/tool/BindingTarget.java b/compiler/src/main/java/android/databinding/tool/BindingTarget.java
index 83c28b08..38dd7e84 100644
--- a/compiler/src/main/java/android/databinding/tool/BindingTarget.java
+++ b/compiler/src/main/java/android/databinding/tool/BindingTarget.java
@@ -55,7 +55,7 @@ public class BindingTarget implements LocationScopeProvider {
}
public void addBinding(String name, Expr expr) {
- if (SetterStore.get(ModelAnalyzer.getInstance()).isTwoWayEventAttribute(name)) {
+ if (SetterStore.get().isTwoWayEventAttribute(name)) {
L.e(ErrorMessages.TWO_WAY_EVENT_ATTRIBUTE, name);
}
mBindings.add(new Binding(this, name, expr));
@@ -122,7 +122,7 @@ public class BindingTarget implements LocationScopeProvider {
}
public boolean supportsTag() {
- return !SetterStore.get(ModelAnalyzer.getInstance())
+ return !SetterStore.get()
.isUntaggable(mBundle.getFullClassName());
}
@@ -194,7 +194,7 @@ public class BindingTarget implements LocationScopeProvider {
*/
public void resolveMultiSetters() {
L.d("resolving multi setters for %s", getId());
- final SetterStore setterStore = SetterStore.get(ModelAnalyzer.getInstance());
+ final SetterStore setterStore = SetterStore.get();
String[] attributes = new String[mBindings.size()];
ModelClass[] types = new ModelClass[mBindings.size()];
boolean hasObservableFields = false;
diff --git a/compiler/src/main/java/android/databinding/tool/Context.kt b/compiler/src/main/java/android/databinding/tool/Context.kt
new file mode 100644
index 00000000..23d9f2a4
--- /dev/null
+++ b/compiler/src/main/java/android/databinding/tool/Context.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.databinding.tool
+
+import android.databinding.tool.reflection.ModelAnalyzer
+import android.databinding.tool.reflection.SdkUtil
+import android.databinding.tool.reflection.TypeUtil
+import android.databinding.tool.reflection.annotation.AnnotationAnalyzer
+import android.databinding.tool.reflection.annotation.AnnotationLogger
+import android.databinding.tool.store.SetterStore
+import android.databinding.tool.util.GenerationalClassUtil
+import android.databinding.tool.util.L
+import java.io.File
+import javax.annotation.processing.ProcessingEnvironment
+
+/**
+ * Simple class to hold all singletons so that it is relatively easier to clean them.
+ * We cannot easily get rid of singletons w/o a bigger change so this is a middle ground where
+ * we can start clearing them from a central location.
+ *
+ * Singletons are expected to use this to keep their instances.
+ */
+object Context {
+ private val logger : AnnotationLogger = AnnotationLogger()
+ @JvmStatic
+ fun init(processingEnvironment: ProcessingEnvironment,
+ args : DataBindingCompilerArgs) {
+ generationalClassUtil = GenerationalClassUtil.create(args)
+ modelAnalyzer = AnnotationAnalyzer(processingEnvironment)
+ typeUtil = modelAnalyzer!!.createTypeUtil()
+ setterStore = SetterStore.create(modelAnalyzer, generationalClassUtil)
+ sdkUtil = SdkUtil.create(File(args.sdkDir), args.minApi)
+ L.setClient(logger)
+ }
+
+ @JvmStatic
+ fun initForTests(modelAnayzer: ModelAnalyzer, sdkUtil: SdkUtil) {
+ this.modelAnalyzer = modelAnayzer
+ this.sdkUtil = sdkUtil
+ typeUtil = modelAnalyzer!!.createTypeUtil()
+ }
+
+ @JvmStatic
+ var modelAnalyzer : ModelAnalyzer? = null
+ private set
+
+ @JvmStatic
+ var setterStore : SetterStore? = null
+ private set
+
+ @JvmStatic
+ var generationalClassUtil : GenerationalClassUtil? = null
+ private set
+
+ @JvmStatic
+ var typeUtil : TypeUtil? = null
+ private set
+
+ @JvmStatic
+ var sdkUtil : SdkUtil? = null
+ private set
+
+ @JvmStatic
+ fun fullClear(processingEnvironment: ProcessingEnvironment) {
+ logger.flushMessages(processingEnvironment)
+ modelAnalyzer = null
+ setterStore = null
+ generationalClassUtil = null
+ typeUtil = null
+ sdkUtil = null
+ L.setClient(null)
+ }
+}
diff --git a/compiler/src/main/java/android/databinding/tool/InverseBinding.java b/compiler/src/main/java/android/databinding/tool/InverseBinding.java
index a2960c71..86564886 100644
--- a/compiler/src/main/java/android/databinding/tool/InverseBinding.java
+++ b/compiler/src/main/java/android/databinding/tool/InverseBinding.java
@@ -105,7 +105,7 @@ public class InverseBinding implements LocationScopeProvider {
Scope.enter(mTarget);
Scope.enter(this);
ModelClass viewType = mTarget.getResolvedType();
- final SetterStore setterStore = SetterStore.get(ModelAnalyzer.getInstance());
+ final SetterStore setterStore = SetterStore.get();
final ModelClass resolvedType = expr == null ? null : expr.getResolvedType();
mGetterCall = setterStore.getGetterCall(mName, viewType, resolvedType,
expr.getModel().getImports());
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 d51df2f3..7a41d30f 100644
--- a/compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java
+++ b/compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java
@@ -16,7 +16,6 @@
package android.databinding.tool.expr;
-import android.databinding.Bindable;
import android.databinding.tool.Binding;
import android.databinding.tool.BindingTarget;
import android.databinding.tool.InverseBinding;
@@ -27,7 +26,6 @@ import android.databinding.tool.reflection.Callable;
import android.databinding.tool.reflection.Callable.Type;
import android.databinding.tool.reflection.ModelAnalyzer;
import android.databinding.tool.reflection.ModelClass;
-import android.databinding.tool.reflection.ModelField;
import android.databinding.tool.store.SetterStore;
import android.databinding.tool.store.SetterStore.BindingGetterCall;
import android.databinding.tool.util.BrNameUtil;
@@ -35,14 +33,11 @@ import android.databinding.tool.util.L;
import android.databinding.tool.util.Preconditions;
import android.databinding.tool.util.StringUtils;
import android.databinding.tool.writer.KCode;
-
import com.google.common.collect.Lists;
-import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import java.util.stream.Collectors;
public class FieldAccessExpr extends MethodBaseExpr {
// notification name for the field. Important when we map this to a method w/ different name
@@ -343,7 +338,7 @@ public class FieldAccessExpr extends MethodBaseExpr {
// There was no binding expression to bind to. This should be a two-way binding.
// This is a synthesized two-way binding because we must capture the events from
// the View and change the value when the target View's attribute changes.
- final SetterStore setterStore = SetterStore.get(ModelAnalyzer.getInstance());
+ final SetterStore setterStore = SetterStore.get();
final ModelClass targetClass = expr.getResolvedType();
BindingGetterCall getter = setterStore.getGetterCall(mName, targetClass, null, null);
if (getter == null) {
diff --git a/compiler/src/main/java/android/databinding/tool/expr/MethodCallExpr.java b/compiler/src/main/java/android/databinding/tool/expr/MethodCallExpr.java
index 371925c2..0029e9e9 100644
--- a/compiler/src/main/java/android/databinding/tool/expr/MethodCallExpr.java
+++ b/compiler/src/main/java/android/databinding/tool/expr/MethodCallExpr.java
@@ -36,7 +36,6 @@ import java.util.List;
import static android.databinding.tool.reflection.Callable.DYNAMIC;
import static android.databinding.tool.reflection.Callable.STATIC;
-
public class MethodCallExpr extends Expr {
final String mName;
Callable mGetter;
@@ -267,7 +266,7 @@ public class MethodCallExpr extends Expr {
@Override
public String getInvertibleError() {
- final SetterStore setterStore = SetterStore.get(ModelAnalyzer.getInstance());
+ final SetterStore setterStore = SetterStore.get();
getResolvedType(); // ensure mMethod has been set
if (mMethod == null) {
return "Could not find the method " + mName + " to inverse for two-way binding";
@@ -299,7 +298,7 @@ public class MethodCallExpr extends Expr {
inverse.setUnwrapObservableFields(false);
return inverse;
}
- SetterStore setterStore = SetterStore.get(ModelAnalyzer.getInstance());
+ SetterStore setterStore = SetterStore.get();
String methodName = setterStore.getInverseMethod(mMethod);
List<Expr> theseArgs = getArgs();
List<Expr> args = new ArrayList<>();
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 a6ecc5b7..e8be90db 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/ModelAnalyzer.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/ModelAnalyzer.java
@@ -15,6 +15,7 @@
*/
package android.databinding.tool.reflection;
+import android.databinding.tool.Context;
import android.databinding.tool.reflection.annotation.AnnotationAnalyzer;
import android.databinding.tool.util.L;
import android.databinding.tool.util.Preconditions;
@@ -94,14 +95,9 @@ public abstract class ModelAnalyzer {
*/
private Boolean mHasGeneratedAnnotation;
- private static ModelAnalyzer sAnalyzer;
private final Map<String, InjectedClass> mInjectedClasses =
new HashMap<String, InjectedClass>();
- protected void setInstance(ModelAnalyzer analyzer) {
- sAnalyzer = analyzer;
- }
-
public ModelClass findCommonParentOf(ModelClass modelClass1, ModelClass modelClass2) {
return findCommonParentOf(modelClass1, modelClass2, true);
}
@@ -136,16 +132,7 @@ public abstract class ModelAnalyzer {
public abstract ModelClass loadPrimitive(String className);
public static ModelAnalyzer getInstance() {
- return sAnalyzer;
- }
-
- public static void setProcessingEnvironment(ProcessingEnvironment processingEnvironment) {
- if (sAnalyzer != null) {
- throw new IllegalStateException("processing env is already created, you cannot "
- + "change class loader after that");
- }
- L.d("setting processing env to %s", processingEnvironment);
- sAnalyzer = new AnnotationAnalyzer(processingEnvironment);
+ return Context.getModelAnalyzer();
}
/**
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 d4a022af..b7920936 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/ModelClass.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/ModelClass.java
@@ -451,7 +451,7 @@ public abstract class ModelClass {
* return 1.
*/
public int getMinApi() {
- return SdkUtil.getMinApi(this);
+ return SdkUtil.get().getMinApi(this);
}
/**
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/SdkUtil.java b/compiler/src/main/java/android/databinding/tool/reflection/SdkUtil.java
index 350dda51..d9a82d66 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/SdkUtil.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/SdkUtil.java
@@ -19,9 +19,12 @@ import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
+import android.databinding.tool.Context;
import android.databinding.tool.util.L;
import android.databinding.tool.util.Preconditions;
+import com.android.annotations.VisibleForTesting;
+
import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
@@ -40,29 +43,37 @@ import javax.xml.xpath.XPathFactory;
*/
public class SdkUtil {
- static ApiChecker sApiChecker;
+ private ApiChecker mApiChecker;
+
+ private final int mMinSdk;
+
+ public SdkUtil(ApiChecker mApiChecker, int mMinSdk) {
+ this.mApiChecker = mApiChecker;
+ this.mMinSdk = mMinSdk;
+ }
- static int sMinSdk;
+ public static SdkUtil create(File sdkPath, int minSdk) {
+ ApiChecker checker = new ApiChecker(new File(sdkPath.getAbsolutePath()
+ + "/platform-tools/api/api-versions.xml"));
+ return new SdkUtil(checker, minSdk);
+ }
- public static void initialize(int minSdk, File sdkPath) {
- sMinSdk = minSdk;
- sApiChecker = new ApiChecker(new File(sdkPath.getAbsolutePath()
- + "/platform-tools/api/api-versions.xml"));
- L.d("SdkUtil init, minSdk: %s", minSdk);
+ public static SdkUtil get() {
+ return Context.getSdkUtil();
}
- public static int getMinApi(ModelClass modelClass) {
- return sApiChecker.getMinApi(modelClass.getJniDescription(), null);
+ public int getMinApi(ModelClass modelClass) {
+ return mApiChecker.getMinApi(modelClass.getJniDescription(), null);
}
- public static int getMinApi(ModelMethod modelMethod) {
+ public int getMinApi(ModelMethod modelMethod) {
ModelClass declaringClass = modelMethod.getDeclaringClass();
- Preconditions.checkNotNull(sApiChecker, "should've initialized api checker");
+ Preconditions.checkNotNull(mApiChecker, "should've initialized api checker");
int minApi = Integer.MAX_VALUE;
String methodDesc = modelMethod.getJniDescription();
while (declaringClass != null) {
String classDesc = declaringClass.getJniDescription();
- int result = sApiChecker.getMinApi(classDesc, methodDesc);
+ int result = mApiChecker.getMinApi(classDesc, methodDesc);
L.d("checking method api for %s, class:%s method:%s. result: %d", modelMethod.getName(),
classDesc, methodDesc, result);
if (result > 0) {
@@ -76,7 +87,20 @@ public class SdkUtil {
return minApi;
}
- static class ApiChecker {
+ public ApiChecker getApiChecker() {
+ return mApiChecker;
+ }
+
+ public int getMinSdk() {
+ return mMinSdk;
+ }
+
+ @VisibleForTesting
+ public void swapApiChecker(ApiChecker apiChecker) {
+ mApiChecker = apiChecker;
+ }
+
+ public static class ApiChecker {
private Map<String, Integer> mFullLookup;
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/TypeUtil.java b/compiler/src/main/java/android/databinding/tool/reflection/TypeUtil.java
index 2fd1735d..1dcb435c 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/TypeUtil.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/TypeUtil.java
@@ -16,6 +16,8 @@
package android.databinding.tool.reflection;
+import android.databinding.tool.Context;
+
public abstract class TypeUtil {
public static final String BYTE = "B";
@@ -42,8 +44,6 @@ public abstract class TypeUtil {
public static final String CLASS_SUFFIX = ";";
- private static TypeUtil sInstance;
-
abstract public String getDescription(ModelClass modelClass);
abstract public String getDescription(ModelMethod modelMethod);
@@ -83,9 +83,6 @@ public abstract class TypeUtil {
}
public static TypeUtil getInstance() {
- if (sInstance == null) {
- sInstance = ModelAnalyzer.getInstance().createTypeUtil();
- }
- return sInstance;
+ return Context.getTypeUtil();
}
}
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 6357e9b9..115fb442 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
@@ -52,8 +52,6 @@ public class AnnotationAnalyzer extends ModelAnalyzer {
public AnnotationAnalyzer(ProcessingEnvironment processingEnvironment) {
mProcessingEnv = processingEnvironment;
- setInstance(this);
- L.setClient(new AnnotationLogger(processingEnvironment));
}
public static AnnotationAnalyzer get() {
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationLogger.java b/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationLogger.java
index 4501e519..df054c01 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationLogger.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationLogger.java
@@ -35,17 +35,12 @@ import javax.tools.Diagnostic;
* Messager and then writes them all out when flushMessages() is called. Elements
* are kept in a round-independent format so that the messages can be logged
* independently from the annotation processing round in which they were created.
- * {@link #flushMessages()} should be called when all rounds are over so that
+ * {@link #flushMessages(ProcessingEnvironment)} should be called when all rounds are over so that
* superfluous errors aren't generated.
*/
-class AnnotationLogger implements L.Client {
- private final ProcessingEnvironment mProcessingEnvironment;
+public class AnnotationLogger implements L.Client {
private final ArrayList<Message> mMessages = new ArrayList<>();
- AnnotationLogger(ProcessingEnvironment processingEnvironment) {
- mProcessingEnvironment = processingEnvironment;
- }
-
@Override
public void printMessage(Diagnostic.Kind kind, String message, Element element) {
ElementPath elementPath = null;
@@ -59,13 +54,12 @@ class AnnotationLogger implements L.Client {
}
}
- @Override
- public void flushMessages() {
- Messager messager = mProcessingEnvironment.getMessager();
+ public void flushMessages(ProcessingEnvironment processingEnvironment) {
+ Messager messager = processingEnvironment.getMessager();
synchronized (mMessages) {
for (Message message : mMessages) {
if (message.element != null) {
- Element element = message.element.toElement(mProcessingEnvironment);
+ Element element = message.element.toElement(processingEnvironment);
messager.printMessage(message.kind, message.message, element);
} else {
messager.printMessage(message.kind, message.message);
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 e9f59d82..dfff98bb 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
@@ -159,7 +159,7 @@ class AnnotationMethod extends ModelMethod {
@Override
public int getMinApi() {
if (mApiLevel == -1) {
- mApiLevel = SdkUtil.getMinApi(this);
+ mApiLevel = SdkUtil.get().getMinApi(this);
}
return mApiLevel;
}
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 c73c424f..d427a698 100644
--- a/compiler/src/main/java/android/databinding/tool/store/SetterStore.java
+++ b/compiler/src/main/java/android/databinding/tool/store/SetterStore.java
@@ -16,6 +16,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;
@@ -58,7 +59,6 @@ import javax.lang.model.util.Types;
public class SetterStore {
private static final int ASSIGNABLE_CONVERSION = 1;
- private static SetterStore sStore;
private final IntermediateV3 mStore;
private final ModelAnalyzer mClassAnalyzer;
@@ -170,16 +170,19 @@ public class SetterStore {
}
}
- public static SetterStore get(ModelAnalyzer modelAnalyzer) {
- if (sStore == null) {
- sStore = load(modelAnalyzer);
- }
- return sStore;
+ public static SetterStore get() {
+ return Context.getSetterStore();
+ }
+
+ public static SetterStore create(ModelAnalyzer modelAnalyzer,
+ GenerationalClassUtil generationalClassUtil) {
+ return load(modelAnalyzer, generationalClassUtil);
}
- private static SetterStore load(ModelAnalyzer modelAnalyzer) {
+ private static SetterStore load(ModelAnalyzer modelAnalyzer,
+ GenerationalClassUtil generationalClassUtil) {
IntermediateV3 store = new IntermediateV3();
- List<Intermediate> previousStores = GenerationalClassUtil
+ List<Intermediate> previousStores = GenerationalClassUtil.get()
.loadObjects(GenerationalClassUtil.ExtensionFilter.SETTER_STORE);
for (Intermediate intermediate : previousStores) {
merge(store, intermediate);
@@ -485,7 +488,7 @@ public class SetterStore {
public void write(String projectPackage, ProcessingEnvironment processingEnvironment)
throws IOException {
- GenerationalClassUtil.writeIntermediateFile(projectPackage, projectPackage +
+ GenerationalClassUtil.get().writeIntermediateFile(projectPackage, projectPackage +
GenerationalClassUtil.ExtensionFilter.SETTER_STORE.getExtension(), mStore);
}
@@ -1187,7 +1190,7 @@ public class SetterStore {
if (adapter.isStatic) {
sb.append(adapter.type);
} else {
- final SetterStore setterStore = SetterStore.get(ModelAnalyzer.getInstance());
+ final SetterStore setterStore = SetterStore.get();
final String binderCall = setterStore.getBindingAdapterCall(adapter.type);
sb.append(componentExpression).append('.').append(binderCall);
}
diff --git a/compiler/src/main/java/android/databinding/tool/util/GenerationalClassUtil.java b/compiler/src/main/java/android/databinding/tool/util/GenerationalClassUtil.java
index b6e97c56..6a1319f2 100644
--- a/compiler/src/main/java/android/databinding/tool/util/GenerationalClassUtil.java
+++ b/compiler/src/main/java/android/databinding/tool/util/GenerationalClassUtil.java
@@ -17,6 +17,7 @@
package android.databinding.tool.util;
import android.databinding.annotationprocessor.ProcessExpressions;
+import android.databinding.tool.Context;
import android.databinding.tool.DataBindingBuilder;
import android.databinding.tool.DataBindingCompilerArgs;
@@ -43,53 +44,61 @@ import java.util.List;
* and their extraction later on.
*/
public class GenerationalClassUtil {
- private static List[] sCache = null;
+ private List[] mCache = null;
@Nullable
- private static List<File> sInputDirs = new ArrayList<>();
+ private List<File> mInputDirs;
@Nullable
- private static File sIncrementalOutDir;
+ private File mIncrementalOutDir;
- private static ExtensionFilter[] sEnabledExtensions;
+ private ExtensionFilter[] mEnabledExtensions;
- public static void init(DataBindingCompilerArgs args) {
+ public static GenerationalClassUtil create(DataBindingCompilerArgs args) {
+ return new GenerationalClassUtil(args);
+ }
+
+ private GenerationalClassUtil(DataBindingCompilerArgs args) {
if (args.isEnableV2()) {
- sEnabledExtensions = new ExtensionFilter[]{ExtensionFilter.BR,
+ mEnabledExtensions = new ExtensionFilter[]{ExtensionFilter.BR,
ExtensionFilter.SETTER_STORE};
} else {
- sEnabledExtensions = new ExtensionFilter[]{ExtensionFilter.BR, ExtensionFilter.LAYOUT,
+ mEnabledExtensions = new ExtensionFilter[]{ExtensionFilter.BR, ExtensionFilter.LAYOUT,
ExtensionFilter.SETTER_STORE};
}
if (StringUtils.isNotBlank(args.getAarOutFolder())) {
- sIncrementalOutDir = new File(args.getAarOutFolder(),
+ mIncrementalOutDir = new File(args.getAarOutFolder(),
DataBindingBuilder.INCREMENTAL_BIN_AAR_DIR);
} else {
- sIncrementalOutDir = null;
+ mIncrementalOutDir = null;
}
- sInputDirs = new ArrayList<>();
+ mInputDirs = new ArrayList<>();
if (StringUtils.isNotBlank(args.getBuildFolder())) {
- sInputDirs.add(new File(args.getBuildFolder(),
+ mInputDirs.add(new File(args.getBuildFolder(),
DataBindingBuilder.ARTIFACT_FILES_DIR_FROM_LIBS));
}
}
- public static <T extends Serializable> List<T> loadObjects(ExtensionFilter filter) {
- if (sCache == null) {
+ public static GenerationalClassUtil get() {
+ return Context.getGenerationalClassUtil();
+ }
+
+ public <T extends Serializable> List<T> loadObjects(ExtensionFilter filter) {
+ if (mCache == null) {
buildCache();
}
- List result = sCache[filter.ordinal()];
+ List result = mCache[filter.ordinal()];
Preconditions.checkNotNull(result, "Invalid filter " + filter);
//noinspection unchecked
return result;
}
- private static void buildCache() {
+ private void buildCache() {
L.d("building generational class cache");
- sCache = new List[ExtensionFilter.values().length];
- for (ExtensionFilter filter : sEnabledExtensions) {
- sCache[filter.ordinal()] = new ArrayList();
+ mCache = new List[ExtensionFilter.values().length];
+ for (ExtensionFilter filter : mEnabledExtensions) {
+ mCache[filter.ordinal()] = new ArrayList();
}
loadFromBuildInfo();
}
@@ -105,17 +114,17 @@ public class GenerationalClassUtil {
* This is a backward compatibility measure and should eventually be phased out after we move
* to an aar based information retrieval model.
*/
- private static void loadFromBuildInfo() {
- sInputDirs.forEach(GenerationalClassUtil::loadFromDirectory);
+ private void loadFromBuildInfo() {
+ mInputDirs.forEach(this::loadFromDirectory);
}
- private static void loadFromDirectory(File directory) {
+ private void loadFromDirectory(File directory) {
if (directory == null || !directory.canRead() || !directory.isDirectory()) {
return;
}
for (File file : FileUtils.listFiles(directory, TrueFileFilter.INSTANCE,
TrueFileFilter.INSTANCE)) {
- for (ExtensionFilter filter : sEnabledExtensions) {
+ for (ExtensionFilter filter : mEnabledExtensions) {
if (filter.accept(file.getName())) {
InputStream inputStream = null;
try {
@@ -123,7 +132,7 @@ public class GenerationalClassUtil {
Serializable item = fromInputStream(inputStream);
if (item != null) {
//noinspection unchecked
- sCache[filter.ordinal()].add(item);
+ mCache[filter.ordinal()].add(item);
L.d("loaded item %s from file", item);
}
} catch (IOException e) {
@@ -139,24 +148,24 @@ public class GenerationalClassUtil {
}
}
- private static Serializable fromInputStream(InputStream inputStream)
+ private Serializable fromInputStream(InputStream inputStream)
throws IOException, ClassNotFoundException {
ObjectInputStream in = new IgnoreSerialIdObjectInputStream(inputStream);
return (Serializable) in.readObject();
}
- public static void writeIntermediateFile(String packageName, String fileName,
+ public void writeIntermediateFile(String packageName, String fileName,
Serializable object) {
ObjectOutputStream oos = null;
OutputStream ios = null;
try {
try {
- Preconditions.checkNotNull(sIncrementalOutDir, "incremental out directory should be"
+ Preconditions.checkNotNull(mIncrementalOutDir, "incremental out directory should be"
+ " set to aar output directory.");
//noinspection ResultOfMethodCallIgnored
- sIncrementalOutDir.mkdirs();
- File out = new File(sIncrementalOutDir, packageName + "-" + fileName);
+ mIncrementalOutDir.mkdirs();
+ File out = new File(mIncrementalOutDir, packageName + "-" + fileName);
ios = new FileOutputStream(out);
oos = new ObjectOutputStream(ios);
oos.writeObject(object);
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 e7af414e..f2a647f1 100644
--- a/compiler/src/main/java/android/databinding/tool/writer/ComponentWriter.java
+++ b/compiler/src/main/java/android/databinding/tool/writer/ComponentWriter.java
@@ -15,7 +15,6 @@
*/
package android.databinding.tool.writer;
-import android.databinding.tool.reflection.ModelAnalyzer;
import android.databinding.tool.store.SetterStore;
import java.util.List;
@@ -34,7 +33,7 @@ public class ComponentWriter {
final StringBuilder builder = new StringBuilder();
builder.append("package android.databinding;\n\n");
builder.append("public interface DataBindingComponent {\n");
- final SetterStore setterStore = SetterStore.get(ModelAnalyzer.getInstance());
+ final SetterStore setterStore = SetterStore.get();
Map<String, List<String>> bindingAdapters = setterStore.getComponentBindingAdapters();
for (final String simpleName : bindingAdapters.keySet()) {
final List<String> classes = bindingAdapters.get(simpleName);