aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar dbabkin <dbabkin@google.com>2018-01-10 05:24:22 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2018-01-10 05:26:29 -0800
commit32dff21d00ad7d1bdf50e8761d675a6e7e002de9 (patch)
treeb4c63f295bcb7482dabd9e30da7efcea988c7ea0
parentcc386e62a2c585f7e0ef87ed5440c9abd757d647 (diff)
Create function createJavaInfo with new API. Implement JavaCompilationArgsProvider.
Added tests for checking JavaCompilationArgsProvider state. All other providers will be implemented in next CLs. RELNOTES:none PiperOrigin-RevId: 181451235
-rw-r--r--src/main/java/com/google/devtools/build/lib/BUILD2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgs.java17
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaInfo.java100
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaInfoBuildHelper.java395
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java268
-rw-r--r--src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java332
-rwxr-xr-xsrc/test/shell/bazel/bazel_java_test.sh76
7 files changed, 955 insertions, 235 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index fbfb27f16e..4b404b9733 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -869,6 +869,7 @@ java_library(
"rules/java/JavaHeaderCompileAction.java",
"rules/java/JavaHelper.java",
"rules/java/JavaInfo.java",
+ "rules/java/JavaInfoBuildHelper.java",
"rules/java/JavaLibraryHelper.java",
"rules/java/JavaNativeLibraryProvider.java",
"rules/java/JavaOptions.java",
@@ -880,6 +881,7 @@ java_library(
"rules/java/JavaRuntimeInfo.java",
"rules/java/JavaSemantics.java",
"rules/java/JavaSkylarkApiProvider.java",
+ "rules/java/JavaSkylarkCommon.java",
"rules/java/JavaSourceJarsProvider.java",
"rules/java/JavaTargetAttributes.java",
"rules/java/JavaToolchainProvider.java",
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgs.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgs.java
index f9198eee58..1dc527b81f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgs.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgs.java
@@ -22,7 +22,6 @@ 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.util.FileType;
-import java.util.Collection;
/** A container of Java compilation artifacts. */
@AutoValue
@@ -96,6 +95,15 @@ public abstract class JavaCompilationArgs {
private Builder() {
}
+ public static Builder copyOf(Builder builder){
+ Builder result = new Builder();
+ result.addTransitiveRuntimeJars(builder.runtimeJarsBuilder.build());
+ result.addTransitiveCompileTimeJars(builder.compileTimeJarsBuilder.build());
+ result.addTransitiveFullCompileTimeJars(builder.fullCompileTimeJarsBuilder.build());
+ result.addInstrumentationMetadata(builder.instrumentationMetadataBuilder.build());
+ return result;
+ }
+
/**
* Legacy method for dealing with objects which construct
* {@link JavaCompilationArtifacts} objects.
@@ -155,6 +163,11 @@ public abstract class JavaCompilationArgs {
return this;
}
+ public Builder addFullCompileTimeJar(Artifact fullCompileTimeJar) {
+ this.fullCompileTimeJarsBuilder.add(fullCompileTimeJar);
+ return this;
+ }
+
public Builder addTransitiveCompileTimeJars(NestedSet<Artifact> compileTimeJars) {
this.compileTimeJarsBuilder.addTransitive(compileTimeJars);
return this;
@@ -170,7 +183,7 @@ public abstract class JavaCompilationArgs {
return this;
}
- public Builder addInstrumentationMetadata(Collection<Artifact> instrumentationMetadata) {
+ public Builder addInstrumentationMetadata(Iterable<Artifact> instrumentationMetadata) {
this.instrumentationMetadataBuilder.addAll(instrumentationMetadata);
return this;
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfo.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfo.java
index c26679ff51..0f792bb480 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfo.java
@@ -13,28 +13,40 @@
// limitations under the License.
package com.google.devtools.build.lib.rules.java;
+import static com.google.devtools.build.lib.syntax.SkylarkType.BOOL;
+
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.Runfiles;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap;
import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMapBuilder;
+import com.google.devtools.build.lib.analysis.skylark.SkylarkActionFactory;
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.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.NativeInfo;
import com.google.devtools.build.lib.packages.NativeProvider;
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
+import com.google.devtools.build.lib.syntax.EvalException;
+import com.google.devtools.build.lib.syntax.FunctionSignature;
+import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
+import com.google.devtools.build.lib.syntax.SkylarkType;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import javax.annotation.Nullable;
@@ -48,8 +60,82 @@ import javax.annotation.Nullable;
@Immutable
public final class JavaInfo extends NativeInfo {
+ public static final String SKYLARK_NAME = "JavaInfo";
+
+ private static final SkylarkType SEQUENCE_OF_ARTIFACTS =
+ SkylarkType.Combination.of(SkylarkType.SEQUENCE, SkylarkType.of(Artifact.class));
+ private static final SkylarkType SEQUENCE_OF_JAVA_INFO =
+ SkylarkType.Combination.of(SkylarkType.SEQUENCE, SkylarkType.of(JavaInfo.class));
+ private static final SkylarkType LIST_OF_ARTIFACTS =
+ SkylarkType.Combination.of(SkylarkType.SEQUENCE, SkylarkType.of(Artifact.class));
+
+ private static final FunctionSignature.WithValues<Object, SkylarkType> SIGNATURE =
+ FunctionSignature.WithValues.create(
+ FunctionSignature.of(
+ /*numMandatoryPositionals=*/ 0,
+ /*numOptionalPositionals=*/ 0,
+ /*numMandatoryNamedOnly=*/ 1,
+ /*starArg=*/ false,
+ /*kwArg=*/ false,
+ "output_jar",
+ "sources",
+ "source_jars",
+ "use_ijar",
+ "neverlink",
+ "deps",
+ "runtime_deps",
+ "exports",
+ "actions",
+ "java_toolchain"),
+
+ /*defaultValues=*/ Arrays.asList(
+ SkylarkList.createImmutable(Collections.emptyList()), // sources
+ SkylarkList.createImmutable(Collections.emptyList()), // source_jars
+ Boolean.TRUE, // use_ijar
+ Boolean.FALSE, // neverlink
+ SkylarkList.createImmutable(Collections.emptyList()), // deps
+ SkylarkList.createImmutable(Collections.emptyList()), // runtime_deps
+ SkylarkList.createImmutable(Collections.emptyList()), // exports
+ Runtime.NONE, // actions
+ Runtime.NONE), // java_toolchain
+ /*types=*/ ImmutableList.of(
+ SkylarkType.of(Artifact.class), // output_jar
+ SkylarkType.Union.of(SEQUENCE_OF_ARTIFACTS, LIST_OF_ARTIFACTS), // sources
+ SkylarkType.Union.of(SEQUENCE_OF_ARTIFACTS, LIST_OF_ARTIFACTS), // source_jars
+ BOOL, // use_ijar
+ BOOL, // neverlink
+ SEQUENCE_OF_JAVA_INFO, // deps
+ SEQUENCE_OF_JAVA_INFO, // runtime_deps
+ SEQUENCE_OF_JAVA_INFO, // exports
+ SkylarkType.of(SkylarkActionFactory.class), // actions
+ SkylarkType.of(ConfiguredTarget.class))); // java_toolchain
+
public static final NativeProvider<JavaInfo> PROVIDER =
- new NativeProvider<JavaInfo>(JavaInfo.class, "JavaInfo") {};
+ new NativeProvider<JavaInfo>(JavaInfo.class, SKYLARK_NAME, SIGNATURE) {
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected JavaInfo createInstanceFromSkylark(Object[] args, Location loc)
+ throws EvalException {
+
+ JavaInfo javaInfo =
+ JavaInfoBuildHelper.getInstance()
+ .createJavaInfo(
+ (Artifact) args[0],
+ (SkylarkList<Artifact>) args[1],
+ (SkylarkList<Artifact>) args[2],
+ (Boolean) args[3],
+ (Boolean) args[4],
+ (SkylarkList<JavaInfo>) args[5],
+ (SkylarkList<JavaInfo>) args[6],
+ (SkylarkList<JavaInfo>) args[7],
+ args[8],
+ args[9],
+ loc);
+
+ return javaInfo;
+ }
+ };
public static final JavaInfo EMPTY = JavaInfo.Builder.create().build();
@@ -206,8 +292,8 @@ public final class JavaInfo extends NativeInfo {
return providersList.build();
}
- private JavaInfo(TransitiveInfoProviderMap providers, boolean neverlink) {
- super(PROVIDER);
+ private JavaInfo(TransitiveInfoProviderMap providers, boolean neverlink, Location location) {
+ super(PROVIDER, ImmutableMap.of(), location);
this.providers = providers;
this.neverlink = neverlink;
}
@@ -430,6 +516,7 @@ public final class JavaInfo extends NativeInfo {
public static class Builder {
TransitiveInfoProviderMapBuilder providerMap;
private boolean neverlink;
+ private Location location = Location.BUILTIN;
private Builder(TransitiveInfoProviderMapBuilder providerMap) {
this.providerMap = providerMap;
@@ -449,6 +536,11 @@ public final class JavaInfo extends NativeInfo {
return this;
}
+ public Builder setLocation(Location location) {
+ this.location = location;
+ return this;
+ }
+
public <P extends TransitiveInfoProvider> Builder addProvider(
Class<P> providerClass, TransitiveInfoProvider provider) {
Preconditions.checkArgument(ALLOWED_PROVIDERS.contains(providerClass));
@@ -457,7 +549,7 @@ public final class JavaInfo extends NativeInfo {
}
public JavaInfo build() {
- return new JavaInfo(providerMap.build(), neverlink);
+ return new JavaInfo(providerMap.build(), neverlink, location);
}
}
}
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
new file mode 100644
index 0000000000..6cff33a4e1
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfoBuildHelper.java
@@ -0,0 +1,395 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.rules.java;
+
+import static com.google.devtools.build.lib.rules.java.JavaCompilationArgs.ClasspathType.BOTH;
+import static com.google.devtools.build.lib.rules.java.JavaCompilationArgs.ClasspathType.COMPILE_ONLY;
+import static com.google.devtools.build.lib.rules.java.JavaCompilationArgs.ClasspathType.RUNTIME_ONLY;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.FilesToRunProvider;
+import com.google.devtools.build.lib.analysis.Runfiles;
+import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
+import com.google.devtools.build.lib.analysis.actions.SpawnAction;
+import com.google.devtools.build.lib.analysis.actions.SpawnAction.Builder;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration.StrictDepsMode;
+import com.google.devtools.build.lib.analysis.skylark.SkylarkActionFactory;
+import com.google.devtools.build.lib.analysis.skylark.SkylarkRuleContext;
+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.events.Location;
+import com.google.devtools.build.lib.rules.java.JavaCompilationArgs.ClasspathType;
+import com.google.devtools.build.lib.syntax.EvalException;
+import com.google.devtools.build.lib.syntax.SkylarkList;
+import com.google.devtools.build.lib.syntax.SkylarkType;
+import com.google.devtools.build.lib.vfs.FileSystemUtils;
+import java.util.List;
+import javax.annotation.Nullable;
+
+/** Implements logic for creating JavaInfo from different set of input parameters. */
+final class JavaInfoBuildHelper {
+ private static final JavaInfoBuildHelper INSTANCE = new JavaInfoBuildHelper();
+
+ private JavaInfoBuildHelper() {}
+
+ public static JavaInfoBuildHelper getInstance() {
+ return INSTANCE;
+ }
+
+
+ /**
+ * Creates JavaInfo instance from outputJar.
+ *
+ * @param outputJar the jar that was created as a result of
+ * a compilation (e.g. javac, scalac, etc)
+ * @param sourceFiles the sources that were used to create the output jar
+ * @param sourceJars the source jars that were used to create the output jar
+ * @param useIjar if an ijar of the output jar should be created and stored in the provider
+ * @param neverlink if true only use this library for compilation and not at runtime
+ * @param compileTimeDeps compile time dependencies that were used to create the output jar
+ * @param runtimeDeps runtime dependencies that are needed for this library
+ * @param exports libraries to make available for users of this library.
+ * <a href="https://docs.bazel.build/versions/master/be/java.html#java_library"
+ * target="_top">java_library.exports</a>
+ * @param action used to create the ijar and single jar actions
+ * @param javaToolchain the toolchain to be used for retrieving the ijar tool
+ * @return new created JavaInfo instance
+ * @throws EvalException if some mandatory parameter are missing
+ */
+ //todo(b/69780248 gh/3769) only populates JavaInfo with JavaCompilationArgsProvider
+ public JavaInfo createJavaInfo(
+ Artifact outputJar,
+ SkylarkList<Artifact> sourceFiles,
+ SkylarkList<Artifact> sourceJars,
+ Boolean useIjar,
+ Boolean neverlink,
+ SkylarkList<JavaInfo> compileTimeDeps,
+ SkylarkList<JavaInfo> runtimeDeps,
+ SkylarkList<JavaInfo> exports, //todo(b/69780248 gh/3769) handle exports.
+ Object action,
+ Object javaToolchain,
+ Location location)
+ throws EvalException {
+
+ JavaInfo.Builder javaInfoBuilder = JavaInfo.Builder.create();
+ javaInfoBuilder.setLocation(location);
+
+ JavaCompilationArgs.Builder javaCompilationArgsBuilder = JavaCompilationArgs.builder();
+
+ if (useIjar) {
+ SkylarkActionFactory skylarkActionFactory = checkActionType(action, location);
+ ConfiguredTarget configuredTarget = checkConfiguredTargetType(javaToolchain, location);
+ Artifact iJar = buildIjar(outputJar, skylarkActionFactory, configuredTarget);
+ javaCompilationArgsBuilder.addCompileTimeJar(iJar);
+ } else {
+ javaCompilationArgsBuilder.addCompileTimeJar(outputJar);
+ }
+
+ javaCompilationArgsBuilder.addFullCompileTimeJar(outputJar);
+ if (!neverlink) {
+ javaCompilationArgsBuilder.addRuntimeJar(outputJar);
+ }
+
+ JavaCompilationArgs.Builder recursiveJavaCompilationArgsBuilder =
+ JavaCompilationArgs.Builder.copyOf(javaCompilationArgsBuilder);
+
+
+ ClasspathType type = neverlink ? COMPILE_ONLY : BOTH;
+ recursiveJavaCompilationArgsBuilder.addTransitiveArgs(
+ fetchAggregatedRecursiveJavaCompilationArgsFromProvider(compileTimeDeps), type);
+
+ recursiveJavaCompilationArgsBuilder.addTransitiveArgs(
+ fetchAggregatedRecursiveJavaCompilationArgsFromProvider(runtimeDeps), RUNTIME_ONLY);
+
+ javaInfoBuilder.addProvider(
+ JavaCompilationArgsProvider.class,
+ JavaCompilationArgsProvider.create(
+ javaCompilationArgsBuilder.build(), recursiveJavaCompilationArgsBuilder.build()));
+ //todo(b/69780248 gh/3769) add other providers.
+
+ return javaInfoBuilder.build();
+ }
+
+ public JavaInfo create(
+ @Nullable Object actionsUnchecked,
+ NestedSet<Artifact> compileTimeJars,
+ NestedSet<Artifact> runtimeJars,
+ Boolean useIjar,
+ @Nullable Object javaToolchainUnchecked,
+ NestedSet<Artifact> transitiveCompileTimeJars,
+ NestedSet<Artifact> transitiveRuntimeJars,
+ NestedSet<Artifact> sourceJars)
+ throws EvalException {
+
+ JavaCompilationArgs.Builder javaCompilationArgsBuilder = JavaCompilationArgs.builder();
+ if (useIjar && !compileTimeJars.isEmpty()) {
+ javaCompilationArgsBuilder.addFullCompileTimeJars(compileTimeJars);
+ SkylarkActionFactory skylarkActionFactory =
+ checkActionType(actionsUnchecked);
+ ConfiguredTarget configuredTarget =
+ checkConfiguredTargetType(javaToolchainUnchecked);
+ for (Artifact compileJar : compileTimeJars) {
+ javaCompilationArgsBuilder.addCompileTimeJar(
+ buildIjar(compileJar, skylarkActionFactory, configuredTarget));
+ }
+ } else {
+ javaCompilationArgsBuilder.addCompileTimeJars(compileTimeJars);
+ javaCompilationArgsBuilder.addFullCompileTimeJars(compileTimeJars);
+ }
+
+ JavaCompilationArgs javaCompilationArgs =
+ javaCompilationArgsBuilder.addTransitiveRuntimeJars(runtimeJars).build();
+
+ JavaCompilationArgs.Builder recursiveJavaCompilationArgs = JavaCompilationArgs.builder();
+ if (transitiveCompileTimeJars.isEmpty()) {
+ recursiveJavaCompilationArgs.addTransitiveCompileTimeJars(
+ javaCompilationArgs.getCompileTimeJars());
+ recursiveJavaCompilationArgs.addTransitiveFullCompileTimeJars(
+ javaCompilationArgs.getFullCompileTimeJars());
+ } else {
+ recursiveJavaCompilationArgs.addTransitiveCompileTimeJars(transitiveCompileTimeJars);
+ }
+
+ if (transitiveRuntimeJars.isEmpty()) {
+ recursiveJavaCompilationArgs.addTransitiveRuntimeJars(runtimeJars);
+ } else {
+ recursiveJavaCompilationArgs.addTransitiveRuntimeJars(transitiveRuntimeJars);
+ }
+
+ JavaInfo javaInfo =
+ JavaInfo.Builder.create()
+ .addProvider(
+ JavaCompilationArgsProvider.class,
+ JavaCompilationArgsProvider.create(
+ javaCompilationArgs, recursiveJavaCompilationArgs.build()))
+ .addProvider(
+ JavaSourceJarsProvider.class,
+ JavaSourceJarsProvider.create(
+ NestedSetBuilder.emptySet(Order.STABLE_ORDER), sourceJars))
+ .build();
+ return javaInfo;
+ }
+
+ public JavaInfo createJavaCompileAction(
+ SkylarkRuleContext skylarkRuleContext,
+ SkylarkList<Artifact> sourceJars,
+ SkylarkList<Artifact> sourceFiles,
+ Artifact outputJar,
+ SkylarkList<String> javacOpts,
+ SkylarkList<JavaInfo> deps,
+ SkylarkList<JavaInfo> exports,
+ SkylarkList<JavaInfo> plugins,
+ SkylarkList<JavaInfo> exportedPlugins,
+ String strictDepsMode,
+ ConfiguredTarget javaToolchain,
+ ConfiguredTarget hostJavabase,
+ SkylarkList<Artifact> sourcepathEntries,
+ SkylarkList<Artifact> resources,
+ JavaSemantics javaSemantics)
+ throws EvalException, InterruptedException {
+ if (sourceJars.isEmpty() && sourceFiles.isEmpty() && exports.isEmpty()) {
+ throw new EvalException(
+ null, "source_jars, sources and exports cannot be simultaneous empty");
+ }
+
+ if (hostJavabase.get(JavaRuntimeInfo.PROVIDER) == null) {
+ throw new EvalException(null, "'host_javabase' must point to a Java runtime");
+ }
+
+ JavaLibraryHelper helper =
+ new JavaLibraryHelper(skylarkRuleContext.getRuleContext())
+ .setOutput(outputJar)
+ .addSourceJars(sourceJars)
+ .addSourceFiles(sourceFiles)
+ .addResources(resources)
+ .setSourcePathEntries(sourcepathEntries)
+ .setJavacOpts(javacOpts);
+
+ List<JavaCompilationArgsProvider> depsCompilationArgsProviders =
+ JavaInfo.fetchProvidersFromList(deps, JavaCompilationArgsProvider.class);
+ List<JavaCompilationArgsProvider> exportsCompilationArgsProviders =
+ JavaInfo.fetchProvidersFromList(exports, JavaCompilationArgsProvider.class);
+ helper.addAllDeps(depsCompilationArgsProviders);
+ helper.addAllExports(exportsCompilationArgsProviders);
+ helper.setCompilationStrictDepsMode(getStrictDepsMode(strictDepsMode.toUpperCase()));
+
+ helper.addAllPlugins(JavaInfo.fetchProvidersFromList(plugins, JavaPluginInfoProvider.class));
+ helper.addAllPlugins(JavaInfo.fetchProvidersFromList(deps, JavaPluginInfoProvider.class));
+
+ JavaRuleOutputJarsProvider.Builder outputJarsBuilder = JavaRuleOutputJarsProvider.builder();
+
+ boolean generateMergedSourceJar =
+ (sourceJars.size() > 1 || !sourceFiles.isEmpty())
+ || (sourceJars.isEmpty() && sourceFiles.isEmpty() && !exports.isEmpty());
+ Artifact outputSourceJar =
+ generateMergedSourceJar ? getSourceJar(skylarkRuleContext, outputJar) : sourceJars.get(0);
+
+ JavaCompilationArtifacts artifacts =
+ helper.build(
+ javaSemantics,
+ getJavaToolchainProvider(javaToolchain),
+ hostJavabase.get(JavaRuntimeInfo.PROVIDER),
+ SkylarkList.createImmutable(ImmutableList.of()),
+ outputJarsBuilder,
+ /*createOutputSourceJar*/ generateMergedSourceJar,
+ outputSourceJar);
+
+ JavaCompilationArgsProvider javaCompilationArgsProvider =
+ helper.buildCompilationArgsProvider(artifacts, true);
+ Runfiles runfiles =
+ new Runfiles.Builder(skylarkRuleContext.getWorkspaceName())
+ .addTransitiveArtifactsWrappedInStableOrder(
+ javaCompilationArgsProvider.getRecursiveJavaCompilationArgs().getRuntimeJars())
+ .build();
+
+ JavaPluginInfoProvider transitivePluginsProvider =
+ JavaPluginInfoProvider.merge(
+ Iterables.concat(
+ JavaInfo.getProvidersFromListOfJavaProviders(
+ JavaPluginInfoProvider.class, exportedPlugins),
+ JavaInfo.getProvidersFromListOfJavaProviders(
+ JavaPluginInfoProvider.class, exports)));
+
+ ImmutableList<Artifact> outputSourceJars = ImmutableList.of(outputSourceJar);
+
+ NestedSetBuilder<Artifact> transitiveSourceJars =
+ NestedSetBuilder.<Artifact>stableOrder().addAll(outputSourceJars);
+ for (JavaSourceJarsProvider sourceJarsProvider :
+ JavaInfo.getProvidersFromListOfJavaProviders(JavaSourceJarsProvider.class, deps)) {
+ transitiveSourceJars.addTransitive(sourceJarsProvider.getTransitiveSourceJars());
+ }
+
+ return JavaInfo.Builder.create()
+ .addProvider(JavaCompilationArgsProvider.class, javaCompilationArgsProvider)
+ .addProvider(
+ JavaSourceJarsProvider.class,
+ createJavaSourceJarsProvider(outputSourceJars, transitiveSourceJars.build()))
+ .addProvider(JavaRuleOutputJarsProvider.class, outputJarsBuilder.build())
+ .addProvider(JavaRunfilesProvider.class, new JavaRunfilesProvider(runfiles))
+ .addProvider(JavaPluginInfoProvider.class, transitivePluginsProvider)
+ .build();
+ }
+
+ private SkylarkActionFactory checkActionType(Object action) throws EvalException {
+ return checkActionType(action, /*location=*/ null);
+ }
+
+ private SkylarkActionFactory checkActionType(Object action, Location location)
+ throws EvalException {
+ return SkylarkType.cast(
+ action,
+ SkylarkActionFactory.class,
+ location,
+ "The value of use_ijar is True. Make sure the ctx.actions argument is valid.");
+ }
+
+ private ConfiguredTarget checkConfiguredTargetType(Object javaToolchain) throws EvalException {
+ return checkConfiguredTargetType(javaToolchain, /*location=*/ null);
+ }
+
+ private ConfiguredTarget checkConfiguredTargetType(Object javaToolchain, Location location)
+ throws EvalException {
+ return SkylarkType.cast(
+ javaToolchain,
+ ConfiguredTarget.class,
+ location,
+ "The value of use_ijar is True. Make sure the java_toolchain argument is a valid.");
+ }
+
+ private Artifact buildIjar(
+ Artifact inputJar, SkylarkActionFactory actions, ConfiguredTarget javaToolchain)
+ throws EvalException {
+ String ijarBasename = FileSystemUtils.removeExtension(inputJar.getFilename()) + "-ijar.jar";
+ Artifact interfaceJar = actions.declareFile(ijarBasename, inputJar);
+ FilesToRunProvider ijarTarget = getJavaToolchainProvider(javaToolchain).getIjar();
+ SpawnAction.Builder actionBuilder =
+ new Builder()
+ .addInput(inputJar)
+ .addOutput(interfaceJar)
+ .setExecutable(ijarTarget)
+ .setProgressMessage("Extracting interface for jar %s", inputJar.getFilename())
+ .addCommandLine(
+ CustomCommandLine.builder().addExecPath(inputJar).addExecPath(interfaceJar).build())
+ .useDefaultShellEnvironment()
+ .setMnemonic("JavaIjar");
+ actions.registerAction(actionBuilder.build(actions.getActionConstructionContext()));
+ return interfaceJar;
+ }
+
+ JavaToolchainProvider getJavaToolchainProvider(ConfiguredTarget javaToolchain)
+ throws EvalException {
+ JavaToolchainProvider javaToolchainProvider = JavaToolchainProvider.from(javaToolchain);
+ if (javaToolchainProvider == null) {
+ throw new EvalException(
+ null, javaToolchain.getLabel() + " does not provide JavaToolchainProvider.");
+ }
+ return javaToolchainProvider;
+ }
+
+
+ /**
+ * Merge collection of JavaInfos to one. Gets CompilationArgsProvider and call
+ * getRecursiveJavaCompilationArgs on it and return.
+ *
+ * @see JavaInfo#merge(List)
+ */
+ private JavaCompilationArgs fetchAggregatedRecursiveJavaCompilationArgsFromProvider(
+ SkylarkList<JavaInfo> dependencies) {
+
+ JavaInfo aggregatedDependencies = JavaInfo.merge(dependencies);
+ JavaCompilationArgsProvider compilationArgsProvider =
+ aggregatedDependencies.getProvider(JavaCompilationArgsProvider.class);
+ if (compilationArgsProvider == null) {
+ // this should not happen: JavaInfo.merge() always creates JavaCompilationArgsProvider
+ throw new IllegalStateException(
+ "compilationArgsProvider is null. check JavaInfo.merge implementation.");
+ }
+ return compilationArgsProvider.getRecursiveJavaCompilationArgs();
+ }
+
+ private static StrictDepsMode getStrictDepsMode(String strictDepsMode) {
+ switch (strictDepsMode) {
+ case "OFF":
+ return StrictDepsMode.OFF;
+ case "ERROR":
+ case "DEFAULT":
+ return StrictDepsMode.ERROR;
+ case "WARN":
+ return StrictDepsMode.WARN;
+ default:
+ throw new IllegalArgumentException(
+ "StrictDepsMode "
+ + strictDepsMode
+ + " not allowed."
+ + " Only OFF and ERROR values are accepted.");
+ }
+ }
+
+ private static Artifact getSourceJar(SkylarkRuleContext skylarkRuleContext, Artifact outputJar) {
+ return JavaCompilationHelper.derivedArtifact(
+ skylarkRuleContext.getRuleContext(), outputJar, "", "-src.jar");
+ }
+
+ /** Creates a {@link JavaSourceJarsProvider} from the given lists of source jars. */
+ private static JavaSourceJarsProvider createJavaSourceJarsProvider(
+ List<Artifact> sourceJars, NestedSet<Artifact> transitiveSourceJars) {
+ NestedSet<Artifact> javaSourceJars =
+ NestedSetBuilder.<Artifact>stableOrder().addAll(sourceJars).build();
+ return JavaSourceJarsProvider.create(transitiveSourceJars, javaSourceJars);
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
index 2f2e3ab75c..932834b91e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
@@ -19,18 +19,11 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
-import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.analysis.RuleContext;
-import com.google.devtools.build.lib.analysis.Runfiles;
-import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
-import com.google.devtools.build.lib.analysis.actions.SpawnAction;
-import com.google.devtools.build.lib.analysis.actions.SpawnAction.Builder;
-import com.google.devtools.build.lib.analysis.config.BuildConfiguration.StrictDepsMode;
import com.google.devtools.build.lib.analysis.skylark.SkylarkActionFactory;
import com.google.devtools.build.lib.analysis.skylark.SkylarkRuleContext;
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.packages.Provider;
import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.ParamType;
@@ -40,8 +33,6 @@ import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
import com.google.devtools.build.lib.syntax.Type;
-import com.google.devtools.build.lib.vfs.FileSystemUtils;
-import java.util.List;
import javax.annotation.Nullable;
/** A module that contains Skylark utilities for Java support. */
@@ -172,70 +163,17 @@ public class JavaSkylarkCommon {
Object transitiveRuntimeJars,
Object sourceJars)
throws EvalException {
- NestedSet<Artifact> compileTimeJarsNestedSet = asArtifactNestedSet(compileTimeJars);
- NestedSet<Artifact> runtimeJarsNestedSet = asArtifactNestedSet(runtimeJars);
- JavaCompilationArgs.Builder javaCompilationArgsBuilder = JavaCompilationArgs.builder();
- if (useIjar && !compileTimeJarsNestedSet.isEmpty()) {
- if (!(actionsUnchecked instanceof SkylarkActionFactory)) {
- throw new EvalException(null, "In java_common.create_provider the value of use_ijar is "
- + "True. Make sure the first argument of the function is the ctx.actions object.");
- }
- if (!(javaToolchainUnchecked instanceof ConfiguredTarget)) {
- throw new EvalException(null, "In java_common.create_provider the value of use_ijar is "
- + "True. Make sure the java_toolchain argument is a valid java_toolchain Target.");
- }
- SkylarkActionFactory actions = (SkylarkActionFactory) actionsUnchecked;
- ConfiguredTarget javaToolchain = (ConfiguredTarget) javaToolchainUnchecked;
- javaCompilationArgsBuilder.addFullCompileTimeJars(compileTimeJarsNestedSet);
- for (Artifact compileJar : compileTimeJarsNestedSet) {
- javaCompilationArgsBuilder.addCompileTimeJar(
- buildIjar(actions, compileJar, javaToolchain)
- );
- }
- } else {
- javaCompilationArgsBuilder.addCompileTimeJars(compileTimeJarsNestedSet);
- javaCompilationArgsBuilder.addFullCompileTimeJars(compileTimeJarsNestedSet);
- }
-
- JavaCompilationArgs javaCompilationArgs = javaCompilationArgsBuilder
- .addTransitiveRuntimeJars(runtimeJarsNestedSet)
- .build();
-
- NestedSet<Artifact> transitiveCompileTimeJarsNestedSet =
- asArtifactNestedSet(transitiveCompileTimeJars);
- NestedSet<Artifact> transitiveRuntimeJarsNestedSet = asArtifactNestedSet(transitiveRuntimeJars);
-
- JavaCompilationArgs.Builder recursiveJavaCompilationArgs = JavaCompilationArgs.builder();
- if (transitiveCompileTimeJarsNestedSet.isEmpty()) {
- recursiveJavaCompilationArgs
- .addTransitiveCompileTimeJars(javaCompilationArgs.getCompileTimeJars());
- recursiveJavaCompilationArgs
- .addTransitiveFullCompileTimeJars(javaCompilationArgs.getFullCompileTimeJars());
- } else {
- recursiveJavaCompilationArgs
- .addTransitiveCompileTimeJars(transitiveCompileTimeJarsNestedSet);
- }
-
- if (transitiveRuntimeJarsNestedSet.isEmpty()) {
- recursiveJavaCompilationArgs.addTransitiveRuntimeJars(runtimeJarsNestedSet);
- } else {
- recursiveJavaCompilationArgs.addTransitiveRuntimeJars(transitiveRuntimeJarsNestedSet);
- }
-
- JavaInfo javaInfo =
- JavaInfo.Builder.create()
- .addProvider(
- JavaCompilationArgsProvider.class,
- JavaCompilationArgsProvider.create(
- javaCompilationArgs, recursiveJavaCompilationArgs.build()))
- .addProvider(
- JavaSourceJarsProvider.class,
- JavaSourceJarsProvider.create(
- NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER),
- asArtifactNestedSet(sourceJars)))
- .build();
- return javaInfo;
+ return JavaInfoBuildHelper.getInstance()
+ .create(
+ actionsUnchecked,
+ asArtifactNestedSet(compileTimeJars),
+ asArtifactNestedSet(runtimeJars),
+ useIjar,
+ javaToolchainUnchecked,
+ asArtifactNestedSet(transitiveCompileTimeJars),
+ asArtifactNestedSet(transitiveRuntimeJars),
+ asArtifactNestedSet(sourceJars));
}
public JavaSkylarkCommon(JavaSemantics javaSemantics) {
@@ -253,18 +191,6 @@ public class JavaSkylarkCommon {
return JavaInfo.PROVIDER;
}
- /**
- * Takes an Object that is either a SkylarkNestedSet or a SkylarkList of Artifacts and returns it
- * as a NestedSet.
- */
- private static NestedSet<Artifact> asArtifactNestedSet(Object o) throws EvalException {
- return o instanceof SkylarkNestedSet
- ? ((SkylarkNestedSet) o).getSet(Artifact.class)
- : NestedSetBuilder.<Artifact>naiveLinkOrder()
- .addAll(((SkylarkList<?>) o).getContents(Artifact.class, null))
- .build();
- }
-
@SkylarkCallable(
name = "compile",
doc = "Compiles Java source files/jars from the implementation of a Skylark rule and returns a "
@@ -403,121 +329,24 @@ public class JavaSkylarkCommon {
ConfiguredTarget hostJavabase,
SkylarkList<Artifact> sourcepathEntries,
SkylarkList<Artifact> resources) throws EvalException, InterruptedException {
- if (sourceJars.isEmpty() && sourceFiles.isEmpty() && exports.isEmpty()) {
- throw new EvalException(
- null, "source_jars, sources and exports cannot be simultaneous empty");
- }
-
- if (hostJavabase.get(JavaRuntimeInfo.PROVIDER) == null) {
- throw new EvalException(null, "'host_javabase' must point to a Java runtime");
- }
- JavaLibraryHelper helper =
- new JavaLibraryHelper(skylarkRuleContext.getRuleContext())
- .setOutput(outputJar)
- .addSourceJars(sourceJars)
- .addSourceFiles(sourceFiles)
- .addResources(resources)
- .setSourcePathEntries(sourcepathEntries)
- .setJavacOpts(javacOpts);
-
- List<JavaCompilationArgsProvider> depsCompilationArgsProviders =
- JavaInfo.fetchProvidersFromList(deps, JavaCompilationArgsProvider.class);
- List<JavaCompilationArgsProvider> exportsCompilationArgsProviders =
- JavaInfo.fetchProvidersFromList(exports, JavaCompilationArgsProvider.class);
- helper.addAllDeps(depsCompilationArgsProviders);
- helper.addAllExports(exportsCompilationArgsProviders);
- helper.setCompilationStrictDepsMode(getStrictDepsMode(strictDepsMode.toUpperCase()));
-
- helper.addAllPlugins(
- JavaInfo.fetchProvidersFromList(plugins, JavaPluginInfoProvider.class));
- helper.addAllPlugins(JavaInfo.fetchProvidersFromList(deps, JavaPluginInfoProvider.class));
-
- JavaRuleOutputJarsProvider.Builder outputJarsBuilder = JavaRuleOutputJarsProvider.builder();
- boolean generateMergedSourceJar = (sourceJars.size() > 1 || !sourceFiles.isEmpty())
- || (sourceJars.isEmpty() && sourceFiles.isEmpty() && !exports.isEmpty());
- Artifact outputSourceJar =
- generateMergedSourceJar ? getSourceJar(skylarkRuleContext, outputJar) : sourceJars.get(0);
-
- JavaCompilationArtifacts artifacts =
- helper.build(
- javaSemantics,
- getJavaToolchainProvider(javaToolchain),
- hostJavabase.get(JavaRuntimeInfo.PROVIDER),
- SkylarkList.createImmutable(ImmutableList.of()),
- outputJarsBuilder,
- /*createOutputSourceJar*/ generateMergedSourceJar,
- outputSourceJar);
-
- JavaCompilationArgsProvider javaCompilationArgsProvider =
- helper.buildCompilationArgsProvider(artifacts, true);
- Runfiles runfiles =
- new Runfiles.Builder(skylarkRuleContext.getWorkspaceName())
- .addTransitiveArtifactsWrappedInStableOrder(
- javaCompilationArgsProvider.getRecursiveJavaCompilationArgs().getRuntimeJars())
- .build();
-
- JavaPluginInfoProvider transitivePluginsProvider =
- JavaPluginInfoProvider.merge(Iterables.concat(
- JavaInfo.getProvidersFromListOfJavaProviders(
- JavaPluginInfoProvider.class, exportedPlugins),
- JavaInfo.getProvidersFromListOfJavaProviders(
- JavaPluginInfoProvider.class, exports)
- ));
-
- ImmutableList<Artifact> outputSourceJars = ImmutableList.of(outputSourceJar);
-
- NestedSetBuilder<Artifact> transitiveSourceJars =
- NestedSetBuilder.<Artifact>stableOrder().addAll(outputSourceJars);
- for (JavaSourceJarsProvider sourceJarsProvider :
- JavaInfo.getProvidersFromListOfJavaProviders(JavaSourceJarsProvider.class, deps)) {
- transitiveSourceJars.addTransitive(sourceJarsProvider.getTransitiveSourceJars());
- }
-
- return JavaInfo.Builder.create()
- .addProvider(JavaCompilationArgsProvider.class, javaCompilationArgsProvider)
- .addProvider(JavaSourceJarsProvider.class,
- createJavaSourceJarsProvider(outputSourceJars, transitiveSourceJars.build()))
- .addProvider(JavaRuleOutputJarsProvider.class, outputJarsBuilder.build())
- .addProvider(JavaRunfilesProvider.class, new JavaRunfilesProvider(runfiles))
- .addProvider(JavaPluginInfoProvider.class, transitivePluginsProvider)
- .build();
- }
-
- private static Artifact getSourceJar(SkylarkRuleContext skylarkRuleContext, Artifact outputJar) {
- return JavaCompilationHelper.derivedArtifact(
- skylarkRuleContext.getRuleContext(), outputJar, "", "-src.jar");
- }
-
- private static Artifact buildIjar(
- SkylarkActionFactory actions,
- Artifact inputJar,
- ConfiguredTarget javaToolchain) throws EvalException {
- String ijarBasename = FileSystemUtils.removeExtension(inputJar.getFilename()) + "-ijar.jar";
- Artifact interfaceJar = actions.declareFile(ijarBasename, inputJar);
- FilesToRunProvider ijarTarget = getJavaToolchainProvider(javaToolchain).getIjar();
- SpawnAction.Builder actionBuilder = new Builder()
- .addInput(inputJar)
- .addOutput(interfaceJar)
- .setExecutable(ijarTarget)
- .setProgressMessage("Extracting interface for jar %s", inputJar.getFilename())
- .addCommandLine(CustomCommandLine.builder()
- .addExecPath(inputJar)
- .addExecPath(interfaceJar)
- .build())
- .useDefaultShellEnvironment()
- .setMnemonic("JavaIjar");
- actions.registerAction(actionBuilder.build(actions.getActionConstructionContext()));
- return interfaceJar;
- }
- /**
- * Creates a {@link JavaSourceJarsProvider} from the given lists of source jars.
- */
- private static JavaSourceJarsProvider createJavaSourceJarsProvider(
- List<Artifact> sourceJars, NestedSet<Artifact> transitiveSourceJars) {
- NestedSet<Artifact> javaSourceJars =
- NestedSetBuilder.<Artifact>stableOrder().addAll(sourceJars).build();
- return JavaSourceJarsProvider.create(transitiveSourceJars, javaSourceJars);
+ return JavaInfoBuildHelper.getInstance()
+ .createJavaCompileAction(
+ skylarkRuleContext,
+ sourceJars,
+ sourceFiles,
+ outputJar,
+ javacOpts,
+ deps,
+ exports,
+ plugins,
+ exportedPlugins,
+ strictDepsMode,
+ javaToolchain,
+ hostJavabase,
+ sourcepathEntries,
+ resources,
+ javaSemantics);
}
@SkylarkCallable(
@@ -535,7 +364,8 @@ public class JavaSkylarkCommon {
RuleContext ruleContext = skylarkRuleContext.getRuleContext();
ConfiguredTarget javaToolchainConfigTarget =
(ConfiguredTarget) skylarkRuleContext.getAttr().getValue(javaToolchainAttr);
- JavaToolchainProvider toolchain = getJavaToolchainProvider(javaToolchainConfigTarget);
+ JavaToolchainProvider toolchain =
+ JavaInfoBuildHelper.getInstance().getJavaToolchainProvider(javaToolchainConfigTarget);
ImmutableList<String> javacOptsFromAttr;
if (ruleContext.getRule().isAttrDefined("javacopts", Type.STRING_LIST)) {
javacOptsFromAttr = ruleContext.getExpander().withDataLocations().tokenized("javacopts");
@@ -578,16 +408,6 @@ public class JavaSkylarkCommon {
.build();
}
- private static JavaToolchainProvider getJavaToolchainProvider(ConfiguredTarget javaToolchain)
- throws EvalException{
- JavaToolchainProvider javaToolchainProvider =
- JavaToolchainProvider.from(javaToolchain);
- if (javaToolchainProvider == null) {
- throw new EvalException(
- null, javaToolchain.getLabel() + " does not provide JavaToolchainProvider.");
- }
- return javaToolchainProvider;
- }
/**
* Returns a new JavaCompilationArgsProvider whose direct-jars part is the union of both the
@@ -605,24 +425,6 @@ public class JavaSkylarkCommon {
provider.getRunTimeJavaDependencyArtifacts());
}
- private static StrictDepsMode getStrictDepsMode(String strictDepsMode) {
- switch (strictDepsMode) {
- case "OFF":
- return StrictDepsMode.OFF;
- case "ERROR":
- case "DEFAULT":
- return StrictDepsMode.ERROR;
- case "WARN":
- return StrictDepsMode.WARN;
- default:
- throw new IllegalArgumentException(
- "StrictDepsMode "
- + strictDepsMode
- + " not allowed."
- + " Only OFF and ERROR values are accepted.");
- }
- }
-
@SkylarkCallable(
name = JavaRuntimeInfo.SKYLARK_NAME,
doc =
@@ -633,4 +435,16 @@ public class JavaSkylarkCommon {
public static Provider getJavaRuntimeProvider() {
return JavaRuntimeInfo.PROVIDER;
}
+
+ /**
+ * Takes an Object that is either a SkylarkNestedSet or a SkylarkList of Artifacts and returns it
+ * as a NestedSet.
+ */
+ private NestedSet<Artifact> asArtifactNestedSet(Object o) throws EvalException {
+ return o instanceof SkylarkNestedSet
+ ? ((SkylarkNestedSet) o).getSet(Artifact.class)
+ : NestedSetBuilder.<Artifact>naiveLinkOrder()
+ .addAll(((SkylarkList<?>) o).getContents(Artifact.class, /*description=*/ null))
+ .build();
+ }
}
diff --git a/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java b/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java
index 8a15fbe97b..3b9065840a 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java
@@ -22,6 +22,7 @@ import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.packages.Info;
import com.google.devtools.build.lib.packages.SkylarkProvider.SkylarkKey;
@@ -1453,6 +1454,337 @@ public class JavaSkylarkApiTest extends BuildViewTestCase {
assertThat(javaToolchainLabel.toString()).isEqualTo("//java/com/google/test:toolchain");
}
+ @Test
+ public void javaInfoBuildHelperCreateJavaInfoWithOutputJarOnly() throws Exception {
+ scratch.file(
+ "foo/extension.bzl",
+ "result = provider()",
+ "def _impl(ctx):",
+ " javaInfo = JavaInfo(",
+ " output_jar = ctx.file.output_jar, ",
+ " use_ijar = False",
+ " )",
+ " return [result(property = javaInfo)]",
+ "my_rule = rule(",
+ " implementation = _impl,",
+ " attrs = {",
+ " 'dep' : attr.label(), ",
+ " 'output_jar' : attr.label(allow_single_file=True)",
+ " }",
+ ")");
+
+ scratch.file(
+ "foo/BUILD",
+ "load(':extension.bzl', 'my_rule')",
+ "my_rule(",
+ " name = 'my_skylark_rule',",
+ " output_jar = 'my_skylark_rule_lib.jar'",
+ ")");
+ assertNoEvents();
+
+ ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:my_skylark_rule");
+ Info info =
+ myRuleTarget.get(new SkylarkKey(Label.parseAbsolute("//foo:extension.bzl"), "result"));
+
+ @SuppressWarnings("unchecked")
+ JavaInfo javaInfo = (JavaInfo) info.getValue("property");
+
+ JavaCompilationArgsProvider javaCompilationArgsProvider =
+ javaInfo.getProvider(JavaCompilationArgsProvider.class);
+
+
+ assertThat(
+ prettyJarNames(javaCompilationArgsProvider.getJavaCompilationArgs().getRuntimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getJavaCompilationArgs().getFullCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getJavaCompilationArgs().getCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+
+
+
+
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getRecursiveJavaCompilationArgs().getRuntimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider
+ .getRecursiveJavaCompilationArgs()
+ .getFullCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+
+
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getRecursiveJavaCompilationArgs().getCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+ }
+
+ @Test
+ public void javaInfoBuildHelperCreateJavaInfoWithOutputJarAndUseIJar() throws Exception {
+ writeBuildFileForJavaToolchain();
+ scratch.file(
+ "foo/extension.bzl",
+ "result = provider()",
+ "def _impl(ctx):",
+ " javaInfo = JavaInfo(",
+ " output_jar = ctx.file.output_jar,",
+ " use_ijar = True,",
+ " actions = ctx.actions,",
+ " java_toolchain = ctx.attr._java_toolchain",
+ " )",
+ " return [result(property = javaInfo)]",
+ "my_rule = rule(",
+ " implementation = _impl,",
+ " attrs = {",
+ " 'dep' : attr.label(),",
+ " 'output_jar' : attr.label(allow_single_file=True),",
+ " '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
+ " }",
+ ")");
+
+ scratch.file(
+ "foo/BUILD",
+ "load(':extension.bzl', 'my_rule')",
+ "my_rule(",
+ " name = 'my_skylark_rule',",
+ " output_jar = 'my_skylark_rule_lib.jar'",
+ ")");
+ assertNoEvents();
+
+ JavaCompilationArgsProvider javaCompilationArgsProvider =
+ fetchJavaInfo().getProvider(JavaCompilationArgsProvider.class);
+
+ assertThat(
+ prettyJarNames(javaCompilationArgsProvider.getJavaCompilationArgs().getRuntimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getJavaCompilationArgs().getFullCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getJavaCompilationArgs().getCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib-ijar.jar");
+
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getRecursiveJavaCompilationArgs().getRuntimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider
+ .getRecursiveJavaCompilationArgs()
+ .getFullCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getRecursiveJavaCompilationArgs().getCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib-ijar.jar");
+ }
+
+ @Test
+ public void javaInfoBuildHelperCreateJavaInfoWithDeps() throws Exception {
+ scratch.file(
+ "foo/extension.bzl",
+ "result = provider()",
+ "def _impl(ctx):",
+ " dp = [dep[java_common.provider] for dep in ctx.attr.dep]",
+ " javaInfo = JavaInfo(",
+ " output_jar = ctx.file.output_jar,",
+ " use_ijar = False,",
+ " deps = dp",
+ " )",
+ " return [result(property = javaInfo)]",
+ "my_rule = rule(",
+ " implementation = _impl,",
+ " attrs = {",
+ " 'dep' : attr.label_list(), ",
+ " 'output_jar' : attr.label(allow_single_file=True), ",
+ " }",
+ ")");
+
+ scratch.file(
+ "foo/BUILD",
+ "load(':extension.bzl', 'my_rule')",
+ "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
+ "my_rule(name = 'my_skylark_rule',",
+ " output_jar = 'my_skylark_rule_lib.jar',",
+ " dep = [':my_java_lib_direct']",
+ ")");
+ assertNoEvents();
+
+ JavaCompilationArgsProvider javaCompilationArgsProvider =
+ fetchJavaInfo().getProvider(JavaCompilationArgsProvider.class);
+
+ assertThat(
+ prettyJarNames(javaCompilationArgsProvider.getJavaCompilationArgs().getRuntimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getJavaCompilationArgs().getFullCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getJavaCompilationArgs().getCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getRecursiveJavaCompilationArgs().getRuntimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar", "foo/libmy_java_lib_direct.jar");
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider
+ .getRecursiveJavaCompilationArgs()
+ .getFullCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar", "foo/libmy_java_lib_direct.jar");
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getRecursiveJavaCompilationArgs().getCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar", "foo/libmy_java_lib_direct-hjar.jar");
+ }
+
+ @Test
+ public void javaInfoBuildHelperCreateJavaInfoWithRunTimeDeps() throws Exception {
+ scratch.file(
+ "foo/extension.bzl",
+ "result = provider()",
+ "def _impl(ctx):",
+ " dp = [dep[java_common.provider] for dep in ctx.attr.dep]",
+ " javaInfo = JavaInfo(",
+ " output_jar = ctx.file.output_jar,",
+ " use_ijar = False,",
+ " runtime_deps = dp",
+ " )",
+ " return [result(property = javaInfo)]",
+ "my_rule = rule(",
+ " implementation = _impl,",
+ " attrs = {",
+ " 'dep' : attr.label_list(), ",
+ " 'output_jar' : attr.label(allow_single_file=True), ",
+ " }",
+ ")");
+
+ scratch.file(
+ "foo/BUILD",
+ "load(':extension.bzl', 'my_rule')",
+ "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
+ "my_rule(name = 'my_skylark_rule',",
+ " output_jar = 'my_skylark_rule_lib.jar',",
+ " dep = [':my_java_lib_direct']",
+ ")");
+ assertNoEvents();
+
+ JavaCompilationArgsProvider javaCompilationArgsProvider =
+ fetchJavaInfo().getProvider(JavaCompilationArgsProvider.class);
+
+ assertThat(
+ prettyJarNames(javaCompilationArgsProvider.getJavaCompilationArgs().getRuntimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getJavaCompilationArgs().getFullCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getJavaCompilationArgs().getCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getRecursiveJavaCompilationArgs().getRuntimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar", "foo/libmy_java_lib_direct.jar");
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider
+ .getRecursiveJavaCompilationArgs()
+ .getFullCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getRecursiveJavaCompilationArgs().getCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+ }
+
+ @Test
+ public void javaInfoBuildHelperCreateJavaInfoWithDepsAndNeverLink() throws Exception {
+ scratch.file(
+ "foo/extension.bzl",
+ "result = provider()",
+ "def _impl(ctx):",
+ " dp = [dep[java_common.provider] for dep in ctx.attr.dep]",
+ " javaInfo = JavaInfo(",
+ " output_jar = ctx.file.output_jar, ",
+ " use_ijar = False,",
+ " deps = dp,",
+ " neverlink = True",
+ " )",
+ " return [result(property = javaInfo)]",
+ "my_rule = rule(",
+ " implementation = _impl,",
+ " attrs = {",
+ " 'dep' : attr.label_list(), ",
+ " 'output_jar' : attr.label(allow_single_file=True), ",
+ " }",
+ ")");
+
+ scratch.file(
+ "foo/BUILD",
+ "load(':extension.bzl', 'my_rule')",
+ "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
+ "my_rule(name = 'my_skylark_rule',",
+ " output_jar = 'my_skylark_rule_lib.jar',",
+ " dep = [':my_java_lib_direct']",
+ ")");
+ assertNoEvents();
+
+ JavaCompilationArgsProvider javaCompilationArgsProvider =
+ fetchJavaInfo().getProvider(JavaCompilationArgsProvider.class);
+
+ assertThat(
+ prettyJarNames(javaCompilationArgsProvider.getJavaCompilationArgs().getRuntimeJars()))
+ .isEmpty();
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getJavaCompilationArgs().getFullCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getJavaCompilationArgs().getCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar");
+
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getRecursiveJavaCompilationArgs().getRuntimeJars()))
+ .isEmpty();
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider
+ .getRecursiveJavaCompilationArgs()
+ .getFullCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar", "foo/libmy_java_lib_direct.jar");
+ assertThat(
+ prettyJarNames(
+ javaCompilationArgsProvider.getRecursiveJavaCompilationArgs().getCompileTimeJars()))
+ .containsExactly("foo/my_skylark_rule_lib.jar", "foo/libmy_java_lib_direct-hjar.jar");
+ }
+
+ private JavaInfo fetchJavaInfo() throws LabelSyntaxException {
+ ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:my_skylark_rule");
+ Info info =
+ myRuleTarget.get(new SkylarkKey(Label.parseAbsolute("//foo:extension.bzl"), "result"));
+
+ @SuppressWarnings("unchecked")
+ JavaInfo javaInfo = (JavaInfo) info.getValue("property");
+ return javaInfo;
+ }
private void writeBuildFileForJavaToolchain() throws Exception {
scratch.file("java/com/google/test/turbine_canary_deploy.jar");
scratch.file("java/com/google/test/tzdata.jar");
diff --git a/src/test/shell/bazel/bazel_java_test.sh b/src/test/shell/bazel/bazel_java_test.sh
index e19426d36c..d425411da2 100755
--- a/src/test/shell/bazel/bazel_java_test.sh
+++ b/src/test/shell/bazel/bazel_java_test.sh
@@ -1323,6 +1323,7 @@ EOF
expect_log "liba.jar"
}
+
function test_java_common_create_provider_with_ijar_unset_actions() {
mkdir -p java/com/google/foo
touch java/com/google/foo/{BUILD,A.java,my_rule.bzl}
@@ -1355,9 +1356,45 @@ my_rule = rule(
EOF
bazel build java/com/google/foo:banana >& "$TEST_log" && fail "Unexpected success"
- expect_log "In java_common.create_provider the value of use_ijar is True. Make sure the first argument of the function is the ctx.actions object."
+ expect_log "The value of use_ijar is True. Make sure the ctx.actions argument is valid."
+}
+
+
+function test_java_info_constructor_with_ijar_unset_actions() {
+ mkdir -p java/com/google/foo
+ touch java/com/google/foo/{BUILD,my_rule.bzl}
+ cat > java/com/google/foo/BUILD << EOF
+load(":my_rule.bzl", "my_rule")
+my_rule(
+ name = 'my_skylark_rule',
+ output_jar = 'my_skylark_rule_lib.jar'
+ )
+EOF
+
+ cat > java/com/google/foo/my_rule.bzl << EOF
+result = provider()
+def _impl(ctx):
+ javaInfo = JavaInfo(
+ output_jar = ctx.file.output_jar,
+ use_ijar = True,
+ java_toolchain = ctx.attr._java_toolchain
+ )
+ return [result(property = javaInfo)]
+
+my_rule = rule(
+ implementation = _impl,
+ attrs = {
+ 'output_jar' : attr.label(allow_single_file=True),
+ "_java_toolchain": attr.label(default = Label("//tools/jdk:toolchain"))
+ }
+)
+EOF
+
+ bazel build java/com/google/foo:my_skylark_rule >& "$TEST_log" && fail "Unexpected success"
+ expect_log "The value of use_ijar is True. Make sure the ctx.actions argument is valid."
}
+
function test_java_common_create_provider_with_ijar_unset_java_toolchain() {
mkdir -p java/com/google/foo
touch java/com/google/foo/{BUILD,A.java,my_rule.bzl}
@@ -1390,9 +1427,44 @@ my_rule = rule(
EOF
bazel build java/com/google/foo:banana >& "$TEST_log" && fail "Unexpected success"
- expect_log "In java_common.create_provider the value of use_ijar is True. Make sure the java_toolchain argument is a valid java_toolchain Target."
+ expect_log "The value of use_ijar is True. Make sure the java_toolchain argument is a valid."
}
+
+function test_java_info_constructor_with_ijar_unset_java_toolchain() {
+ mkdir -p java/com/google/foo
+ touch java/com/google/foo/{BUILD,my_rule.bzl}
+ cat > java/com/google/foo/BUILD << EOF
+load(":my_rule.bzl", "my_rule")
+my_rule(
+ name = 'my_skylark_rule',
+ output_jar = 'my_skylark_rule_lib.jar'
+ )
+EOF
+
+ cat > java/com/google/foo/my_rule.bzl << EOF
+result = provider()
+def _impl(ctx):
+ javaInfo = JavaInfo(
+ output_jar = ctx.file.output_jar,
+ use_ijar = True,
+ actions = ctx.actions
+ )
+ return [result(property = javaInfo)]
+
+my_rule = rule(
+ implementation = _impl,
+ attrs = {
+ 'output_jar' : attr.label(allow_single_file=True)
+ }
+)
+EOF
+
+ bazel build java/com/google/foo:my_skylark_rule >& "$TEST_log" && fail "Unexpected success"
+ expect_log "The value of use_ijar is True. Make sure the java_toolchain argument is a valid."
+}
+
+
function test_java_test_timeout() {
setup_javatest_support
mkdir -p javatests/com/google/timeout