diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaPluginInfo.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaPluginInfo.java index 653c7a3322beca..8be5b5b8e51dc1 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaPluginInfo.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaPluginInfo.java @@ -102,8 +102,8 @@ public JavaPluginInfo wrap(Info value) throws RuleErrorException { try { StructImpl info = (StructImpl) value; return new AutoValue_JavaPluginInfo( - Sequence.cast(info.getValue("java_outputs"), JavaOutput.class, "java_outputs") - .getImmutableList(), + JavaOutput.wrapSequence( + Sequence.cast(info.getValue("java_outputs"), Object.class, "java_outputs")), JavaPluginData.wrap(info.getValue("plugins")), JavaPluginData.wrap(info.getValue("api_generating_plugins"))); } catch (EvalException e) { diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/java/JavaOutputApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/java/JavaOutputApi.java index 0e39e17d5f843d..4012af2beaa67f 100644 --- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/java/JavaOutputApi.java +++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/java/JavaOutputApi.java @@ -14,20 +14,16 @@ package com.google.devtools.build.lib.starlarkbuildapi.java; -import com.google.devtools.build.docgen.annot.DocCategory; import com.google.devtools.build.lib.starlarkbuildapi.FileApi; +import com.google.devtools.build.lib.starlarkbuildapi.core.StructApi; import javax.annotation.Nullable; -import net.starlark.java.annot.StarlarkBuiltin; import net.starlark.java.annot.StarlarkMethod; +import net.starlark.java.eval.EvalException; +import net.starlark.java.eval.Starlark; import net.starlark.java.eval.StarlarkSemantics; -import net.starlark.java.eval.StarlarkValue; /** A tuple of a java classes jar and its associated source and interface archives. */ -@StarlarkBuiltin( - name = "java_output", - category = DocCategory.BUILTIN, - doc = "The outputs of Java compilation.") -public interface JavaOutputApi extends StarlarkValue { +public interface JavaOutputApi extends StructApi { @StarlarkMethod(name = "class_jar", doc = "A classes jar file.", structField = true) FileT getClassJar(); @@ -121,4 +117,14 @@ public interface JavaOutputApi extends StarlarkValue { structField = true) @Nullable Object getSrcJarsStarlark(StarlarkSemantics semantics); + + @Override + default String toProto() throws EvalException { + throw Starlark.errorf("unsupported method"); + } + + @Override + default String toJson() throws EvalException { + throw Starlark.errorf("unsupported method"); + } } diff --git a/src/test/java/com/google/devtools/build/lib/rules/java/JavaInfoStarlarkApiTest.java b/src/test/java/com/google/devtools/build/lib/rules/java/JavaInfoStarlarkApiTest.java index 2367e83f43b74f..8e3bff1a437c63 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/java/JavaInfoStarlarkApiTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/java/JavaInfoStarlarkApiTest.java @@ -44,6 +44,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.io.IOException; import java.util.Map; +import net.starlark.java.eval.Starlark; import net.starlark.java.eval.StarlarkList; import org.junit.Test; import org.junit.runner.RunWith; @@ -872,6 +873,25 @@ public void buildHelperCreateJavaInfoWithModuleFlags() throws Exception { .containsExactly("--add-opens=java.base/java.lang=ALL-UNNAMED"); } + @Test + public void starlarkJavaOutputsCanBeAddedToJavaPluginInfo() throws Exception { + Artifact classJar = createArtifact("foo.jar"); + StarlarkInfo starlarkJavaOutput = + makeStruct(ImmutableMap.of("source_jars", Starlark.NONE, "class_jar", classJar)); + StarlarkInfo starlarkPluginInfo = + makeStruct( + ImmutableMap.of( + "java_outputs", StarlarkList.immutableOf(starlarkJavaOutput), + "plugins", JavaPluginData.empty(), + "api_generating_plugins", JavaPluginData.empty())); + + JavaPluginInfo pluginInfo = JavaPluginInfo.PROVIDER.wrap(starlarkPluginInfo); + + assertThat(pluginInfo).isNotNull(); + assertThat(pluginInfo.getJavaOutputs()).hasSize(1); + assertThat(pluginInfo.getJavaOutputs().get(0).getClassJar()).isEqualTo(classJar); + } + @Test public void javaOutputSourceJarsReturnsListWithIncompatibleFlagDisabled() throws Exception { setBuildLanguageOptions("--noincompatible_depset_for_java_output_source_jars"); @@ -932,6 +952,39 @@ public void javaOutputSourceJarsReturnsDepsetWithIncompatibleFlagEnabled() throw assertThat(info.getValue("source_jars")).isInstanceOf(Depset.class); } + @Test + public void nativeAndStarlarkJavaOutputsCanBeAddedToADepset() throws Exception { + scratch.file( + "foo/extension.bzl", + "def _impl(ctx):", + " f = ctx.actions.declare_file(ctx.label.name + '.jar')", + " ctx.actions.write(f, '')", + " return [JavaInfo(output_jar=f, compile_jar=None)]", + "", + "my_rule = rule(implementation = _impl)"); + scratch.file( + "foo/BUILD", + // + "load(':extension.bzl', 'my_rule')", + "my_rule(name = 'my_starlark_rule')"); + JavaOutput nativeOutput = + JavaOutput.builder().setClassJar(createArtifact("native.jar")).build(); + StarlarkList starlarkOutputs = + ((StarlarkInfo) + getConfiguredTarget("//foo:my_starlark_rule").get(JavaInfo.PROVIDER.getKey())) + .getValue("java_outputs", StarlarkList.class); + + Depset depset = + Depset.fromDirectAndTransitive( + Order.STABLE_ORDER, + /* direct= */ ImmutableList.builder().add(nativeOutput).addAll(starlarkOutputs).build(), + /* transitive= */ ImmutableList.of(), + /* strict= */ true); + + assertThat(depset).isNotNull(); + assertThat(depset.toList()).hasSize(2); + } + @Test public void translateStarlarkJavaInfo_minimal() throws Exception { ImmutableMap fields = getBuilderWithMandataryFields().buildOrThrow();