summaryrefslogtreecommitdiff
path: root/compiler/src/main/java/android/databinding/tool/CompilerChef.java
diff options
context:
space:
mode:
authorYigit Boyar <yboyar@google.com>2018-03-07 09:32:00 -0800
committerYigit Boyar <yboyar@google.com>2018-03-09 14:08:47 -0800
commit213ad9c850a29829f2f61f0cec73944f5f178d05 (patch)
tree6db4db79b052a9d3a7fcf5eb47150fcf567d292c /compiler/src/main/java/android/databinding/tool/CompilerChef.java
parentb5afc9d80f4b7b7c49e1058632d9399ac1db92f3 (diff)
downloaddata-binding-213ad9c850a29829f2f61f0cec73944f5f178d05.tar.gz
Support v1 dependencies in v1 compilation
This CL adds backward compatibility into data binding v2 such that it can consume dependencies that were compiled with v1. We achieve this in 2 steps: * Inside the gradle task, we deserialize v1 layout info and convert it into GenClassLog. This allows gradle task to generate the right code. (albeit, it might depend on not yet existing classes but that is how v1 works anyways). * Then in the annotation processor, we reload the same layout info, create a CompilerChef that thinks it is in v1 and let it generate the code. Finally, we create 1 mapper for all v1 compat classes. All code generated for v1 is stripped for libraries. This is necessary because if 2 separate libraries in an app depend on the same v1 lbirary, both of them will generate code for it, causing duplicate class issues. For apps compiled w/ v2 and has v2 dependencies, cost is almost none (is just the gradle task has 1 more dependency). For apps compiled w/ v1 and has v1 dependencies, it is as slow as v1 is, + a bit more since we end up writing mode classes than we would but it is negligible. Bug: 74264651 Test: MultiModuleTestApp (gradle invokes it w/ v1 - v2 setup) Change-Id: I0e04e7f04b67eb010d4a1bf32e0fce32586a4b90
Diffstat (limited to 'compiler/src/main/java/android/databinding/tool/CompilerChef.java')
-rw-r--r--compiler/src/main/java/android/databinding/tool/CompilerChef.java57
1 files changed, 55 insertions, 2 deletions
diff --git a/compiler/src/main/java/android/databinding/tool/CompilerChef.java b/compiler/src/main/java/android/databinding/tool/CompilerChef.java
index b747d8b4..45638966 100644
--- a/compiler/src/main/java/android/databinding/tool/CompilerChef.java
+++ b/compiler/src/main/java/android/databinding/tool/CompilerChef.java
@@ -32,6 +32,8 @@ 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;
@@ -43,6 +45,11 @@ 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.
@@ -79,10 +86,17 @@ public class CompilerChef {
private ResourceBundle mResourceBundle;
private DataBinder mDataBinder;
private boolean mEnableV2;
+ // the compiler chef we create for V1 dependencies
+ @Nullable
+ private CompilerChef mV1CompatChef;
private CompilerChef() {
}
+ public void setV1CompatChef(CompilerChef v1CompatChef) {
+ mV1CompatChef = v1CompatChef;
+ }
+
public static CompilerChef createChef(
ResourceBundle bundle,
JavaFileWriter fileWriter,
@@ -171,6 +185,7 @@ public class CompilerChef {
}
public void writeDataBinderMapper(
+ ProcessingEnvironment processingEnv,
DataBindingCompilerArgs compilerArgs,
Map<String, Integer> brValueLookup,
List<String> modulePackages) {
@@ -186,6 +201,9 @@ public class CompilerChef {
if (generateMapper) {
writeMapperForModule(compilerArgs, brValueLookup);
}
+ if (mV1CompatChef != null) {
+ writeMapperForV1Compat(compilerArgs, brValueLookup);
+ }
// merged mapper is the one generated for the whole app that includes the mappers
// generated for individual modules.
@@ -198,7 +216,7 @@ public class CompilerChef {
generateMergedMapper = false;
}
if (generateMergedMapper) {
- writeMergedMapper(compilerArgs, modulePackages);
+ writeMergedMapper(processingEnv, compilerArgs, modulePackages);
}
} else {
final String pkg = "android.databinding";
@@ -213,17 +231,52 @@ public class CompilerChef {
}
}
+ private void writeMapperForV1Compat(
+ DataBindingCompilerArgs compilerArgs,
+ Map<String, Integer> brValueLookup) {
+ BindingMapperWriter dbr = new BindingMapperWriter(
+ BindingMapperWriter.V1_COMPAT_MAPPER_PKG,
+ BindingMapperWriter.V1_COMPAT_MAPPER_NAME,
+ mV1CompatChef.getLayoutBinders(),
+ compilerArgs);
+ mFileWriter.writeToFile(
+ BindingMapperWriter.V1_COMPAT_MAPPER_PKG + "." + dbr.getClassName(),
+ dbr.write(brValueLookup));
+ }
+
+ public List<LayoutBinder> getLayoutBinders() {
+ return mDataBinder.getLayoutBinders();
+ }
+
/**
* Writes the mapper android.databinding.DataBinderMapperImpl which is a merged mapper
* that includes all mappers from dependencies.
*/
private void writeMergedMapper(
+ ProcessingEnvironment processingEnv,
DataBindingCompilerArgs compilerArgs,
List<String> modulePackages) {
+ // figure out which mappers exists as they may not exist for v1 libs.
+ List<String> availableDependencyModules = modulePackages.stream()
+ .filter(modulePackage -> {
+ if (modulePackage.equals(compilerArgs.getModulePackage())) {
+ // mine will be generated
+ return true;
+ }
+ String mapper = BindingMapperWriterV2.createMapperQName(modulePackage);
+ TypeElement impl = processingEnv
+ .getElementUtils()
+ .getTypeElement(mapper);
+ return impl != null;
+ }).collect(Collectors.toList());
Set<String> featurePackageIds = loadFeaturePackageIds(compilerArgs);
StringBuilder sb = new StringBuilder();
MergedBindingMapperWriter mergedBindingMapperWriter =
- new MergedBindingMapperWriter(modulePackages, compilerArgs, featurePackageIds);
+ new MergedBindingMapperWriter(
+ availableDependencyModules,
+ compilerArgs,
+ featurePackageIds,
+ mV1CompatChef != null);
TypeSpec mergedMapperSpec = mergedBindingMapperWriter.write();
try {
JavaFile.builder(mergedBindingMapperWriter.getPkg(), mergedMapperSpec)