diff options
author | lberki <lberki@google.com> | 2018-07-12 01:14:46 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-07-12 01:16:14 -0700 |
commit | ce8f52060e2cf1e5a49a522039f0cba2a340f7e3 (patch) | |
tree | 7f76f467b308f06a80fc81a1467f41f39a48fec1 | |
parent | f814454ff5477418ca44696efb5c71339368efa4 (diff) |
Automated rollback of commit f4a3dd9b8124dc7b2795f89e6700881b66371e4f.
*** Reason for rollback ***
Breaks //devtools/blaze/integration:{[]_test_test,gdp_validation_test} and at leats //contentads/supermixer/server:supermixer .
*** Original change description ***
Refactor handling of API generation in JavaPluginInfoProvider
Instead of keeping two copies of state for the API-generating and
non-API-generating cases, create a 'JavaPluginInfo' abstraction to contain all
state for each case, and then keep two copies in the top-level
JavaPluginInfoProvider provider.
This will make it easier and less error-prone to add additional state to the
provider.
PiperOrigin-RevId: 204258844
12 files changed, 274 insertions, 153 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 6adbb0cf00..c589342614 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 @@ -156,7 +156,16 @@ public final class DataBinding { ruleContext.getPrerequisite( DATABINDING_ANNOTATION_PROCESSOR_ATTR, RuleConfiguredTarget.Mode.HOST)); - attributes.addPlugin(plugin); + for (String name : plugin.getProcessorClasses()) { + // For header compilation (see JavaHeaderCompileAction): + attributes.addApiGeneratingProcessorName(name); + // For full compilation: + attributes.addProcessorName(name); + } + // For header compilation (see JavaHeaderCompileAction): + attributes.addApiGeneratingProcessorPath(plugin.getProcessorClasspath()); + // For full compilation: + attributes.addProcessorPath(plugin.getProcessorClasspath()); attributes.addAdditionalOutputs(getMetadataOutputs(ruleContext)); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java index c68bd76547..e88782951d 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java @@ -50,7 +50,6 @@ import com.google.devtools.build.lib.packages.Target; import com.google.devtools.build.lib.packages.TargetUtils; import com.google.devtools.build.lib.rules.cpp.LinkerInput; import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider.ClasspathType; -import com.google.devtools.build.lib.rules.java.JavaPluginInfoProvider.JavaPluginInfo; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.FileTypeSet; import com.google.devtools.build.lib.util.Pair; @@ -103,7 +102,7 @@ public class JavaCommon { targetsTreatedAsDeps; private final ImmutableList<Artifact> sources; - private JavaPluginInfoProvider activePlugins = JavaPluginInfoProvider.empty(); + private ImmutableList<JavaPluginInfoProvider> activePlugins = ImmutableList.of(); private final RuleContext ruleContext; private final JavaSemantics semantics; @@ -763,21 +762,33 @@ public class JavaCommon { * Adds information about the annotation processors that should be run for this java target * retrieved from the given plugins to the target attributes. * - * <p>In particular, the processor names/paths and the API generating processor names/paths are - * added to the given attributes. Plugins having repetitive names/paths will be added only once. + * In particular, the processor names/paths and the API generating processor names/paths are added + * to the given attributes. Plugins having repetitive names/paths will be added only once. */ public static void addPlugins( - JavaTargetAttributes.Builder attributes, JavaPluginInfoProvider activePlugins) { - attributes.addPlugin(activePlugins); + JavaTargetAttributes.Builder attributes, Iterable<JavaPluginInfoProvider> activePlugins) { + for (JavaPluginInfoProvider plugin : activePlugins) { + for (String name : plugin.getProcessorClasses()) { + attributes.addProcessorName(name); + } + // Now get the plugin-libraries runtime classpath. + attributes.addProcessorPath(plugin.getProcessorClasspath()); + + // Add api-generating plugins + for (String name : plugin.getApiGeneratingProcessorClasses()) { + attributes.addApiGeneratingProcessorName(name); + } + attributes.addApiGeneratingProcessorPath(plugin.getApiGeneratingProcessorClasspath()); + } } - private JavaPluginInfoProvider collectPlugins() { + private ImmutableList<JavaPluginInfoProvider> collectPlugins() { List<JavaPluginInfoProvider> result = new ArrayList<>(); Iterables.addAll(result, getPluginInfoProvidersForAttribute(ruleContext, ":java_plugins", Mode.HOST)); Iterables.addAll(result, getPluginInfoProvidersForAttribute(ruleContext, "plugins", Mode.HOST)); Iterables.addAll(result, getPluginInfoProvidersForAttribute(ruleContext, "deps", Mode.TARGET)); - return JavaPluginInfoProvider.merge(result); + return ImmutableList.copyOf(result); } private static Iterable<JavaPluginInfoProvider> getPluginInfoProvidersForAttribute( @@ -790,12 +801,23 @@ public class JavaCommon { } JavaPluginInfoProvider getJavaPluginInfoProvider(RuleContext ruleContext) { - NestedSet<String> processorClasses = - NestedSetBuilder.wrap(Order.NAIVE_LINK_ORDER, getProcessorClasses(ruleContext)); + ImmutableSet<String> processorClasses = getProcessorClasses(ruleContext); NestedSet<Artifact> processorClasspath = getRuntimeClasspath(); - return JavaPluginInfoProvider.create( - JavaPluginInfo.create(processorClasses, processorClasspath), - ruleContext.attributes().get("generates_api", Type.BOOLEAN)); + ImmutableSet<String> apiGeneratingProcessorClasses; + NestedSet<Artifact> apiGeneratingProcessorClasspath; + if (ruleContext.attributes().get("generates_api", Type.BOOLEAN)) { + apiGeneratingProcessorClasses = processorClasses; + apiGeneratingProcessorClasspath = processorClasspath; + } else { + apiGeneratingProcessorClasses = ImmutableSet.of(); + apiGeneratingProcessorClasspath = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER); + } + + return new JavaPluginInfoProvider( + processorClasses, + processorClasspath, + apiGeneratingProcessorClasses, + apiGeneratingProcessorClasspath); } /** diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java index 8047ba4bbe..388c55efb4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java @@ -229,7 +229,8 @@ public final class JavaCompilationHelper { builder.setSourceGenDirectory(sourceGenDir(classJar)); builder.setTempDirectory(tempDir(classJar)); builder.setClassDirectory(classDir(classJar)); - builder.setPlugins(attributes.plugins().plugins()); + builder.setProcessorPaths(attributes.getProcessorPath()); + builder.addProcessorNames(attributes.getProcessorNames()); builder.setStrictJavaDeps(attributes.getStrictJavaDeps()); builder.setFixDepsTool(getJavaConfiguration().getFixDepsTool()); builder.setDirectJars(attributes.getDirectJars()); @@ -404,7 +405,8 @@ public final class JavaCompilationHelper { ImmutableList.copyOf(Iterables.concat(getBootclasspathOrDefault(), getExtdirInputs()))); // only run API-generating annotation processors during header compilation - builder.setPlugins(attributes.plugins().apiGeneratingPlugins()); + builder.setProcessorPaths(attributes.getApiGeneratingProcessorPath()); + builder.addProcessorNames(attributes.getApiGeneratingProcessorNames()); builder.setJavacOpts(getJavacOpts()); builder.setTempDirectory(tempDir(headerJar)); builder.setOutputJar(headerJar); @@ -457,7 +459,7 @@ public final class JavaCompilationHelper { */ public boolean usesAnnotationProcessing() { JavaTargetAttributes attributes = getAttributes(); - return getJavacOpts().contains("-processor") || !attributes.plugins().isEmpty(); + return getJavacOpts().contains("-processor") || !attributes.getProcessorNames().isEmpty(); } /** diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java index dc960d7b0d..cdca40369d 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java @@ -15,7 +15,6 @@ package com.google.devtools.build.lib.rules.java; import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; import static java.nio.charset.StandardCharsets.ISO_8859_1; import com.google.common.annotations.VisibleForTesting; @@ -57,7 +56,6 @@ import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible; import com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaClasspathMode; -import com.google.devtools.build.lib.rules.java.JavaPluginInfoProvider.JavaPluginInfo; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization; import com.google.devtools.build.lib.util.LazyString; @@ -117,8 +115,10 @@ public final class JavaCompileAction extends SpawnAction { /** The list of classpath entries to search for annotation processors. */ private final NestedSet<Artifact> processorPath; - /** The list of annotation processor classes to run. */ - private final NestedSet<String> processorNames; + /** + * The list of annotation processor classes to run. + */ + private final ImmutableList<String> processorNames; /** Set of additional Java source files to compile. */ private final ImmutableList<Artifact> sourceJars; @@ -189,7 +189,7 @@ public final class JavaCompileAction extends SpawnAction { ImmutableList<Artifact> sourcePathEntries, ImmutableList<Artifact> extdirInputs, NestedSet<Artifact> processorPath, - NestedSet<String> processorNames, + List<String> processorNames, Collection<Artifact> sourceJars, ImmutableSet<Artifact> sourceFiles, List<String> javacOpts, @@ -226,7 +226,7 @@ public final class JavaCompileAction extends SpawnAction { this.sourcePathEntries = ImmutableList.copyOf(sourcePathEntries); this.extdirInputs = extdirInputs; this.processorPath = processorPath; - this.processorNames = processorNames; + this.processorNames = ImmutableList.copyOf(processorNames); this.sourceJars = ImmutableList.copyOf(sourceJars); this.sourceFiles = sourceFiles; this.javacOpts = ImmutableList.copyOf(javacOpts); @@ -318,7 +318,7 @@ public final class JavaCompileAction extends SpawnAction { */ @VisibleForTesting public List<String> getProcessorNames() { - return processorNames.toList(); + return processorNames; } /** @@ -456,7 +456,8 @@ public final class JavaCompileAction extends SpawnAction { private PathFragment sourceGenDirectory; private PathFragment tempDirectory; private PathFragment classDirectory; - private JavaPluginInfo plugins = JavaPluginInfo.empty(); + private NestedSet<Artifact> processorPath = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER); + private final List<String> processorNames = new ArrayList<>(); private Label targetLabel; @Nullable private String injectingRuleKind; @@ -571,7 +572,7 @@ public final class JavaCompileAction extends SpawnAction { NestedSetBuilder.<Artifact>stableOrder() .addTransitive(classpathEntries) .addTransitive(compileTimeDependencyArtifacts) - .addTransitive(plugins.processorClasspath()) + .addTransitive(processorPath) .addAll(sourceJars) .addAll(sourceFiles) .addAll(javabaseInputs) @@ -632,8 +633,8 @@ public final class JavaCompileAction extends SpawnAction { bootclasspathEntries, sourcePathEntries, extdirInputs, - plugins.processorClasspath(), - plugins.processorClasses(), + processorPath, + processorNames, sourceJars, sourceFiles, internedJcopts, @@ -684,8 +685,12 @@ public final class JavaCompileAction extends SpawnAction { if (!sourcePathEntries.isEmpty()) { result.addExecPaths("--sourcepath", sourcePathEntries); } - result.addExecPaths("--processorpath", plugins.processorClasspath()); - result.addAll("--processors", plugins.processorClasses()); + if (!processorPath.isEmpty()) { + result.addExecPaths("--processorpath", processorPath); + } + if (!processorNames.isEmpty()) { + result.addAll("--processors", ImmutableList.copyOf(processorNames)); + } if (!sourceJars.isEmpty()) { result.addExecPaths("--source_jars", ImmutableList.copyOf(sourceJars)); } @@ -771,12 +776,12 @@ public final class JavaCompileAction extends SpawnAction { } private String getProcessorNames() { - if (plugins.processorClasses().isEmpty()) { + if (processorNames.isEmpty()) { return ""; } StringBuilder sb = new StringBuilder(); List<String> shortNames = new ArrayList<>(); - for (String name : plugins.processorClasses()) { + for (String name : processorNames) { // Annotation processor names are qualified class names. Omit the package part for the // progress message, e.g. `com.google.Foo` -> `Foo`. int idx = name.lastIndexOf('.'); @@ -948,10 +953,13 @@ public final class JavaCompileAction extends SpawnAction { return this; } - public Builder setPlugins(JavaPluginInfo plugins) { - checkNotNull(plugins, "plugins must not be null"); - checkState(this.plugins.isEmpty()); - this.plugins = plugins; + public Builder setProcessorPaths(NestedSet<Artifact> processorPaths) { + this.processorPath = processorPaths; + return this; + } + + public Builder addProcessorNames(Collection<String> processorNames) { + this.processorNames.addAll(processorNames); return this; } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaGenJarsProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaGenJarsProvider.java index b748dbb96a..c5923776c5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaGenJarsProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaGenJarsProvider.java @@ -22,6 +22,9 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.skylarkbuildapi.java.JavaAnnotationProcessingApi; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; import javax.annotation.Nullable; /** The collection of gen jars from the transitive closure. */ @@ -46,7 +49,7 @@ public final class JavaGenJarsProvider boolean usesAnnotationProcessing, @Nullable Artifact genClassJar, @Nullable Artifact genSourceJar, - JavaPluginInfoProvider plugins, + List<JavaPluginInfoProvider> plugins, Iterable<JavaGenJarsProvider> transitiveJavaGenJars) { NestedSetBuilder<Artifact> classJarsBuilder = NestedSetBuilder.stableOrder(); NestedSetBuilder<Artifact> sourceJarsBuilder = NestedSetBuilder.stableOrder(); @@ -61,12 +64,20 @@ public final class JavaGenJarsProvider classJarsBuilder.addTransitive(dep.getTransitiveGenClassJars()); sourceJarsBuilder.addTransitive(dep.getTransitiveGenSourceJars()); } + + NestedSetBuilder<Artifact> processorClasspathsBuilder = NestedSetBuilder.naiveLinkOrder(); + Set<String> processorNames = new LinkedHashSet<>(); + for (JavaPluginInfoProvider plugin : plugins) { + processorClasspathsBuilder.addTransitive(plugin.getProcessorClasspath()); + processorNames.addAll(plugin.getProcessorClasses()); + } + return new JavaGenJarsProvider( usesAnnotationProcessing, genClassJar, genSourceJar, - plugins.plugins().processorClasspath(), - ImmutableList.copyOf(plugins.plugins().processorClasses().toList()), + processorClasspathsBuilder.build(), + ImmutableList.copyOf(processorNames), classJarsBuilder.build(), sourceJarsBuilder.build()); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java index 5d7d66fd0e..7f6436f8c9 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java @@ -52,7 +52,6 @@ import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; -import com.google.devtools.build.lib.rules.java.JavaPluginInfoProvider.JavaPluginInfo; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.util.Fingerprint; import com.google.devtools.build.lib.util.LazyString; @@ -212,7 +211,8 @@ public class JavaHeaderCompileAction extends SpawnAction { private NestedSet<Artifact> compileTimeDependencyArtifacts = NestedSetBuilder.emptySet(Order.STABLE_ORDER); private ImmutableList<String> javacOpts; - private JavaPluginInfo plugins = JavaPluginInfo.empty(); + private NestedSet<Artifact> processorPath = NestedSetBuilder.emptySet(Order.STABLE_ORDER); + private final List<String> processorNames = new ArrayList<>(); private NestedSet<Artifact> additionalInputs = NestedSetBuilder.emptySet(Order.STABLE_ORDER); private Artifact javacJar; @@ -285,10 +285,16 @@ public class JavaHeaderCompileAction extends SpawnAction { } /** Sets the annotation processors classpath entries. */ - public Builder setPlugins(JavaPluginInfo plugins) { - checkNotNull(plugins, "plugins must not be null"); - checkState(this.plugins.isEmpty()); - this.plugins = plugins; + public Builder setProcessorPaths(NestedSet<Artifact> processorPaths) { + checkNotNull(processorPaths, "processorPaths must not be null"); + this.processorPath = processorPaths; + return this; + } + + /** Sets the fully-qualified class names of annotation processors to run. */ + public Builder addProcessorNames(Collection<String> processorNames) { + checkNotNull(processorNames, "processorNames must not be null"); + this.processorNames.addAll(processorNames); return this; } @@ -355,6 +361,8 @@ public class JavaHeaderCompileAction extends SpawnAction { checkNotNull( compileTimeDependencyArtifacts, "compileTimeDependencyArtifacts must not be null"); checkNotNull(javacOpts, "javacOpts must not be null"); + checkNotNull(processorPath, "processorPath must not be null"); + checkNotNull(processorNames, "processorNames must not be null"); // Invariant: if strictJavaDeps is OFF, then directJars and // dependencyArtifacts are ignored @@ -365,7 +373,7 @@ public class JavaHeaderCompileAction extends SpawnAction { // The compilation uses API-generating annotation processors and has to fall back to // javac-turbine. - boolean requiresAnnotationProcessing = !plugins.isEmpty(); + boolean requiresAnnotationProcessing = !processorNames.isEmpty(); NestedSet<Artifact> tools = NestedSetBuilder.<Artifact>stableOrder() @@ -436,7 +444,7 @@ public class JavaHeaderCompileAction extends SpawnAction { NestedSetBuilder.<Artifact>stableOrder() .addTransitive(baseInputs) .addTransitive(classpathEntries) - .addTransitive(plugins.processorClasspath()) + .addTransitive(processorPath) .addTransitive(compileTimeDependencyArtifacts); final CommandLines commandLines; @@ -524,7 +532,7 @@ public class JavaHeaderCompileAction extends SpawnAction { private LazyString getProgressMessageWithAnnotationProcessors() { List<String> shortNames = new ArrayList<>(); - for (String name : plugins.processorClasses()) { + for (String name : processorNames) { shortNames.add(name.substring(name.lastIndexOf('.') + 1)); } String tail = " and running annotation processors (" + Joiner.on(", ").join(shortNames) + ")"; @@ -611,8 +619,12 @@ public class JavaHeaderCompileAction extends SpawnAction { private CommandLine transitiveCommandLine() { CustomCommandLine.Builder result = CustomCommandLine.builder(); baseCommandLine(result, classpathEntries); - result.addAll("--processors", plugins.processorClasses()); - result.addExecPaths("--processorpath", plugins.processorClasspath()); + if (!processorNames.isEmpty()) { + result.addAll("--processors", ImmutableList.copyOf(processorNames)); + } + if (!processorPath.isEmpty()) { + result.addExecPaths("--processorpath", processorPath); + } if (strictJavaDeps != BuildConfiguration.StrictDepsMode.OFF) { result.addExecPaths("--direct_dependencies", directJars); if (!compileTimeDependencyArtifacts.isEmpty()) { diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfoBuildHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfoBuildHelper.java index 560c02d0eb..0bab58e1ec 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfoBuildHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfoBuildHelper.java @@ -20,7 +20,6 @@ import static com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvid import static java.util.stream.Stream.concat; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.ActionAnalysisMetadata; import com.google.devtools.build.lib.actions.ActionRegistry; import com.google.devtools.build.lib.actions.Artifact; @@ -467,11 +466,8 @@ final class JavaInfoBuildHelper { helper.addAllExports(exportsCompilationArgsProviders); helper.setCompilationStrictDepsMode(getStrictDepsMode(strictDepsMode.toUpperCase())); - helper.setPlugins( - JavaPluginInfoProvider.merge( - Iterables.concat( - JavaInfo.fetchProvidersFromList(plugins, JavaPluginInfoProvider.class), - JavaInfo.fetchProvidersFromList(deps, JavaPluginInfoProvider.class)))); + helper.addAllPlugins(JavaInfo.fetchProvidersFromList(plugins, JavaPluginInfoProvider.class)); + helper.addAllPlugins(JavaInfo.fetchProvidersFromList(deps, JavaPluginInfoProvider.class)); helper.setNeverlink(neverlink); JavaRuleOutputJarsProvider.Builder outputJarsBuilder = JavaRuleOutputJarsProvider.builder(); diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java index 8cf6d1b985..3a28e17cca 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java @@ -15,7 +15,6 @@ package com.google.devtools.build.lib.rules.java; import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; import static com.google.devtools.build.lib.analysis.config.BuildConfiguration.StrictDepsMode.OFF; import static com.google.devtools.build.lib.rules.java.JavaCommon.collectJavaCompilationArgs; @@ -53,7 +52,7 @@ public final class JavaLibraryHelper { */ private final List<JavaCompilationArgsProvider> deps = new ArrayList<>(); private final List<JavaCompilationArgsProvider> exports = new ArrayList<>(); - private JavaPluginInfoProvider plugins = JavaPluginInfoProvider.empty(); + private final List<JavaPluginInfoProvider> plugins = new ArrayList<>(); private ImmutableList<String> javacOpts = ImmutableList.of(); private ImmutableList<Artifact> sourcePathEntries = ImmutableList.of(); private StrictDepsMode strictDepsMode = StrictDepsMode.OFF; @@ -132,10 +131,8 @@ public final class JavaLibraryHelper { return this; } - public JavaLibraryHelper setPlugins(JavaPluginInfoProvider plugins) { - checkNotNull(plugins, "plugins must not be null"); - checkState(this.plugins.isEmpty()); - this.plugins = plugins; + public JavaLibraryHelper addAllPlugins(Iterable<JavaPluginInfoProvider> providers) { + Iterables.addAll(plugins, providers); return this; } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaPluginInfoProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaPluginInfoProvider.java index 48241d4ccf..59ed632abc 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaPluginInfoProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaPluginInfoProvider.java @@ -14,93 +14,76 @@ package com.google.devtools.build.lib.rules.java; -import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; -import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; -import java.util.ArrayList; -import java.util.List; /** Provider for users of Java plugins. */ @AutoCodec @Immutable -@AutoValue -public abstract class JavaPluginInfoProvider implements TransitiveInfoProvider { - - /** Information about a Java plugin, except for whether it generates API. */ - @AutoCodec - @Immutable - @AutoValue - public abstract static class JavaPluginInfo { - - public static JavaPluginInfo create( - NestedSet<String> processorClasses, NestedSet<Artifact> processorClasspath) { - return new AutoValue_JavaPluginInfoProvider_JavaPluginInfo( - processorClasses, processorClasspath); - } - - @AutoCodec.Instantiator - public static JavaPluginInfo empty() { - return create( - NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), - NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER)); - } - - public static JavaPluginInfo merge(Iterable<JavaPluginInfo> plugins) { - NestedSetBuilder<String> processorClasses = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder<Artifact> processorClasspath = NestedSetBuilder.naiveLinkOrder(); - for (JavaPluginInfo plugin : plugins) { - processorClasses.addTransitive(plugin.processorClasses()); - processorClasspath.addTransitive(plugin.processorClasspath()); - } - return create(processorClasses.build(), processorClasspath.build()); - } - - /** - * Returns the class that should be passed to javac in order to run the annotation processor - * this class represents. - */ - public abstract NestedSet<String> processorClasses(); - - /** Returns the artifacts to add to the runtime classpath for this plugin. */ - public abstract NestedSet<Artifact> processorClasspath(); - - public boolean isEmpty() { - return processorClasses().isEmpty() && processorClasspath().isEmpty(); - } - } +public final class JavaPluginInfoProvider implements TransitiveInfoProvider { public static JavaPluginInfoProvider merge(Iterable<JavaPluginInfoProvider> providers) { - List<JavaPluginInfo> plugins = new ArrayList<>(); - List<JavaPluginInfo> apiGeneratingPlugins = new ArrayList<>(); + ImmutableSet.Builder<String> processorClasses = ImmutableSet.builder(); + NestedSetBuilder<Artifact> processorClasspath = NestedSetBuilder.naiveLinkOrder(); + ImmutableSet.Builder<String> apiGeneratingProcessorClasses = ImmutableSet.builder(); + NestedSetBuilder<Artifact> apiGeneratingProcessorClasspath = NestedSetBuilder.naiveLinkOrder(); + for (JavaPluginInfoProvider provider : providers) { - plugins.add(provider.plugins()); - apiGeneratingPlugins.add(provider.apiGeneratingPlugins()); + processorClasses.addAll(provider.getProcessorClasses()); + processorClasspath.addTransitive(provider.getProcessorClasspath()); + apiGeneratingProcessorClasses.addAll(provider.getApiGeneratingProcessorClasses()); + apiGeneratingProcessorClasspath.addTransitive(provider.getApiGeneratingProcessorClasspath()); } - return new AutoValue_JavaPluginInfoProvider( - JavaPluginInfo.merge(plugins), JavaPluginInfo.merge(apiGeneratingPlugins)); + return new JavaPluginInfoProvider( + processorClasses.build(), + processorClasspath.build(), + apiGeneratingProcessorClasses.build(), + apiGeneratingProcessorClasspath.build()); } - public static JavaPluginInfoProvider create(JavaPluginInfo javaPluginInfo, Boolean generatesApi) { - return new AutoValue_JavaPluginInfoProvider( - javaPluginInfo, generatesApi ? javaPluginInfo : JavaPluginInfo.empty()); + private final ImmutableSet<String> processorClasses; + private final NestedSet<Artifact> processorClasspath; + private final ImmutableSet<String> apiGeneratingProcessorClasses; + private final NestedSet<Artifact> apiGeneratingProcessorClasspath; + + public JavaPluginInfoProvider( + ImmutableSet<String> processorClasses, + NestedSet<Artifact> processorClasspath, + ImmutableSet<String> apiGeneratingProcessorClasses, + NestedSet<Artifact> apiGeneratingProcessorClasspath) { + this.processorClasses = processorClasses; + this.processorClasspath = processorClasspath; + this.apiGeneratingProcessorClasses = apiGeneratingProcessorClasses; + this.apiGeneratingProcessorClasspath = apiGeneratingProcessorClasspath; } - @AutoCodec.Instantiator - public static JavaPluginInfoProvider empty() { - return new AutoValue_JavaPluginInfoProvider(JavaPluginInfo.empty(), JavaPluginInfo.empty()); + /** + * Returns the class that should be passed to javac in order + * to run the annotation processor this class represents. + */ + public ImmutableSet<String> getProcessorClasses() { + return processorClasses; } - public abstract JavaPluginInfo plugins(); + /** + * Returns the artifacts to add to the runtime classpath for this plugin. + */ + public NestedSet<Artifact> getProcessorClasspath() { + return processorClasspath; + } - public abstract JavaPluginInfo apiGeneratingPlugins(); + /** Returns the class names of API-generating annotation processors. */ + public ImmutableSet<String> getApiGeneratingProcessorClasses() { + return apiGeneratingProcessorClasses; + } - public boolean isEmpty() { - // apiGeneratingPlugins is a subset of plugins, so checking if plugins is empty is sufficient - return plugins().isEmpty(); + /** Returns the artifacts to add to the runtime classpath of the API-generating processors. */ + public NestedSet<Artifact> getApiGeneratingProcessorClasspath() { + return apiGeneratingProcessorClasspath; } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSourceInfoProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSourceInfoProvider.java index ea09db174c..f29e90e306 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSourceInfoProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSourceInfoProvider.java @@ -18,6 +18,9 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; +import com.google.devtools.build.lib.collect.nestedset.NestedSet; +import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; +import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization; @@ -34,6 +37,8 @@ public final class JavaSourceInfoProvider implements TransitiveInfoProvider { private final Collection<Artifact> jarFiles; private final Collection<Artifact> sourceJarsForJarFiles; private final Map<PathFragment, Artifact> resources; + private final Collection<String> processorNames; + private final NestedSet<Artifact> processorPath; @VisibleForSerialization JavaSourceInfoProvider( @@ -41,12 +46,16 @@ public final class JavaSourceInfoProvider implements TransitiveInfoProvider { Collection<Artifact> sourceJars, Collection<Artifact> jarFiles, Collection<Artifact> sourceJarsForJarFiles, - Map<PathFragment, Artifact> resources) { + Map<PathFragment, Artifact> resources, + Collection<String> processorNames, + NestedSet<Artifact> processorPath) { this.sourceFiles = sourceFiles; this.sourceJars = sourceJars; this.jarFiles = jarFiles; this.sourceJarsForJarFiles = sourceJarsForJarFiles; this.resources = resources; + this.processorNames = processorNames; + this.processorPath = processorPath; } /** Gets the original Java source files provided as inputs to this rule. */ @@ -93,6 +102,16 @@ public final class JavaSourceInfoProvider implements TransitiveInfoProvider { return resources; } + /** Gets the names of the annotation processors which operate on this rule's sources. */ + public Collection<String> getProcessorNames() { + return processorNames; + } + + /** Gets the classpath for the annotation processors which operate on this rule's sources. */ + public NestedSet<Artifact> getProcessorPath() { + return processorPath; + } + /** * Constructs a JavaSourceInfoProvider using the sources in the given JavaTargetAttributes. * @@ -105,6 +124,8 @@ public final class JavaSourceInfoProvider implements TransitiveInfoProvider { .setSourceFiles(attributes.getSourceFiles()) .setSourceJars(attributes.getSourceJars()) .setResources(attributes.getResources()) + .setProcessorNames(attributes.getProcessorNames()) + .setProcessorPath(attributes.getProcessorPath()) .build(); } @@ -115,6 +136,8 @@ public final class JavaSourceInfoProvider implements TransitiveInfoProvider { private Collection<Artifact> jarFiles = ImmutableList.<Artifact>of(); private Collection<Artifact> sourceJarsForJarFiles = ImmutableList.<Artifact>of(); private Map<PathFragment, Artifact> resources = ImmutableMap.<PathFragment, Artifact>of(); + private Collection<String> processorNames = ImmutableList.<String>of(); + private NestedSet<Artifact> processorPath = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER); /** Sets the source files included as part of the sources of this rule. */ public Builder setSourceFiles(Collection<Artifact> sourceFiles) { @@ -157,10 +180,29 @@ public final class JavaSourceInfoProvider implements TransitiveInfoProvider { return this; } + /** Sets the names of the annotation processors used by this rule. */ + public Builder setProcessorNames(Collection<String> processorNames) { + this.processorNames = Preconditions.checkNotNull(processorNames); + return this; + } + + /** Sets the classpath used by this rule for annotation processing. */ + public Builder setProcessorPath(NestedSet<Artifact> processorPath) { + Preconditions.checkNotNull(processorPath); + this.processorPath = processorPath; + return this; + } + /** Constructs the JavaSourceInfoProvider from the provided Java sources. */ public JavaSourceInfoProvider build() { return new JavaSourceInfoProvider( - sourceFiles, sourceJars, jarFiles, sourceJarsForJarFiles, resources); + sourceFiles, + sourceJars, + jarFiles, + sourceJarsForJarFiles, + resources, + processorNames, + processorPath); } } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaTargetAttributes.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaTargetAttributes.java index d75c9dad76..9f51626b54 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaTargetAttributes.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaTargetAttributes.java @@ -70,7 +70,14 @@ public class JavaTargetAttributes { private final List<Artifact> sourcePath = new ArrayList<>(); private final List<Artifact> nativeLibraries = new ArrayList<>(); - private JavaPluginInfoProvider plugins = JavaPluginInfoProvider.empty(); + private final NestedSetBuilder<Artifact> processorPath = NestedSetBuilder.naiveLinkOrder(); + // Classpath directories can't be represented as artifacts (TreeArtifact isn't appropriate + // here since all we need is a path string to apply to the command line). + private final Set<String> processorNames = new LinkedHashSet<>(); + + private final NestedSetBuilder<Artifact> apiGeneratingProcessorPath = + NestedSetBuilder.naiveLinkOrder(); + private final Set<String> apiGeneratingProcessorNames = new LinkedHashSet<>(); private final Map<PathFragment, Artifact> resources = new LinkedHashMap<>(); private final NestedSetBuilder<Artifact> resourceJars = NestedSetBuilder.stableOrder(); @@ -297,10 +304,27 @@ public class JavaTargetAttributes { return this; } - public Builder addPlugin(JavaPluginInfoProvider plugins) { + public Builder addProcessorName(String processor) { + Preconditions.checkArgument(!built); + processorNames.add(processor); + return this; + } + + public Builder addProcessorPath(NestedSet<Artifact> jars) { + Preconditions.checkArgument(!built); + processorPath.addTransitive(jars); + return this; + } + + public Builder addApiGeneratingProcessorName(String processor) { + Preconditions.checkArgument(!built); + apiGeneratingProcessorNames.add(processor); + return this; + } + + public Builder addApiGeneratingProcessorPath(NestedSet<Artifact> jars) { Preconditions.checkArgument(!built); - Preconditions.checkArgument(this.plugins.isEmpty()); - this.plugins = plugins; + apiGeneratingProcessorPath.addTransitive(jars); return this; } @@ -334,7 +358,10 @@ public class JavaTargetAttributes { bootClassPath, sourcePath, nativeLibraries, - plugins, + processorPath.build(), + processorNames, + apiGeneratingProcessorPath.build(), + apiGeneratingProcessorNames, resources, resourceJars.build(), messages, @@ -364,28 +391,19 @@ public class JavaTargetAttributes { return !sourceFiles.isEmpty() || !sourceJars.isEmpty(); } - /** - * @deprecated prefer to use a built {@link JavaTargetAttributes} instead of accessing mutable - * state in the {@link Builder}. - */ + /** @deprecated prefer {@link JavaTargetAttributes#hasSourceFiles} */ @Deprecated public boolean hasSourceFiles() { return !sourceFiles.isEmpty(); } - /** - * @deprecated prefer to use a built {@link JavaTargetAttributes} instead of accessing mutable - * state in the {@link Builder}. - */ + /** @deprecated prefer {@link JavaTargetAttributes#getInstrumentationMetadata} */ @Deprecated public List<Artifact> getInstrumentationMetadata() { return instrumentationMetadata; } - /** - * @deprecated prefer to use a built {@link JavaTargetAttributes} instead of accessing mutable - * state in the {@link Builder}. - */ + /** @deprecated prefer {@link JavaTargetAttributes#hasSourceJars} */ @Deprecated public boolean hasSourceJars() { return !sourceJars.isEmpty(); @@ -405,7 +423,11 @@ public class JavaTargetAttributes { private final ImmutableList<Artifact> sourcePath; private final ImmutableList<Artifact> nativeLibraries; - private final JavaPluginInfoProvider plugins; + private final NestedSet<Artifact> processorPath; + private final ImmutableSet<String> processorNames; + + private final NestedSet<Artifact> apiGeneratingProcessorPath; + private final ImmutableSet<String> apiGeneratingProcessorNames; private final ImmutableMap<PathFragment, Artifact> resources; private final NestedSet<Artifact> resourceJars; @@ -433,7 +455,10 @@ public class JavaTargetAttributes { List<Artifact> bootClassPath, List<Artifact> sourcePath, List<Artifact> nativeLibraries, - JavaPluginInfoProvider plugins, + NestedSet<Artifact> processorPath, + Set<String> processorNames, + NestedSet<Artifact> apiGeneratingProcessorPath, + Set<String> apiGeneratingProcessorNames, Map<PathFragment, Artifact> resources, NestedSet<Artifact> resourceJars, List<Artifact> messages, @@ -457,7 +482,10 @@ public class JavaTargetAttributes { this.bootClassPath = ImmutableList.copyOf(bootClassPath); this.sourcePath = ImmutableList.copyOf(sourcePath); this.nativeLibraries = ImmutableList.copyOf(nativeLibraries); - this.plugins = plugins; + this.processorPath = processorPath; + this.processorNames = ImmutableSet.copyOf(processorNames); + this.apiGeneratingProcessorPath = apiGeneratingProcessorPath; + this.apiGeneratingProcessorNames = ImmutableSet.copyOf(apiGeneratingProcessorNames); this.resources = ImmutableMap.copyOf(resources); this.resourceJars = resourceJars; this.messages = ImmutableList.copyOf(messages); @@ -561,8 +589,16 @@ public class JavaTargetAttributes { return sourcePath; } - public JavaPluginInfoProvider plugins() { - return plugins; + public NestedSet<Artifact> getProcessorPath() { + return processorPath; + } + + public NestedSet<Artifact> getApiGeneratingProcessorPath() { + return apiGeneratingProcessorPath; + } + + public ImmutableSet<String> getApiGeneratingProcessorNames() { + return apiGeneratingProcessorNames; } public ImmutableSet<Artifact> getSourceFiles() { @@ -573,6 +609,10 @@ public class JavaTargetAttributes { return nativeLibraries; } + public Collection<String> getProcessorNames() { + return processorNames; + } + public boolean hasSources() { return !sourceFiles.isEmpty() || !sourceJars.isEmpty(); } diff --git a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java index 0d399f2db3..298bfc0c2d 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java @@ -270,7 +270,6 @@ public final class BazelAnalysisMock extends AnalysisMock { .add("sh_binary(name = 'android_runtest', srcs = ['empty.sh'])") .add("sh_binary(name = 'instrumentation_test_entry_point', srcs = ['empty.sh'])") .add("java_plugin(name = 'databinding_annotation_processor',") - .add(" generates_api = 1,") .add(" processor_class = 'android.databinding.annotationprocessor.ProcessDataBinding')") .add("sh_binary(name = 'jarjar_bin', srcs = ['empty.sh'])") .add("sh_binary(name = 'instrumentation_test_check', srcs = ['empty.sh'])") |