aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar corysmith <corysmith@google.com>2018-08-03 15:38:35 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-08-03 15:40:24 -0700
commit68cbbe96e8b28e8de50228275f7d2d83c2bb137b (patch)
tree8764c35ced54abaf6ca5f67c417ebea064a9a51d
parent0cb8590de83b9250eee198a3f82078aad74f42b5 (diff)
Moved all external calls to isDataEnabled to DataBindingContext and made it private.
RELNOTES: None PiperOrigin-RevId: 207335684
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java35
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java56
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java19
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java60
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/DataBinding.java104
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ProcessedAndroidData.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java36
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidResources.java2
-rw-r--r--src/test/java/com/google/devtools/build/lib/rules/android/AndroidResourcesTest.java9
12 files changed, 222 insertions, 117 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
index 959ffe83dd..dc4b78d317 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
@@ -114,23 +114,8 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
AndroidSdkProvider.verifyPresence(ruleContext);
NestedSetBuilder<Artifact> filesBuilder = NestedSetBuilder.stableOrder();
- JavaCommon javaCommon =
- AndroidCommon.createJavaCommonWithAndroidDataBinding(ruleContext, javaSemantics, false);
- javaSemantics.checkRule(ruleContext, javaCommon);
- javaSemantics.checkForProtoLibraryAndJavaProtoLibraryOnSameProto(ruleContext, javaCommon);
-
- AndroidCommon androidCommon = new AndroidCommon(javaCommon, /* asNeverLink= */ true);
- ResourceDependencies resourceDeps =
- ResourceDependencies.fromRuleDeps(ruleContext, /* neverlink= */ false);
RuleConfiguredTargetBuilder builder =
- init(
- ruleContext,
- filesBuilder,
- resourceDeps,
- androidCommon,
- cppSemantics,
- javaSemantics,
- androidSemantics);
+ init(ruleContext, filesBuilder, cppSemantics, javaSemantics, androidSemantics);
return builder.build();
}
@@ -175,13 +160,14 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
private static RuleConfiguredTargetBuilder init(
RuleContext ruleContext,
NestedSetBuilder<Artifact> filesBuilder,
- ResourceDependencies resourceDeps,
- AndroidCommon androidCommon,
CppSemantics cppSemantics,
JavaSemantics javaSemantics,
AndroidSemantics androidSemantics)
throws InterruptedException, RuleErrorException {
+ ResourceDependencies resourceDeps =
+ ResourceDependencies.fromRuleDeps(ruleContext, /* neverlink= */ false);
+
validateRuleContext(ruleContext);
NativeLibs nativeLibs =
@@ -229,7 +215,6 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
ResourceFilterFactory.fromRuleContextAndAttrs(ruleContext),
ruleContext.getExpander().withDataLocations().tokenized("nocompress_extensions"),
ruleContext.attributes().get("crunch_png", Type.BOOLEAN),
- DataBinding.isEnabled(ruleContext),
ruleContext.attributes().isAttributeValueExplicitlySpecified("feature_of")
? ruleContext
.getPrerequisite("feature_of", Mode.TARGET, ApkInfo.PROVIDER)
@@ -261,6 +246,7 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
applicationManifest.packBinaryWithDataAndResources(
ruleContext,
dataContext,
+ DataBinding.contextFrom(ruleContext),
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_APK),
resourceDeps,
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_R_TXT),
@@ -273,15 +259,20 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
dataContext.getAndroidConfig(), ruleContext, shrinkResources),
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_PROCESSED_MANIFEST),
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_ZIP),
- DataBinding.isEnabled(ruleContext)
- ? DataBinding.getLayoutInfoFile(ruleContext)
- : null,
featureOfArtifact,
featureAfterArtifact);
}
ruleContext.assertNoErrors();
+ JavaCommon javaCommon =
+ AndroidCommon.createJavaCommonWithAndroidDataBinding(
+ ruleContext, javaSemantics, resourceApk.asDataBindingContext(), /* isLibrary */ false);
+ javaSemantics.checkRule(ruleContext, javaCommon);
+ javaSemantics.checkForProtoLibraryAndJavaProtoLibraryOnSameProto(ruleContext, javaCommon);
+
+ AndroidCommon androidCommon = new AndroidCommon(javaCommon, /* asNeverLink= */ true);
+
// Remove the library resource JARs from the binary's runtime classpath.
// Resource classes from android_library dependencies are replaced by the binary's resource
// class. We remove them only at the top level so that resources included by a library that is
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
index edeee584dd..cc5c0d3fb8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
@@ -44,6 +44,7 @@ import com.google.devtools.build.lib.packages.NativeProvider;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.packages.TriState;
+import com.google.devtools.build.lib.rules.android.DataBinding.DataBindingContext;
import com.google.devtools.build.lib.rules.android.ZipFilterBuilder.CheckHashMismatchMode;
import com.google.devtools.build.lib.rules.cpp.AbstractCcLinkParamsStore;
import com.google.devtools.build.lib.rules.cpp.CcLinkParams;
@@ -483,16 +484,23 @@ public class AndroidCommon {
}
ImmutableList.Builder<String> javacopts = ImmutableList.builder();
javacopts.addAll(androidSemantics.getCompatibleJavacOptions(ruleContext));
- if (DataBinding.isEnabled(ruleContext)) {
- javacopts.addAll(DataBinding.getJavacOpts(ruleContext, isBinary));
- }
+
+ resourceApk
+ .asDataBindingContext()
+ .supplyJavaCoptsUsing(ruleContext, isBinary, javacopts::addAll);
JavaTargetAttributes.Builder attributes =
javaCommon
.initCommon(idlHelper.getIdlGeneratedJavaSources(), javacopts.build())
.setBootClassPath(bootclasspath);
- if (DataBinding.isEnabled(ruleContext)) {
- DataBinding.addAnnotationProcessor(ruleContext, attributes);
- }
+
+ resourceApk
+ .asDataBindingContext()
+ .supplyAnnotationProcessor(
+ ruleContext,
+ (plugin, additionalOutputs) -> {
+ attributes.addPlugin(plugin);
+ attributes.addAdditionalOutputs(additionalOutputs);
+ });
if (excludedRuntimeArtifacts != null) {
attributes.addExcludedArtifacts(excludedRuntimeArtifacts);
@@ -514,7 +522,9 @@ public class AndroidCommon {
jarsProducedForRuntime.add(resourceApk.getResourceJavaClassJar());
}
- JavaCompilationHelper helper = initAttributes(attributes, javaSemantics);
+ JavaCompilationHelper helper =
+ initAttributes(
+ attributes, javaSemantics, resourceApk.asDataBindingContext().processDeps(ruleContext));
if (ruleContext.hasErrors()) {
return null;
}
@@ -545,15 +555,16 @@ public class AndroidCommon {
}
private JavaCompilationHelper initAttributes(
- JavaTargetAttributes.Builder attributes, JavaSemantics semantics) {
- boolean useDataBinding = DataBinding.isEnabled(ruleContext);
+ JavaTargetAttributes.Builder attributes,
+ JavaSemantics semantics,
+ ImmutableList<Artifact> additionalArtifacts) {
JavaCompilationHelper helper =
new JavaCompilationHelper(
ruleContext,
semantics,
javaCommon.getJavacOpts(),
attributes,
- useDataBinding ? DataBinding.processDeps(ruleContext) : ImmutableList.<Artifact>of(),
+ additionalArtifacts,
/*disableStrictDeps=*/ false);
helper.addLibrariesToAttributes(javaCommon.targetsTreatedAsDeps(ClasspathType.COMPILE_ONLY));
@@ -845,25 +856,14 @@ public class AndroidCommon {
* <p>No rule needs <i>any</i> support if data binding is disabled.
*/
static JavaCommon createJavaCommonWithAndroidDataBinding(
- RuleContext ruleContext, JavaSemantics semantics, boolean isLibrary) {
- boolean useDataBinding = DataBinding.isEnabled(ruleContext);
-
+ RuleContext ruleContext,
+ JavaSemantics semantics,
+ DataBindingContext dataBindingContext,
+ boolean isLibrary) {
ImmutableList<Artifact> srcs =
- ruleContext.getPrerequisiteArtifacts("srcs", RuleConfiguredTarget.Mode.TARGET).list();
- if (useDataBinding) {
- // Add this rule's annotation processor input. If the rule doesn't have direct resources,
- // there's no direct data binding info, so there's strictly no need for annotation processing.
- // But it's still important to process the deps' .bin files so any Java class references get
- // re-referenced so they don't get filtered out of the compilation classpath by JavaBuilder
- // (which filters out classpath .jars that "aren't used": see --reduce_classpath). If data
- // binding didn't reprocess a library's data binding expressions redundantly up the dependency
- // chain (meaning each depender processes them again as if they were its own), this problem
- // wouldn't happen.
- Artifact annotationFile = DataBinding.createAnnotationFile(ruleContext);
- if (annotationFile != null) {
- srcs = ImmutableList.<Artifact>builder().addAll(srcs).add(annotationFile).build();
- }
- }
+ dataBindingContext.addAnnotationFileToSrcs(
+ ruleContext.getPrerequisiteArtifacts("srcs", RuleConfiguredTarget.Mode.TARGET).list(),
+ ruleContext);
ImmutableList<TransitiveInfoCollection> compileDeps;
ImmutableList<TransitiveInfoCollection> runtimeDeps;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java
index 58ef404322..54e7683d07 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java
@@ -135,13 +135,6 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory {
AndroidIdlHelper.maybeAddSupportLibProguardConfigs(ruleContext, proguardConfigsbuilder);
NestedSet<Artifact> transitiveProguardConfigs = proguardConfigsbuilder.build();
- // JavaCommon and AndroidCommon contain shared helper classes between java_* and android_*
- // rules respectively.
- JavaCommon javaCommon =
- AndroidCommon.createJavaCommonWithAndroidDataBinding(ruleContext, javaSemantics, true);
- javaSemantics.checkRule(ruleContext, javaCommon);
- AndroidCommon androidCommon = new AndroidCommon(javaCommon);
-
AndroidConfiguration androidConfig = AndroidCommon.getAndroidConfig(ruleContext);
// "Resources" here include actual resources (xmls, drawables, etc), assets, and the manifest.
@@ -205,9 +198,7 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory {
ruleContext.getImplicitOutputArtifact(
AndroidRuleClasses.ANDROID_PROCESSED_MANIFEST),
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_ZIP),
- DataBinding.isEnabled(ruleContext)
- ? DataBinding.getLayoutInfoFile(ruleContext)
- : null);
+ DataBinding.contextFrom(ruleContext));
}
if (ruleContext.hasErrors()) {
return null;
@@ -223,6 +214,14 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory {
StampedAndroidManifest.createEmpty(ruleContext, /* exported = */ false));
}
+ // JavaCommon and AndroidCommon contain shared helper classes between java_* and android_*
+ // rules respectively.
+ JavaCommon javaCommon =
+ AndroidCommon.createJavaCommonWithAndroidDataBinding(
+ ruleContext, javaSemantics, resourceApk.asDataBindingContext(), /* isLibrary */ true);
+ javaSemantics.checkRule(ruleContext, javaCommon);
+ AndroidCommon androidCommon = new AndroidCommon(javaCommon);
+
// As android_library makes use of the Java rule compilation pipeline, we collect all
// Java-related information here to be passed into the JavaSourceInfoProvider later.
JavaTargetAttributes javaTargetAttributes =
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java
index 6d02827921..55fe52f37a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java
@@ -122,6 +122,7 @@ public abstract class AndroidLocalTestBase implements RuleConfiguredTargetFactor
applicationManifest.packBinaryWithDataAndResources(
ruleContext,
dataContext,
+ DataBinding.contextFrom(ruleContext),
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_APK),
resourceDependencies,
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_R_TXT),
@@ -133,9 +134,6 @@ public abstract class AndroidLocalTestBase implements RuleConfiguredTargetFactor
/* conditionalKeepRules= */ false,
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_PROCESSED_MANIFEST),
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_ZIP),
- DataBinding.isEnabled(ruleContext)
- ? DataBinding.getLayoutInfoFile(ruleContext)
- : null,
null, /* featureOfArtifact */
null /* featureAfterArtifact */);
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java
index e1567f0209..d1a5e9f257 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java
@@ -233,16 +233,17 @@ public class AndroidResourcesProcessorBuilder {
public ResourceApk buildWithoutLocalResources(
AndroidDataContext dataContext,
StampedAndroidManifest manifest,
- DataBindingContext androidDataContext) {
+ DataBindingContext dataBindingContext) {
build(
- dataContext, AndroidResources.empty(), AndroidAssets.empty(), manifest, androidDataContext);
+ dataContext, AndroidResources.empty(), AndroidAssets.empty(), manifest, dataBindingContext);
return ResourceApk.fromTransitiveResources(
resourceDependencies,
assetDependencies,
manifest.withProcessedManifest(manifestOut == null ? manifest.getManifest() : manifestOut),
- rTxtOut);
+ rTxtOut,
+ dataBindingContext);
}
public ResourceContainer build(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java
index 565fd50a89..8d48497115 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java
@@ -579,7 +579,6 @@ public abstract class AndroidSkylarkData
settings.resourceFilterFactory,
settings.noCompressExtensions,
crunchPng,
- dataBindingEnabled,
/* featureOf = */ null,
/* featureAfter = */ null,
DataBinding.contextFrom(dataBindingEnabled, ctx.getActionConstructionContext()))
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java b/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java
index c9e3daea8c..94e99ac53d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java
@@ -34,9 +34,9 @@ import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.
import com.google.devtools.build.lib.packages.RuleErrorConsumer;
import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion;
import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidManifestMerger;
+import com.google.devtools.build.lib.rules.android.DataBinding.DataBindingContext;
import com.google.devtools.build.lib.rules.android.ResourceContainer.Builder.JavaPackageSource;
import com.google.devtools.build.lib.syntax.Type;
-import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -371,6 +371,7 @@ public final class ApplicationManifest {
public ResourceApk packTestWithDataAndResources(
RuleContext ruleContext,
AndroidDataContext dataContext,
+ DataBindingContext dataBindingContext,
Artifact resourceApk,
ResourceDependencies resourceDeps,
@Nullable Artifact rTxt,
@@ -430,7 +431,8 @@ public final class ApplicationManifest {
AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR))
.build(dataContext, processed);
- return ResourceApk.of(finalContainer, resourceDeps, proguardCfg, mainDexProguardCfg);
+ return ResourceApk.of(
+ finalContainer, resourceDeps, proguardCfg, mainDexProguardCfg, dataBindingContext);
}
/** Packages up the manifest with resource and assets from the LocalResourceContainer. */
@@ -494,7 +496,7 @@ public final class ApplicationManifest {
.setStaticLibraryOut(merged.getStaticLibrary())
.build(dataContext, merged);
- return ResourceApk.of(processed, resourceDeps);
+ return ResourceApk.of(processed, resourceDeps, DataBinding.contextFrom(ruleContext));
}
/* Creates an incremental apk from assets and data. */
@@ -552,7 +554,8 @@ public final class ApplicationManifest {
// Intentionally skip building an R class JAR - incremental binaries handle this separately.
- return ResourceApk.of(processed, resourceDeps, proguardCfg, null);
+ return ResourceApk.of(
+ processed, resourceDeps, proguardCfg, null, DataBinding.contextFrom(ruleContext));
}
/** Packages up the manifest with resource and assets from the rule and dependent resources. */
@@ -560,6 +563,7 @@ public final class ApplicationManifest {
public ResourceApk packBinaryWithDataAndResources(
RuleContext ruleContext,
AndroidDataContext dataContext,
+ DataBindingContext dataBindingContext,
Artifact resourceApk,
ResourceDependencies resourceDeps,
@Nullable Artifact rTxt,
@@ -571,7 +575,6 @@ public final class ApplicationManifest {
boolean conditionalKeepRules,
Artifact manifestOut,
Artifact mergedResources,
- @Nullable Artifact dataBindingInfoZip,
@Nullable Artifact featureOf,
@Nullable Artifact featureAfter)
throws InterruptedException, RuleErrorException {
@@ -604,7 +607,7 @@ public final class ApplicationManifest {
"resource cycle shrinking can only be enabled for builds with aapt2");
}
- ResourceContainer processed =
+ final AndroidResourcesProcessorBuilder androidResourcesProcessorBuilder =
new AndroidResourcesProcessorBuilder()
.setLibrary(false)
.setApkOut(resourceContainer.getApk())
@@ -618,8 +621,10 @@ public final class ApplicationManifest {
.withResourceDependencies(resourceDeps)
.setProguardOut(proguardCfg)
.setMainDexProguardOut(mainDexProguardCfg)
- .conditionalKeepRules(conditionalKeepRules)
- .setDataBindingInfoZip(dataBindingInfoZip)
+ .conditionalKeepRules(conditionalKeepRules);
+ dataBindingContext.supplyLayoutInfo(androidResourcesProcessorBuilder::setDataBindingInfoZip);
+ ResourceContainer processed =
+ androidResourcesProcessorBuilder
.setApplicationId(manifestValues.get("applicationId"))
.setVersionCode(manifestValues.get("versionCode"))
.setVersionName(manifestValues.get("versionName"))
@@ -642,7 +647,8 @@ public final class ApplicationManifest {
AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR))
.build(dataContext, processed);
- return ResourceApk.of(finalContainer, resourceDeps, proguardCfg, mainDexProguardCfg);
+ return ResourceApk.of(
+ finalContainer, resourceDeps, proguardCfg, mainDexProguardCfg, dataBindingContext);
}
public ResourceApk packLibraryWithDataAndResources(
@@ -653,7 +659,7 @@ public final class ApplicationManifest {
Artifact symbols,
Artifact manifestOut,
Artifact mergedResources,
- @Nullable Artifact dataBindingInfoZip)
+ DataBindingContext dataBindingContext)
throws InterruptedException, RuleErrorException {
AndroidResources resources = AndroidResources.from(ruleContext, "resource_files");
AndroidAssets assets = AndroidAssets.from(ruleContext);
@@ -683,7 +689,7 @@ public final class ApplicationManifest {
AndroidRuleClasses.ANDROID_RESOURCES_AAPT2_LIBRARY_APK));
}
- ResourceContainer resourceContainer = builder.build();
+ final ResourceContainer resourceContainer = builder.build();
Artifact rJavaClassJar =
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR);
@@ -701,33 +707,31 @@ public final class ApplicationManifest {
.setOutput(resourceContainer.getSymbols())
.setCompiledSymbolsOutput(resourceContainer.getCompiledSymbols());
- if (dataBindingInfoZip != null && resourceContainer.getCompiledSymbols() != null) {
- PathFragment unusedInfo = dataBindingInfoZip.getRootRelativePath();
+ if (resourceContainer.getCompiledSymbols() != null) {
// TODO(corysmith): Centralize the data binding processing and zipping into a single
// action. Data binding processing needs to be triggered here as well as the merger to
// avoid aapt2 from throwing an error during compilation.
- parsingBuilder
- .setDataBindingInfoZip(
- ruleContext.getDerivedArtifact(
- unusedInfo.replaceName(unusedInfo.getBaseName() + "_unused.zip"),
- dataBindingInfoZip.getRoot()))
- .setManifest(resourceContainer.getManifest())
- .setJavaPackage(resourceContainer.getJavaPackage());
+ dataBindingContext.supplyLayoutInfo(
+ layoutInfo ->
+ parsingBuilder
+ .setDataBindingInfoZip(
+ ruleContext.getUniqueDirectoryArtifact("dummydatabinding", "unused.zip"))
+ .setManifest(resourceContainer.getManifest())
+ .setJavaPackage(resourceContainer.getJavaPackage()));
}
- resourceContainer = parsingBuilder.buildAndUpdate(dataContext, resourceContainer);
+ ResourceContainer parsedResourceContainer =
+ parsingBuilder.buildAndUpdate(dataContext, resourceContainer);
ResourceContainer merged =
new AndroidResourceMergingActionBuilder()
- .setJavaPackage(resourceContainer.getJavaPackage())
+ .setJavaPackage(parsedResourceContainer.getJavaPackage())
.withDependencies(resourceDeps)
.setThrowOnResourceConflict(androidConfiguration.throwOnResourceConflict())
.setUseCompiledMerge(skipParsingAction)
- .setDataBindingInfoZip(dataBindingInfoZip)
.setMergedResourcesOut(mergedResources)
.setManifestOut(manifestOut)
.setClassJarOut(rJavaClassJar)
- .setDataBindingInfoZip(dataBindingInfoZip)
- .build(dataContext, resourceContainer);
+ .build(dataContext, parsedResourceContainer);
ResourceContainer processed =
new AndroidResourceValidatorActionBuilder()
@@ -736,16 +740,16 @@ public final class ApplicationManifest {
.setMergedResources(mergedResources)
.setRTxtOut(merged.getRTxt())
.setSourceJarOut(merged.getJavaSourceJar())
- .setApkOut(resourceContainer.getApk())
- // aapt2 related artifacts. Will be generated if the targetAaptVersion is AAPT2.
+ .setApkOut(parsedResourceContainer.getApk())
.withDependencies(resourceDeps)
+ // aapt2 related artifacts. Will be generated if the targetAaptVersion is AAPT2.
.setCompiledSymbols(merged.getCompiledSymbols())
.setAapt2RTxtOut(merged.getAapt2RTxt())
.setAapt2SourceJarOut(merged.getAapt2JavaSourceJar())
.setStaticLibraryOut(merged.getStaticLibrary())
.build(dataContext, merged);
- return ResourceApk.of(processed, resourceDeps);
+ return ResourceApk.of(processed, resourceDeps, dataBindingContext);
}
public Artifact getManifest() {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/DataBinding.java b/src/main/java/com/google/devtools/build/lib/rules/android/DataBinding.java
index 9f295ba832..cb99971ea5 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/DataBinding.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/DataBinding.java
@@ -33,6 +33,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
@@ -67,7 +68,52 @@ public final class DataBinding {
/** Contains Android Databinding configuration and resource generation information. */
public interface DataBindingContext {
+
+ /**
+ * Returns the file where data binding's resource processing produces binding xml. For example,
+ * given:
+ *
+ * <pre>{@code
+ * <layout>
+ * <data>
+ * <variable name="foo" type="String" />
+ * </data>
+ * </layout>
+ * <LinearLayout>
+ * ...
+ * </LinearLayout>
+ * }</pre>
+ *
+ * <p>data binding strips out and processes this part:
+ *
+ * <pre>{@code
+ * <data>
+ * <variable name="foo" type="String" />
+ * </data>
+ * }</pre>
+ *
+ * for each layout file with data binding expressions. Since this may produce multiple files,
+ * outputs are zipped up into a single container.
+ */
void supplyLayoutInfo(Consumer<Artifact> consumer);
+
+ /** The javac flags that are needed to configure data binding's annotation processor. */
+ void supplyJavaCoptsUsing(
+ RuleContext ruleContext, boolean isBinary, Consumer<Iterable<String>> consumer);
+
+ /**
+ * Adds data binding's annotation processor as a plugin to the given Java compilation context.
+ *
+ * <p>This, in conjunction with {@link #createAnnotationFile} extends the Java compilation to
+ * translate data binding .xml into corresponding classes.
+ */
+ void supplyAnnotationProcessor(
+ RuleContext ruleContext, BiConsumer<JavaPluginInfoProvider, Iterable<Artifact>> consumer);
+
+ ImmutableList<Artifact> processDeps(RuleContext ruleContext);
+
+ ImmutableList<Artifact> addAnnotationFileToSrcs(
+ ImmutableList<Artifact> srcs, RuleContext ruleContext);
}
private static final class EnabledDataBindingContext implements DataBindingContext {
@@ -84,6 +130,38 @@ public final class DataBinding {
}
@Override
+ public void supplyJavaCoptsUsing(
+ RuleContext ruleContext, boolean isBinary, Consumer<Iterable<String>> consumer) {
+ consumer.accept(getJavacOpts(ruleContext, isBinary));
+ }
+
+ @Override
+ public void supplyAnnotationProcessor(
+ RuleContext ruleContext, BiConsumer<JavaPluginInfoProvider, Iterable<Artifact>> consumer) {
+ consumer.accept(
+ JavaInfo.getProvider(
+ JavaPluginInfoProvider.class,
+ ruleContext.getPrerequisite(
+ DATABINDING_ANNOTATION_PROCESSOR_ATTR, RuleConfiguredTarget.Mode.HOST)),
+ getMetadataOutputs(ruleContext));
+ }
+
+ @Override
+ public ImmutableList<Artifact> processDeps(RuleContext ruleContext) {
+ return DataBinding.processDeps(ruleContext);
+ }
+
+ @Override
+ public ImmutableList<Artifact> addAnnotationFileToSrcs(
+ ImmutableList<Artifact> srcs, RuleContext ruleContext) {
+ final Artifact annotationFile = createAnnotationFile(ruleContext);
+ if (annotationFile != null) {
+ return ImmutableList.<Artifact>builder().addAll(srcs).add(annotationFile).build();
+ }
+ return ImmutableList.of();
+ }
+
+ @Override
public boolean equals(Object o) {
if (this == o) {
return true;
@@ -102,11 +180,29 @@ public final class DataBinding {
}
private static final class DisabledDataBindingContext implements DataBindingContext {
-
@Override
public void supplyLayoutInfo(Consumer<Artifact> consumer) {
// pass
}
+
+ @Override
+ public void supplyJavaCoptsUsing(
+ RuleContext ruleContext, boolean isBinary, Consumer<Iterable<String>> consumer) {}
+
+ @Override
+ public void supplyAnnotationProcessor(
+ RuleContext ruleContext, BiConsumer<JavaPluginInfoProvider, Iterable<Artifact>> consumer) {}
+
+ @Override
+ public ImmutableList<Artifact> processDeps(RuleContext ruleContext) {
+ return ImmutableList.of();
+ }
+
+ @Override
+ public ImmutableList<Artifact> addAnnotationFileToSrcs(
+ ImmutableList<Artifact> srcs, RuleContext ruleContext) {
+ return srcs;
+ }
}
/** Supplies a databinding context from a rulecontext. */
@@ -117,7 +213,7 @@ public final class DataBinding {
return asDisabledDataBindingContext();
}
- /** Supplies a databinding context from a rulecontext. */
+ /** Supplies a databinding context from an action context. */
public static DataBindingContext contextFrom(boolean enabled, ActionConstructionContext context) {
if (enabled) {
return asEnabledDataBindingContextFrom(context);
@@ -131,7 +227,7 @@ public final class DataBinding {
return new EnabledDataBindingContext(actionContext);
}
- /** Supplies a disabled (no-op) DataBindingContext from the action context. */
+ /** Supplies a disabled (no-op) DataBindingContext. */
public static DataBindingContext asDisabledDataBindingContext() {
return new DisabledDataBindingContext();
}
@@ -370,7 +466,7 @@ public final class DataBinding {
* @return the deps' metadata outputs. These need to be staged as compilation inputs to the
* current rule.
*/
- static ImmutableList<Artifact> processDeps(RuleContext ruleContext) {
+ private static ImmutableList<Artifact> processDeps(RuleContext ruleContext) {
ImmutableList.Builder<Artifact> dataBindingJavaInputs = ImmutableList.<Artifact>builder();
if (AndroidResources.definesAndroidResources(ruleContext.attributes())) {
dataBindingJavaInputs.add(DataBinding.getLayoutInfoFile(ruleContext));
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ProcessedAndroidData.java b/src/main/java/com/google/devtools/build/lib/rules/android/ProcessedAndroidData.java
index f69128afd1..d0bd385c0f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ProcessedAndroidData.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ProcessedAndroidData.java
@@ -67,7 +67,6 @@ public class ProcessedAndroidData {
ResourceFilterFactory resourceFilterFactory,
List<String> noCompressExtensions,
boolean crunchPng,
- boolean dataBindingEnabled,
@Nullable Artifact featureOf,
@Nullable Artifact featureAfter,
DataBindingContext dataBindingContext)
@@ -90,12 +89,9 @@ public class ProcessedAndroidData {
AndroidBinary.createMainDexProguardSpec(
dataContext.getLabel(), dataContext.getActionConstructionContext()))
.conditionalKeepRules(conditionalKeepRules)
- .setDataBindingInfoZip(
- dataBindingEnabled
- ? DataBinding.getLayoutInfoFile(dataContext.getActionConstructionContext())
- : null)
.setFeatureOf(featureOf)
.setFeatureAfter(featureAfter);
+ dataBindingContext.supplyLayoutInfo(builder::setDataBindingInfoZip);
return buildActionForBinary(
dataContext,
dataBindingContext,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java
index 2ab400cf93..acb9d1d40a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java
@@ -50,16 +50,21 @@ public final class ResourceApk {
private final Artifact rTxt;
@Nullable private final Artifact resourceProguardConfig;
@Nullable private final Artifact mainDexProguardConfig;
+ private final DataBindingContext dataBindingContext;
- static ResourceApk of(ResourceContainer resourceContainer, ResourceDependencies resourceDeps) {
- return of(resourceContainer, resourceDeps, null, null);
+ static ResourceApk of(
+ ResourceContainer resourceContainer,
+ ResourceDependencies resourceDeps,
+ DataBindingContext dataBindingContext) {
+ return of(resourceContainer, resourceDeps, null, null, dataBindingContext);
}
static ResourceApk of(
ResourceContainer resourceContainer,
ResourceDependencies resourceDeps,
@Nullable Artifact resourceProguardConfig,
- @Nullable Artifact mainDexProguardConfig) {
+ @Nullable Artifact mainDexProguardConfig,
+ DataBindingContext dataBindingContext) {
return new ResourceApk(
resourceContainer.getApk(),
resourceContainer.getJavaSourceJar(),
@@ -72,7 +77,8 @@ public final class ResourceApk {
resourceContainer.getProcessedManifest(),
resourceContainer.getRTxt(),
resourceProguardConfig,
- mainDexProguardConfig);
+ mainDexProguardConfig,
+ dataBindingContext);
}
public static ResourceApk of(
@@ -92,7 +98,8 @@ public final class ResourceApk {
resources.getProcessedManifest(),
resources.getRTxt(),
resourceProguardConfig,
- mainDexProguardConfig);
+ mainDexProguardConfig,
+ resources.asDataBindingContext());
}
private ResourceApk(
@@ -107,7 +114,8 @@ public final class ResourceApk {
ProcessedAndroidManifest manifest,
Artifact rTxt,
@Nullable Artifact resourceProguardConfig,
- @Nullable Artifact mainDexProguardConfig) {
+ @Nullable Artifact mainDexProguardConfig,
+ DataBindingContext dataBindingContext) {
this.resourceApk = resourceApk;
this.resourceJavaSrcJar = resourceJavaSrcJar;
this.resourceJavaClassJar = resourceJavaClassJar;
@@ -120,6 +128,7 @@ public final class ResourceApk {
this.rTxt = rTxt;
this.resourceProguardConfig = resourceProguardConfig;
this.mainDexProguardConfig = mainDexProguardConfig;
+ this.dataBindingContext = dataBindingContext;
}
ResourceApk withApk(Artifact apk) {
@@ -135,7 +144,8 @@ public final class ResourceApk {
manifest,
rTxt,
resourceProguardConfig,
- mainDexProguardConfig);
+ mainDexProguardConfig,
+ asDataBindingContext());
}
public Artifact getArtifact() {
@@ -179,7 +189,8 @@ public final class ResourceApk {
ResourceDependencies resourceDeps,
AssetDependencies assetDeps,
ProcessedAndroidManifest manifest,
- Artifact rTxt) {
+ Artifact rTxt,
+ DataBindingContext dataBindingContext) {
return new ResourceApk(
null,
null,
@@ -192,7 +203,8 @@ public final class ResourceApk {
manifest,
rTxt,
null,
- null);
+ null,
+ dataBindingContext);
}
public Artifact getResourceProguardConfig() {
@@ -211,6 +223,10 @@ public final class ResourceApk {
return assetDeps;
}
+ public DataBindingContext asDataBindingContext() {
+ return dataBindingContext;
+ }
+
/**
* Creates an provider from the resources in the ResourceApk.
*
@@ -266,7 +282,7 @@ public final class ResourceApk {
// targets
// so we can validate there are no asset merging conflicts.
builder.addOutputGroup(OutputGroupInfo.HIDDEN_TOP_LEVEL, assetsInfo.getValidationResult());
- }
+ }
if (manifestInfo.isPresent() && !isLibrary) {
builder.addNativeDeclaredProvider(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidResources.java b/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidResources.java
index c70239b8b3..172dcee898 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidResources.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidResources.java
@@ -194,12 +194,12 @@ public class ValidatedAndroidResources extends MergedAndroidResources
return new ValidatedAndroidResources(
new MergedAndroidResources(
new ParsedAndroidResources(
- // Null out databinding to avoid accidentally propagating ActionCreationContext
new AndroidResources(getResources(), getResourceRoots()),
getSymbols(),
getCompiledSymbols(),
getLabel(),
getStampedManifest(),
+ // Null out databinding to avoid accidentally propagating ActionCreationContext
null),
getMergedResources(),
getClassJar(),
diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidResourcesTest.java b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidResourcesTest.java
index f2169b5f4d..d1f9db8166 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidResourcesTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidResourcesTest.java
@@ -496,7 +496,6 @@ public class AndroidResourcesTest extends ResourceTestBase {
ResourceFilterFactory.empty(),
ImmutableList.of(),
false,
- false,
null,
null,
DataBinding.contextFrom(ruleContext))
@@ -549,6 +548,12 @@ public class AndroidResourcesTest extends ResourceTestBase {
private ParsedAndroidResources makeParsedResources(RuleContext ruleContext)
throws RuleErrorException, InterruptedException {
+ return makeParsedResources(ruleContext, DataBinding.asDisabledDataBindingContext());
+ }
+
+ private ParsedAndroidResources makeParsedResources(
+ RuleContext ruleContext, DataBindingContext dataBindingContext)
+ throws RuleErrorException, InterruptedException {
ImmutableList<Artifact> resources = getResources("values-en/foo.xml", "drawable-hdpi/bar.png");
return new AndroidResources(
resources, AndroidResources.getResourceRoots(ruleContext, resources, "resource_files"))
@@ -556,7 +561,7 @@ public class AndroidResourcesTest extends ResourceTestBase {
AndroidDataContext.forNative(ruleContext),
getManifest(),
AndroidAaptVersion.chooseTargetAaptVersion(ruleContext),
- DataBinding.contextFrom(ruleContext));
+ dataBindingContext);
}
private ProcessedAndroidManifest getManifest() {