Skip to content

Commit c00ec98

Browse files
iirinahlopko
authored andcommitted
Add plugins and exported_plugins params to java_common.compile.
This is a step forward to having the same semantics for java_library and custom Skylark rules that use java_common.compile, facilitating the migration from native Java rules to Skylark. Progress on #2614 PiperOrigin-RevId: 160644961
1 parent ed3ba03 commit c00ec98

File tree

7 files changed

+142
-63
lines changed

7 files changed

+142
-63
lines changed

src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java

+45-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.google.common.collect.ImmutableList;
1919
import com.google.common.collect.ImmutableList.Builder;
2020
import com.google.common.collect.ImmutableMap;
21+
import com.google.common.collect.ImmutableSet;
2122
import com.google.common.collect.Iterables;
2223
import com.google.common.collect.Streams;
2324
import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
@@ -732,6 +733,18 @@ private void processRuntimeDeps(JavaTargetAttributes.Builder attributes) {
732733
* the target attributes.
733734
*/
734735
private void addPlugins(JavaTargetAttributes.Builder attributes) {
736+
addPlugins(attributes, activePlugins);
737+
}
738+
739+
/**
740+
* Adds information about the annotation processors that should be run for this java target
741+
* retrieved from the given plugins to the target attributes.
742+
*
743+
* In particular, the processor names/paths and the API generating processor names/paths are added
744+
* to the given attributes. Plugins having repetitive names/paths will be added only once.
745+
*/
746+
public static void addPlugins(
747+
JavaTargetAttributes.Builder attributes, Iterable<JavaPluginInfoProvider> activePlugins) {
735748
for (JavaPluginInfoProvider plugin : activePlugins) {
736749
for (String name : plugin.getProcessorClasses()) {
737750
attributes.addProcessorName(name);
@@ -759,11 +772,42 @@ private ImmutableList<JavaPluginInfoProvider> collectPlugins() {
759772
private static Iterable<JavaPluginInfoProvider> getPluginInfoProvidersForAttribute(
760773
RuleContext ruleContext, String attribute, Mode mode) {
761774
if (ruleContext.attributes().has(attribute, BuildType.LABEL_LIST)) {
762-
return ruleContext.getPrerequisites(attribute, mode, JavaPluginInfoProvider.class);
775+
return JavaProvider.getProvidersFromListOfTargets(
776+
JavaPluginInfoProvider.class, ruleContext.getPrerequisites(attribute, mode));
763777
}
764778
return ImmutableList.of();
765779
}
766780

781+
JavaPluginInfoProvider getJavaPluginInfoProvider(RuleContext ruleContext) {
782+
ImmutableSet<String> processorClasses = getProcessorClasses(ruleContext);
783+
NestedSet<Artifact> processorClasspath = getRuntimeClasspath();
784+
ImmutableSet<String> apiGeneratingProcessorClasses;
785+
NestedSet<Artifact> apiGeneratingProcessorClasspath;
786+
if (ruleContext.attributes().get("generates_api", Type.BOOLEAN)) {
787+
apiGeneratingProcessorClasses = processorClasses;
788+
apiGeneratingProcessorClasspath = processorClasspath;
789+
} else {
790+
apiGeneratingProcessorClasses = ImmutableSet.of();
791+
apiGeneratingProcessorClasspath = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER);
792+
}
793+
794+
return new JavaPluginInfoProvider(
795+
processorClasses,
796+
processorClasspath,
797+
apiGeneratingProcessorClasses,
798+
apiGeneratingProcessorClasspath);
799+
}
800+
801+
/**
802+
* Returns the class that should be passed to javac in order to run the annotation processor this
803+
* class represents.
804+
*/
805+
private static ImmutableSet<String> getProcessorClasses(RuleContext ruleContext) {
806+
return ruleContext.getRule().isAttributeValueExplicitlySpecified("processor_class")
807+
? ImmutableSet.of(ruleContext.attributes().get("processor_class", Type.STRING))
808+
: ImmutableSet.<String>of();
809+
}
810+
767811
public static JavaPluginInfoProvider getTransitivePlugins(RuleContext ruleContext) {
768812
return JavaPluginInfoProvider.merge(Iterables.concat(
769813
getPluginInfoProvidersForAttribute(ruleContext, "exported_plugins", Mode.HOST),

src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java

+25-15
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,16 @@ protected JavaLibrary(JavaSemantics semantics) {
4848
public ConfiguredTarget create(RuleContext ruleContext)
4949
throws InterruptedException, RuleErrorException {
5050
JavaCommon common = new JavaCommon(ruleContext, semantics);
51-
RuleConfiguredTargetBuilder builder =
52-
init(ruleContext, common, false /* includeGeneratedExtensionRegistry */);
53-
return builder != null ? builder.build() : null;
51+
return init(
52+
ruleContext,
53+
common,
54+
/* includeGeneratedExtensionRegistry = */false,
55+
/* includeJavaPluginInfoProvider = */ false);
5456
}
5557

56-
final RuleConfiguredTargetBuilder init(
57-
RuleContext ruleContext, final JavaCommon common, boolean includeGeneratedExtensionRegistry)
58+
final ConfiguredTarget init(
59+
RuleContext ruleContext, final JavaCommon common, boolean includeGeneratedExtensionRegistry,
60+
boolean includeJavaPluginInfoProvider)
5861
throws InterruptedException {
5962
JavaTargetAttributes.Builder attributesBuilder = common.initCommon();
6063

@@ -211,13 +214,7 @@ protected void collect(CcLinkParams.Builder builder, boolean linkingStatically,
211214
NestedSet<Artifact> proguardSpecs = new ProguardLibrary(ruleContext).collectProguardSpecs();
212215

213216
CcLinkParamsProvider ccLinkParamsProvider = new CcLinkParamsProvider(ccLinkParamsStore);
214-
JavaProvider javaProvider = JavaProvider.Builder.create()
215-
.addProvider(JavaCompilationArgsProvider.class, compilationArgsProvider)
216-
.addProvider(JavaSourceJarsProvider.class, sourceJarsProvider)
217-
.addProvider(ProtoJavaApiInfoAspectProvider.class, protoAspectBuilder.build())
218-
.addProvider(JavaRuleOutputJarsProvider.class, ruleOutputJarsProvider)
219-
// java_library doesn't need to return JavaRunfilesProvider
220-
.build();
217+
221218
builder
222219
.addSkylarkTransitiveInfo(
223220
JavaSkylarkApiProvider.NAME, JavaSkylarkApiProvider.fromRuleContext())
@@ -230,10 +227,8 @@ protected void collect(CcLinkParams.Builder builder, boolean linkingStatically,
230227
.addProvider(new JavaNeverlinkInfoProvider(neverLink))
231228
.addProvider(transitiveCppDeps)
232229
.addProvider(JavaCompilationArgsProvider.class, compilationArgsProvider)
233-
.addProvider(javaProvider)
234230
.addProvider(ccLinkParamsProvider)
235231
.addNativeDeclaredProvider(ccLinkParamsProvider)
236-
.addNativeDeclaredProvider(javaProvider)
237232
.addProvider(new JavaNativeLibraryProvider(transitiveJavaNativeLibraries))
238233
.addProvider(JavaSourceInfoProvider.fromJavaTargetAttributes(attributes, semantics))
239234
// TODO(bazel-team): this should only happen for java_plugin
@@ -243,10 +238,25 @@ protected void collect(CcLinkParams.Builder builder, boolean linkingStatically,
243238
.addOutputGroup(JavaSemantics.SOURCE_JARS_OUTPUT_GROUP, transitiveSourceJars)
244239
.addOutputGroup(OutputGroupProvider.HIDDEN_TOP_LEVEL, proguardSpecs);
245240

241+
// java_library doesn't need to return JavaRunfilesProvider
242+
JavaProvider.Builder javaProviderBuilder = JavaProvider.Builder.create()
243+
.addProvider(JavaCompilationArgsProvider.class, compilationArgsProvider)
244+
.addProvider(JavaSourceJarsProvider.class, sourceJarsProvider)
245+
.addProvider(ProtoJavaApiInfoAspectProvider.class, protoAspectBuilder.build())
246+
.addProvider(JavaRuleOutputJarsProvider.class, ruleOutputJarsProvider);
247+
if (includeJavaPluginInfoProvider) {
248+
JavaPluginInfoProvider javaPluginInfoProvider = common.getJavaPluginInfoProvider(ruleContext);
249+
javaProviderBuilder.addProvider(JavaPluginInfoProvider.class, javaPluginInfoProvider);
250+
builder.addProvider(javaPluginInfoProvider);
251+
}
252+
JavaProvider javaProvider = javaProviderBuilder.build();
253+
builder.addProvider(javaProvider);
254+
builder.addNativeDeclaredProvider(javaProvider);
255+
246256
if (ruleContext.hasErrors()) {
247257
return null;
248258
}
249259

250-
return builder;
260+
return builder.build();
251261
}
252262
}

src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java

+7
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public final class JavaLibraryHelper {
5353
*/
5454
private final List<JavaCompilationArgsProvider> deps = new ArrayList<>();
5555
private final List<JavaCompilationArgsProvider> exports = new ArrayList<>();
56+
private final List<JavaPluginInfoProvider> plugins = new ArrayList<>();
5657
private ImmutableList<String> javacOpts = ImmutableList.of();
5758
private ImmutableList<Artifact> sourcePathEntries = ImmutableList.of();
5859
private StrictDepsMode strictDepsMode = StrictDepsMode.OFF;
@@ -119,6 +120,11 @@ public JavaLibraryHelper addAllExports(Iterable<JavaCompilationArgsProvider> pro
119120
return this;
120121
}
121122

123+
public JavaLibraryHelper addAllPlugins(Iterable<JavaPluginInfoProvider> providers) {
124+
Iterables.addAll(plugins, providers);
125+
return this;
126+
}
127+
122128
/**
123129
* Sets the compiler options.
124130
*/
@@ -163,6 +169,7 @@ public JavaCompilationArtifacts build(
163169
attributes.setRuleKind(ruleContext.getRule().getRuleClass());
164170
attributes.setTargetLabel(ruleContext.getLabel());
165171
attributes.setSourcePath(sourcePathEntries);
172+
JavaCommon.addPlugins(attributes, plugins);
166173

167174
for (Artifact resource : resources) {
168175
attributes.addResource(

src/main/java/com/google/devtools/build/lib/rules/java/JavaPlugin.java

+5-44
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,9 @@
1313
// limitations under the License.
1414
package com.google.devtools.build.lib.rules.java;
1515

16-
import com.google.common.collect.ImmutableSet;
17-
import com.google.devtools.build.lib.actions.Artifact;
1816
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
19-
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
2017
import com.google.devtools.build.lib.analysis.RuleContext;
21-
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
22-
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
23-
import com.google.devtools.build.lib.collect.nestedset.Order;
24-
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
2518
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
26-
import com.google.devtools.build.lib.syntax.Type;
2719

2820
/**
2921
* Implementation for the java_plugin rule.
@@ -39,41 +31,10 @@ protected JavaPlugin(JavaSemantics semantics) {
3931
@Override
4032
public final ConfiguredTarget create(RuleContext ruleContext)
4133
throws InterruptedException, RuleErrorException {
42-
JavaLibrary javaLibrary = new JavaLibrary(semantics);
43-
JavaCommon common = new JavaCommon(ruleContext, semantics);
44-
RuleConfiguredTargetBuilder builder =
45-
javaLibrary.init(ruleContext, common, true /* includeGeneratedExtensionRegistry */);
46-
if (builder == null) {
47-
return null;
48-
}
49-
ImmutableSet<String> processorClasses = getProcessorClasses(ruleContext);
50-
NestedSet<Artifact> processorClasspath = common.getRuntimeClasspath();
51-
ImmutableSet<String> apiGeneratingProcessorClasses;
52-
NestedSet<Artifact> apiGeneratingProcessorClasspath;
53-
if (ruleContext.attributes().get("generates_api", Type.BOOLEAN)) {
54-
apiGeneratingProcessorClasses = processorClasses;
55-
apiGeneratingProcessorClasspath = processorClasspath;
56-
} else {
57-
apiGeneratingProcessorClasses = ImmutableSet.of();
58-
apiGeneratingProcessorClasspath = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER);
59-
}
60-
builder.addProvider(
61-
new JavaPluginInfoProvider(
62-
processorClasses,
63-
processorClasspath,
64-
apiGeneratingProcessorClasses,
65-
apiGeneratingProcessorClasspath));
66-
return builder.build();
67-
}
68-
69-
/**
70-
* Returns the class that should be passed to javac in order to run the annotation processor this
71-
* class represents.
72-
*/
73-
private static ImmutableSet<String> getProcessorClasses(RuleContext ruleContext) {
74-
if (ruleContext.getRule().isAttributeValueExplicitlySpecified("processor_class")) {
75-
return ImmutableSet.of(ruleContext.attributes().get("processor_class", Type.STRING));
76-
}
77-
return ImmutableSet.of();
34+
return new JavaLibrary(semantics).init(
35+
ruleContext,
36+
new JavaCommon(ruleContext, semantics),
37+
/* includeGeneratedExtensionRegistry = */ true,
38+
/* includeJavaPluginInfoProvider = */ true);
7839
}
7940
}

src/main/java/com/google/devtools/build/lib/rules/java/JavaProvider.java

+24-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package com.google.devtools.build.lib.rules.java;
1515

1616
import com.google.common.base.Preconditions;
17+
import com.google.common.collect.ImmutableList;
1718
import com.google.common.collect.ImmutableMap;
1819
import com.google.common.collect.ImmutableSet;
1920
import com.google.devtools.build.lib.actions.Artifact;
@@ -45,7 +46,8 @@ public final class JavaProvider extends SkylarkClassObject implements Transitive
4546
JavaSourceJarsProvider.class,
4647
ProtoJavaApiInfoAspectProvider.class,
4748
JavaRuleOutputJarsProvider.class,
48-
JavaRunfilesProvider.class
49+
JavaRunfilesProvider.class,
50+
JavaPluginInfoProvider.class
4951
);
5052

5153
private final TransitiveInfoProviderMap providers;
@@ -74,6 +76,8 @@ public static JavaProvider merge(List<JavaProvider> providers) {
7476
JavaProvider.fetchProvidersFromList(providers, ProtoJavaApiInfoAspectProvider.class);
7577
List<JavaRunfilesProvider> javaRunfilesProviders =
7678
JavaProvider.fetchProvidersFromList(providers, JavaRunfilesProvider.class);
79+
List<JavaPluginInfoProvider> javaPluginInfoProviders =
80+
JavaProvider.fetchProvidersFromList(providers, JavaPluginInfoProvider.class);
7781

7882
Runfiles mergedRunfiles = Runfiles.EMPTY;
7983
for (JavaRunfilesProvider javaRunfilesProvider : javaRunfilesProviders) {
@@ -94,6 +98,8 @@ public static JavaProvider merge(List<JavaProvider> providers) {
9498
// it doesn't have any output jars.
9599
.addProvider(JavaRuleOutputJarsProvider.class, JavaRuleOutputJarsProvider.builder().build())
96100
.addProvider(JavaRunfilesProvider.class, new JavaRunfilesProvider(mergedRunfiles))
101+
.addProvider(
102+
JavaPluginInfoProvider.class, JavaPluginInfoProvider.merge(javaPluginInfoProviders))
97103
.build();
98104
}
99105

@@ -152,6 +158,23 @@ public static <T extends TransitiveInfoProvider> List<T> getProvidersFromListOfT
152158
return providersList;
153159
}
154160

161+
/**
162+
* Returns a list of the given provider class with all the said providers retrieved from the
163+
* given {@link JavaProvider}s.
164+
*/
165+
public static <T extends TransitiveInfoProvider> ImmutableList<T>
166+
getProvidersFromListOfJavaProviders(
167+
Class<T> providerClass, Iterable<JavaProvider> javaProviders) {
168+
ImmutableList.Builder<T> providersList = new ImmutableList.Builder<>();
169+
for (JavaProvider javaProvider : javaProviders) {
170+
T provider = javaProvider.getProvider(providerClass);
171+
if (provider != null) {
172+
providersList.add(provider);
173+
}
174+
}
175+
return providersList.build();
176+
}
177+
155178
private JavaProvider(TransitiveInfoProviderMap providers) {
156179
super(JAVA_PROVIDER, ImmutableMap.<String, Object>of(
157180
"transitive_runtime_jars", SkylarkNestedSet.of(

src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java

+34
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,24 @@ private static NestedSet<Artifact> asArtifactNestedSet(Object o) throws EvalExce
190190
defaultValue = "[]",
191191
doc = "A list of exports. Optional."
192192
),
193+
@Param(
194+
name = "plugins",
195+
positional = false,
196+
named = true,
197+
type = SkylarkList.class,
198+
generic1 = JavaProvider.class,
199+
defaultValue = "[]",
200+
doc = "A list of plugins. Optional."
201+
),
202+
@Param(
203+
name = "exported_plugins",
204+
positional = false,
205+
named = true,
206+
type = SkylarkList.class,
207+
generic1 = JavaProvider.class,
208+
defaultValue = "[]",
209+
doc = "A list of exported plugins. Optional."
210+
),
193211
@Param(
194212
name = "strict_deps",
195213
defaultValue = "'ERROR'",
@@ -241,6 +259,8 @@ public JavaProvider createJavaCompileAction(
241259
SkylarkList<String> javacOpts,
242260
SkylarkList<JavaProvider> deps,
243261
SkylarkList<JavaProvider> exports,
262+
SkylarkList<JavaProvider> plugins,
263+
SkylarkList<JavaProvider> exportedPlugins,
244264
String strictDepsMode,
245265
ConfiguredTarget javaToolchain,
246266
ConfiguredTarget hostJavabase,
@@ -265,6 +285,10 @@ public JavaProvider createJavaCompileAction(
265285
helper.setCompilationStrictDepsMode(getStrictDepsMode(strictDepsMode));
266286
MiddlemanProvider hostJavabaseProvider = hostJavabase.getProvider(MiddlemanProvider.class);
267287

288+
helper.addAllPlugins(
289+
JavaProvider.fetchProvidersFromList(plugins, JavaPluginInfoProvider.class));
290+
helper.addAllPlugins(JavaProvider.fetchProvidersFromList(deps, JavaPluginInfoProvider.class));
291+
268292
NestedSet<Artifact> hostJavabaseArtifacts =
269293
hostJavabaseProvider == null
270294
? NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER)
@@ -285,11 +309,21 @@ public JavaProvider createJavaCompileAction(
285309
helper.buildCompilationArgsProvider(artifacts, true);
286310
Runfiles runfiles = new Runfiles.Builder(skylarkRuleContext.getWorkspaceName()).addArtifacts(
287311
javaCompilationArgsProvider.getRecursiveJavaCompilationArgs().getRuntimeJars()).build();
312+
313+
JavaPluginInfoProvider transitivePluginsProvider =
314+
JavaPluginInfoProvider.merge(Iterables.concat(
315+
JavaProvider.getProvidersFromListOfJavaProviders(
316+
JavaPluginInfoProvider.class, exportedPlugins),
317+
JavaProvider.getProvidersFromListOfJavaProviders(
318+
JavaPluginInfoProvider.class, exports)
319+
));
320+
288321
return JavaProvider.Builder.create()
289322
.addProvider(JavaCompilationArgsProvider.class, javaCompilationArgsProvider)
290323
.addProvider(JavaSourceJarsProvider.class, createJavaSourceJarsProvider(sourceJars))
291324
.addProvider(JavaRuleOutputJarsProvider.class, javaRuleOutputJarsProvider)
292325
.addProvider(JavaRunfilesProvider.class, new JavaRunfilesProvider(runfiles))
326+
.addProvider(JavaPluginInfoProvider.class, transitivePluginsProvider)
293327
.build();
294328
}
295329

src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ public void testJavaPlugin() throws Exception {
134134
SkylarkClassObject skylarkClassObject = configuredTarget.get(
135135
new SkylarkKey(Label.parseAbsolute("//java/test:extension.bzl"), "result"));
136136

137+
assertThat((List<?>) skylarkClassObject.getValue("processor_classnames"))
138+
.containsExactly("com.google.process.stuff");
137139
assertThat(
138140
Iterables.transform(
139141
((SkylarkNestedSet) skylarkClassObject.getValue("processor_classpath"))
@@ -146,8 +148,6 @@ public String apply(Object o) {
146148
}))
147149
.containsExactly("libplugin.jar", "libplugin_dep.jar");
148150

149-
assertThat((List<?>) skylarkClassObject.getValue("processor_classnames"))
150-
.containsExactly("com.google.process.stuff");
151151
}
152152

153153
@Test

0 commit comments

Comments
 (0)