aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules
diff options
context:
space:
mode:
authorGravatar corysmith <corysmith@google.com>2018-08-06 10:16:16 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-08-06 10:18:15 -0700
commit0a0273ad76d9a8ef3901c282a789ac8852e5ca4e (patch)
tree5614ec5f15baf9b3c1d675e0c66329fe8b14bf7e /src/main/java/com/google/devtools/build/lib/rules
parent5a91c0152f04c7ccd4bdd394f02eefc9c63b4b8f (diff)
Add AndroidResources processing to the DataBindingContext.
RELNOTES: None PiperOrigin-RevId: 207564798
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/DataBinding.java223
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidResources.java6
2 files changed, 87 insertions, 142 deletions
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 744a36cb77..d760a3501d 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
@@ -61,10 +61,9 @@ import java.util.function.Consumer;
*/
public final class DataBinding {
/** The rule attribute supplying data binding's annotation processor. */
- public static final String DATABINDING_ANNOTATION_PROCESSOR_ATTR =
- "$databinding_annotation_processor";
+ static final String DATABINDING_ANNOTATION_PROCESSOR_ATTR = "$databinding_annotation_processor";
- public static final String ENABLE_DATA_BINDING_ATTR = "enable_data_binding";
+ private static final String ENABLE_DATA_BINDING_ATTR = "enable_data_binding";
/** Contains Android Databinding configuration and resource generation information. */
public interface DataBindingContext {
@@ -95,11 +94,11 @@ public final class DataBinding {
* 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);
+ default 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);
+ default 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.
@@ -107,8 +106,8 @@ public final class DataBinding {
* <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);
+ default void supplyAnnotationProcessor(
+ RuleContext ruleContext, BiConsumer<JavaPluginInfoProvider, Iterable<Artifact>> consumer) {}
/**
* Processes deps that also apply data binding.
@@ -117,7 +116,9 @@ public final class DataBinding {
* @return the deps' metadata outputs. These need to be staged as compilation inputs to the
* current rule.
*/
- ImmutableList<Artifact> processDeps(RuleContext ruleContext);
+ default ImmutableList<Artifact> processDeps(RuleContext ruleContext) {
+ return ImmutableList.of();
+ }
/**
* Creates and adds the generated Java source for data binding annotation processor to read and
@@ -127,8 +128,10 @@ public final class DataBinding {
* <p>This triggers the annotation processor. Annotation processor settings are configured
* separately in {@link #supplyJavaCoptsUsing(RuleContext, boolean, Consumer)}.
*/
- ImmutableList<Artifact> addAnnotationFileToSrcs(
- ImmutableList<Artifact> srcs, RuleContext ruleContext);
+ default ImmutableList<Artifact> addAnnotationFileToSrcs(
+ ImmutableList<Artifact> srcs, RuleContext ruleContext) {
+ return srcs;
+ };
/**
* Adds the appropriate {@link UsesDataBindingProvider} for a rule if it should expose one.
@@ -136,7 +139,13 @@ public final class DataBinding {
* <p>A rule exposes {@link UsesDataBindingProvider} if either it or its deps set {@code
* enable_data_binding = 1}.
*/
- void addProvider(RuleConfiguredTargetBuilder builder, RuleContext ruleContext);
+ default void addProvider(RuleConfiguredTargetBuilder builder, RuleContext ruleContext) {
+ maybeAddProvider(new ArrayList<>(), builder, ruleContext);
+ }
+
+ default AndroidResources processResources(AndroidResources resources) {
+ return resources;
+ }
}
private static final class EnabledDataBindingContext implements DataBindingContext {
@@ -149,13 +158,51 @@ public final class DataBinding {
@Override
public void supplyLayoutInfo(Consumer<Artifact> consumer) {
- consumer.accept(getLayoutInfoFile(actionConstructionContext));
+ consumer.accept(layoutInfoFile());
+ }
+
+ Artifact layoutInfoFile() {
+ return actionConstructionContext.getUniqueDirectoryArtifact("databinding", "layout-info.zip");
}
@Override
public void supplyJavaCoptsUsing(
RuleContext ruleContext, boolean isBinary, Consumer<Iterable<String>> consumer) {
- consumer.accept(getJavacOpts(ruleContext, isBinary));
+ ImmutableList.Builder<String> flags = ImmutableList.builder();
+ String metadataOutputDir = getDataBindingExecPath(ruleContext).getPathString();
+
+ // Directory where the annotation processor looks for deps metadata output. The annotation
+ // processor automatically appends {@link DEP_METADATA_INPUT_DIR} to this path. Individual
+ // files can be anywhere under this directory, recursively.
+ flags.add(createProcessorFlag("bindingBuildFolder", metadataOutputDir));
+
+ // Directory where the annotation processor should write this rule's metadata output. The
+ // annotation processor automatically appends {@link METADATA_OUTPUT_DIR} to this path.
+ flags.add(createProcessorFlag("generationalFileOutDir", metadataOutputDir));
+
+ // Path to the Android SDK installation (if available).
+ flags.add(createProcessorFlag("sdkDir", "/not/used"));
+
+ // Whether the current rule is a library or binary.
+ flags.add(createProcessorFlag("artifactType", isBinary ? "APPLICATION" : "LIBRARY"));
+
+ // The path where data binding's resource processor wrote its output (the data binding XML
+ // expressions). The annotation processor reads this file to translate that XML into Java.
+ flags.add(createProcessorFlag("xmlOutDir", getDataBindingExecPath(ruleContext).toString()));
+
+ // Unused.
+ flags.add(createProcessorFlag("exportClassListTo", "/tmp/exported_classes"));
+
+ // The Java package for the current rule.
+ flags.add(createProcessorFlag("modulePackage", AndroidCommon.getJavaPackage(ruleContext)));
+
+ // The minimum Android SDK compatible with this rule.
+ flags.add(createProcessorFlag("minApi", "14")); // TODO(gregce): update this
+
+ // If enabled, produces cleaner output for Android Studio.
+ flags.add(createProcessorFlag("printEncodedErrors", "0"));
+
+ consumer.accept(flags.build());
}
@Override
@@ -171,7 +218,15 @@ public final class DataBinding {
@Override
public ImmutableList<Artifact> processDeps(RuleContext ruleContext) {
- return DataBinding.processDeps(ruleContext);
+ ImmutableList.Builder<Artifact> dataBindingJavaInputs = ImmutableList.builder();
+ if (AndroidResources.definesAndroidResources(ruleContext.attributes())) {
+ dataBindingJavaInputs.add(layoutInfoFile());
+ }
+ for (Artifact dataBindingDepMetadata : getTransitiveMetadata(ruleContext, "deps")) {
+ dataBindingJavaInputs.add(
+ symlinkDepsMetadataIntoOutputTree(ruleContext, dataBindingDepMetadata));
+ }
+ return dataBindingJavaInputs.build();
}
@Override
@@ -215,39 +270,15 @@ public final class DataBinding {
public int hashCode() {
return actionConstructionContext.hashCode();
}
- }
- 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;
- }
-
- @Override
- public void addProvider(RuleConfiguredTargetBuilder builder, RuleContext ruleContext) {
- maybeAddProvider(new ArrayList<>(), builder, ruleContext);
+ public AndroidResources processResources(AndroidResources resources) {
+ return resources;
}
}
+ private static final DataBindingContext DISABLED_CONTEXT = new DataBindingContext() {};
+
/** Supplies a databinding context from a rulecontext. */
public static DataBindingContext contextFrom(RuleContext ruleContext) {
if (isEnabled(ruleContext)) {
@@ -272,7 +303,7 @@ public final class DataBinding {
/** Supplies a disabled (no-op) DataBindingContext. */
public static DataBindingContext asDisabledDataBindingContext() {
- return new DisabledDataBindingContext();
+ return DISABLED_CONTEXT;
}
/**
@@ -280,7 +311,7 @@ public final class DataBinding {
* applied. The full file paths include prefixes as implemented in {@link #getMetadataOutputs}.
*/
private static final ImmutableList<String> METADATA_OUTPUT_SUFFIXES =
- ImmutableList.<String>of("setter_store.bin", "layoutinfo.bin", "br.bin");
+ ImmutableList.of("setter_store.bin", "layoutinfo.bin", "br.bin");
/** The directory where the annotation processor looks for dep metadata. */
private static final String DEP_METADATA_INPUT_DIR = "dependent-lib-artifacts";
@@ -295,9 +326,10 @@ public final class DataBinding {
* additional compile/runtime dependencies. But rules with data binding disabled will fail if data
* binding expressions appear in their layout resources.
*/
- public static boolean isEnabled(RuleContext ruleContext) {
+ private static boolean isEnabled(RuleContext ruleContext) {
return ruleContext.attributes().has(ENABLE_DATA_BINDING_ATTR, Type.BOOLEAN)
- && ruleContext.attributes().get(ENABLE_DATA_BINDING_ATTR, Type.BOOLEAN);
+ && Boolean.TRUE.equals(
+ ruleContext.attributes().get(ENABLE_DATA_BINDING_ATTR, Type.BOOLEAN));
}
/** Returns this rule's data binding base output dir (as an execroot-relative path). */
@@ -317,77 +349,6 @@ public final class DataBinding {
binRelativeBasePath.getRelative(relativePath), ruleContext.getBinOrGenfilesDirectory());
}
- /**
- * 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.
- */
- static Artifact getLayoutInfoFile(ActionConstructionContext context) {
- return getSuffixedInfoFile(context, "");
- }
-
- /** Gets a layout info file with the specified suffix (for use in having different outputs) */
- static Artifact getSuffixedInfoFile(ActionConstructionContext context, String suffix) {
- return context.getUniqueDirectoryArtifact("databinding", "layout-info" + suffix + ".zip");
- }
-
- /** The javac flags that are needed to configure data binding's annotation processor. */
- static ImmutableList<String> getJavacOpts(RuleContext ruleContext, boolean isBinary) {
- ImmutableList.Builder<String> flags = ImmutableList.builder();
- String metadataOutputDir = getDataBindingExecPath(ruleContext).getPathString();
-
- // Directory where the annotation processor looks for deps metadata output. The annotation
- // processor automatically appends {@link DEP_METADATA_INPUT_DIR} to this path. Individual
- // files can be anywhere under this directory, recursively.
- flags.add(createProcessorFlag("bindingBuildFolder", metadataOutputDir));
- // Directory where the annotation processor should write this rule's metadata output. The
- // annotation processor automatically appends {@link METADATA_OUTPUT_DIR} to this path.
- flags.add(createProcessorFlag("generationalFileOutDir", metadataOutputDir));
- // Path to the Android SDK installation (if available).
- flags.add(createProcessorFlag("sdkDir", "/not/used"));
- // Whether the current rule is a library or binary.
- flags.add(createProcessorFlag("artifactType", isBinary ? "APPLICATION" : "LIBRARY"));
- // The path where data binding's resource processor wrote its output (the data binding XML
- // expressions). The annotation processor reads this file to translate that XML into Java.
- flags.add(createProcessorFlag("xmlOutDir", getDataBindingExecPath(ruleContext).toString()));
- // Unused.
- flags.add(createProcessorFlag("exportClassListTo", "/tmp/exported_classes"));
- // The Java package for the current rule.
- flags.add(createProcessorFlag("modulePackage", AndroidCommon.getJavaPackage(ruleContext)));
- // The minimum Android SDK compatible with this rule.
- flags.add(createProcessorFlag("minApi", "14")); // TODO(gregce): update this
- // If enabled, the annotation processor reports detailed output about its activities.
- // addProcessorFlag(attributes, "enableDebugLogs", "1");
- // If enabled, produces cleaner output for Android Studio.
- flags.add(createProcessorFlag("printEncodedErrors", "0"));
- // Specifies whether the current rule is a test. Currently unused.
- // addDataBindingProcessorFlag(attributes, "isTestVariant", "false");
- // Specifies that data binding is only used for test instrumentation. Currently unused.
- // addDataBindingProcessorFlag(attributes, "enableForTests", null);
- return flags.build();
- }
-
/** Turns a key/value pair into a javac annotation processor flag received by data binding. */
private static String createProcessorFlag(String flag, String value) {
return String.format("-Aandroid.databinding.%s=%s", flag, value);
@@ -395,13 +356,12 @@ public final class DataBinding {
/**
* Creates and returns the generated Java source that data binding's annotation processor reads to
- * translate layout info xml (from {@link #getLayoutInfoFile} into the classes that end user code
- * consumes.
+ * translate layout info xml into the classes that end user code consumes.
*
* <p>This mostly just triggers the annotation processor. Annotation processor settings are
* configured separately.
*/
- static Artifact createAnnotationFile(RuleContext ruleContext) {
+ private static Artifact createAnnotationFile(RuleContext ruleContext) {
String contents;
try {
contents =
@@ -466,7 +426,7 @@ public final class DataBinding {
if (!AndroidResources.definesAndroidResources(ruleContext.attributes())) {
// If this rule doesn't define local resources, no resource processing was done, so it
// doesn't produce data binding output.
- return ImmutableList.<Artifact>of();
+ return ImmutableList.of();
}
ImmutableList.Builder<Artifact> outputs = ImmutableList.<Artifact>builder();
String javaPackage = AndroidCommon.getJavaPackage(ruleContext);
@@ -482,25 +442,6 @@ public final class DataBinding {
}
/**
- * Processes deps that also apply data binding.
- *
- * @param ruleContext the current rule
- * @return the deps' metadata outputs. These need to be staged as compilation inputs to the
- * current rule.
- */
- private static ImmutableList<Artifact> processDeps(RuleContext ruleContext) {
- ImmutableList.Builder<Artifact> dataBindingJavaInputs = ImmutableList.<Artifact>builder();
- if (AndroidResources.definesAndroidResources(ruleContext.attributes())) {
- dataBindingJavaInputs.add(DataBinding.getLayoutInfoFile(ruleContext));
- }
- for (Artifact dataBindingDepMetadata : getTransitiveMetadata(ruleContext, "deps")) {
- dataBindingJavaInputs.add(
- symlinkDepsMetadataIntoOutputTree(ruleContext, dataBindingDepMetadata));
- }
- return dataBindingJavaInputs.build();
- }
-
- /**
* Data binding's annotation processor reads the transitive metadata outputs of the target's deps
* (see {@link #getMetadataOutputs(RuleContext)}) in the directory specified by the processor flag
* {@code -Aandroid.databinding.bindingBuildFolder}. Since dependencies don't generate their
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidResources.java b/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidResources.java
index 240dce0b11..bfb293577d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidResources.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidResources.java
@@ -63,7 +63,11 @@ public class ParsedAndroidResources extends AndroidResources
isAapt2
? dataContext.createOutputArtifact(AndroidRuleClasses.ANDROID_COMPILED_SYMBOLS)
: null)
- .build(dataContext, resources, manifest, dataBindingContext);
+ .build(
+ dataContext,
+ dataBindingContext.processResources(resources),
+ manifest,
+ dataBindingContext);
}
@VisibleForTesting