From 72b1c2cbe1fa28f63a0f25c3bf5c5e1c115a7f6d Mon Sep 17 00:00:00 2001 From: ilist Date: Mon, 22 Mar 2021 05:03:21 -0700 Subject: [PATCH] Improve Java-like rulesets support. JavaInfo constructor (class JavaInfoApi) is extended with parameters compile_jdeps, native_headers, generated_class_jar, generated_source_jar. Class OutputJarApi exposes all the added data and additionally jdeps and manifest_file. Field ijar is renamed to compile_jar (old ijar getter is left in for compatibility). Class JavaRuleOutptJarsProviderApi: outputs.jdeps and outputs.manifest_file is deprecated in favour of fields in JarOutputs. Design document: https://docs.google.com/document/d/10isTEK5W9iCPp4BIyGBrLY5iti3Waaam6EeGVSjq3r8/edit#bookmark=id.vta5s12rfsxt Related issue https://github.com/bazelbuild/bazel/issues/11928 PiperOrigin-RevId: 364291642 --- .../build/lib/rules/android/AarImport.java | 3 +- .../lib/rules/android/AndroidCommon.java | 26 ++- .../rules/android/AndroidLocalTestBase.java | 13 +- .../android/AndroidStarlarkApiProvider.java | 10 +- .../rules/android/AndroidStarlarkData.java | 4 +- .../build/lib/rules/java/JavaBinary.java | 7 +- .../build/lib/rules/java/JavaImport.java | 7 +- .../build/lib/rules/java/JavaInfo.java | 26 ++- .../lib/rules/java/JavaInfoBuildHelper.java | 36 ++- .../build/lib/rules/java/JavaLibrary.java | 16 +- .../lib/rules/java/JavaLibraryHelper.java | 15 +- .../java/JavaRuleOutputJarsProvider.java | 216 ++++++++++++------ .../rules/java/proto/JavaLiteProtoAspect.java | 10 +- .../lib/rules/java/proto/JavaProtoAspect.java | 10 +- .../starlarkbuildapi/java/JavaInfoApi.java | 62 +++++ .../java/JavaRuleOutputJarsProviderApi.java | 12 +- .../starlarkbuildapi/java/OutputJarApi.java | 62 ++++- .../fakebuildapi/java/FakeJavaInfo.java | 5 + .../lib/rules/java/JavaInfoRoundtripTest.java | 79 +++++-- .../rules/java/JavaInfoStarlarkApiTest.java | 183 +++++++++++++-- .../lib/rules/java/JavaStarlarkApiTest.java | 38 +-- 21 files changed, 625 insertions(+), 215 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java b/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java index 32e1bf9c177305..c86640d0f76fab 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java @@ -41,6 +41,7 @@ import com.google.devtools.build.lib.rules.java.JavaConfiguration.ImportDepsCheckingLevel; import com.google.devtools.build.lib.rules.java.JavaInfo; import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider; +import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.OutputJar; import com.google.devtools.build.lib.rules.java.JavaRuntimeInfo; import com.google.devtools.build.lib.rules.java.JavaSemantics; import com.google.devtools.build.lib.rules.java.JavaSourceJarsProvider; @@ -137,7 +138,7 @@ public ConfiguredTarget create(RuleContext ruleContext) JavaRuleOutputJarsProvider.Builder jarProviderBuilder = new JavaRuleOutputJarsProvider.Builder() - .addOutputJar(mergedJar, null /* ijar */, null /* manifestProto */, ImmutableList.of()); + .addOutputJar(OutputJar.builder().setClassJar(mergedJar).build()); ImmutableList targets = ImmutableList.builder() diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java index f1e893a7ebbff0..de2fb4064658d0 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java @@ -651,19 +651,23 @@ public RuleConfiguredTargetBuilder addTransitiveInfoProviders( OutputJar resourceJar = null; if (resourceApk.getResourceJavaClassJar() != null && resourceSourceJar != null) { resourceJar = - new OutputJar( - resourceApk.getResourceJavaClassJar(), - null /* ijar */, - outputs.manifestProto(), - ImmutableList.of(resourceSourceJar)); + OutputJar.builder() + .setClassJar(resourceApk.getResourceJavaClassJar()) + .addSourceJar(resourceSourceJar) + .build(); javaRuleOutputJarsProviderBuilder.addOutputJar(resourceJar); } JavaRuleOutputJarsProvider ruleOutputJarsProvider = javaRuleOutputJarsProviderBuilder - .addOutputJar(classJar, iJar, outputs.manifestProto(), ImmutableList.of(srcJar)) - .setJdeps(outputs.depsProto()) - .setNativeHeaders(outputs.nativeHeader()) + .addOutputJar( + OutputJar.builder() + .fromJavaCompileOutputs(outputs) + .setCompileJar(iJar) + .setCompileJdeps( + javaCommon.getJavaCompilationArtifacts().getCompileTimeDependencyArtifact()) + .addSourceJar(srcJar) + .build()) .build(); JavaSourceJarsProvider sourceJarsProvider = javaSourceJarsProviderBuilder.build(); JavaCompilationArgsProvider compilationArgsProvider = javaCompilationArgs; @@ -879,10 +883,8 @@ static JavaCommon createJavaCommonWithAndroidDataBinding( ImmutableList dataBindingSources = dataBindingContext.getAnnotationSourceFiles(ruleContext); - ImmutableList srcs = ImmutableList.builder() - .addAll(ruleSources) - .addAll(dataBindingSources) - .build(); + ImmutableList srcs = + ImmutableList.builder().addAll(ruleSources).addAll(dataBindingSources).build(); ImmutableList compileDeps; ImmutableList runtimeDeps; diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java index 3e0e9f68672c67..75ac2bae144ee0 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java @@ -53,6 +53,7 @@ import com.google.devtools.build.lib.rules.java.JavaInfo; import com.google.devtools.build.lib.rules.java.JavaPrimaryClassProvider; import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider; +import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.OutputJar; import com.google.devtools.build.lib.rules.java.JavaRuntimeClasspathProvider; import com.google.devtools.build.lib.rules.java.JavaRuntimeInfo; import com.google.devtools.build.lib.rules.java.JavaSemantics; @@ -239,10 +240,13 @@ public ConfiguredTarget create(RuleContext ruleContext) JavaRuleOutputJarsProvider.Builder javaRuleOutputJarsProviderBuilder = JavaRuleOutputJarsProvider.builder() .addOutputJar( - classJar, - classJar, - outputs.manifestProto(), - srcJar == null ? ImmutableList.of() : ImmutableList.of(srcJar)); + OutputJar.builder() + .fromJavaCompileOutputs(outputs) + .setCompileJar(classJar) + .setCompileJdeps( + javaCommon.getJavaCompilationArtifacts().getCompileTimeDependencyArtifact()) + .addSourceJar(srcJar) + .build()); javaArtifactsBuilder.setCompileTimeDependencies(outputs.depsProto()); @@ -261,7 +265,6 @@ public ConfiguredTarget create(RuleContext ruleContext) JavaTargetAttributes attributes = attributesBuilder.build(); addJavaClassJarToArtifactsBuilder(javaArtifactsBuilder, attributes, classJar); - javaRuleOutputJarsProviderBuilder.setJdeps(outputs.depsProto()); helper.createCompileAction(outputs); helper.createSourceJarAction(srcJar, outputs.genSource()); diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidStarlarkApiProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidStarlarkApiProvider.java index ad493dc4d54027..d177bd5f8bdf1a 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidStarlarkApiProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidStarlarkApiProvider.java @@ -14,7 +14,6 @@ package com.google.devtools.build.lib.rules.android; import com.google.common.collect.ImmutableCollection; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.Artifact; @@ -160,11 +159,10 @@ public JavaRuleOutputJarsProvider.OutputJar getIdlOutput() { } Artifact idlSourceJar = getIdeInfoProvider().getIdlSourceJar(); - return new OutputJar( - getIdeInfoProvider().getIdlClassJar(), - null, - null, - idlSourceJar == null ? ImmutableList.of() : ImmutableList.of(idlSourceJar)); + return OutputJar.builder() + .setClassJar(getIdeInfoProvider().getIdlClassJar()) + .addSourceJar(idlSourceJar) + .build(); } } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidStarlarkData.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidStarlarkData.java index 5d5c1edb7fce16..2f6b5afc438c51 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidStarlarkData.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidStarlarkData.java @@ -34,6 +34,7 @@ import com.google.devtools.build.lib.rules.java.JavaCompilationInfoProvider; import com.google.devtools.build.lib.rules.java.JavaInfo; import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider; +import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.OutputJar; import com.google.devtools.build.lib.rules.java.JavaSourceJarsProvider; import com.google.devtools.build.lib.rules.java.ProguardSpecProvider; import com.google.devtools.build.lib.starlarkbuildapi.android.AndroidBinaryDataSettingsApi; @@ -585,7 +586,8 @@ private static JavaInfo getJavaInfoForRClassJar(Artifact rClassJar, Artifact rCl .addProvider( JavaRuleOutputJarsProvider.class, JavaRuleOutputJarsProvider.builder() - .addOutputJar(rClassJar, null, null, ImmutableList.of(rClassSrcJar)) + .addOutputJar( + OutputJar.builder().setClassJar(rClassJar).addSourceJar(rClassSrcJar).build()) .build()) .addProvider( JavaCompilationArgsProvider.class, diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java index 0ce7380f2860cc..fb31e0f155df2f 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java @@ -52,6 +52,7 @@ import com.google.devtools.build.lib.rules.cpp.LibraryToLink; import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider.ClasspathType; import com.google.devtools.build.lib.rules.java.JavaConfiguration.OneVersionEnforcementLevel; +import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.OutputJar; import com.google.devtools.build.lib.rules.java.proto.GeneratedExtensionRegistryProvider; import com.google.devtools.build.lib.util.OS; import com.google.devtools.build.lib.util.Pair; @@ -204,10 +205,7 @@ public ConfiguredTarget create(RuleContext ruleContext) JavaRuleOutputJarsProvider.Builder ruleOutputJarsProviderBuilder = JavaRuleOutputJarsProvider.builder() .addOutputJar( - /* classJar= */ classJar, - /* iJar= */ null, - /* manifestProto= */ outputs.manifestProto(), - /* sourceJars= */ ImmutableList.of(srcJar)); + OutputJar.builder().fromJavaCompileOutputs(outputs).addSourceJar(srcJar).build()); JavaTargetAttributes attributes = attributesBuilder.build(); List nativeLibraries = attributes.getNativeLibraries(); @@ -238,7 +236,6 @@ public ConfiguredTarget create(RuleContext ruleContext) ruleOutputJarsProviderBuilder, javaSourceJarsProviderBuilder); javaArtifactsBuilder.setCompileTimeDependencies(outputs.depsProto()); - ruleOutputJarsProviderBuilder.setJdeps(outputs.depsProto()); JavaCompilationArtifacts javaArtifacts = javaArtifactsBuilder.build(); common.setJavaCompilationArtifacts(javaArtifacts); diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java index 6f5381b0e18cdb..2c6f831900efc7 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java @@ -32,6 +32,7 @@ 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.cpp.LibraryToLink; +import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.OutputJar; import java.util.LinkedHashSet; import java.util.Set; @@ -117,7 +118,11 @@ public ConfiguredTarget create(RuleContext ruleContext) JavaRuleOutputJarsProvider.builder(); for (Artifact jar : jars) { ruleOutputJarsProviderBuilder.addOutputJar( - jar, compilationToRuntimeJarMap.inverse().get(jar), null /* manifestProto */, srcJars); + OutputJar.builder() + .setClassJar(jar) + .setCompileJar(compilationToRuntimeJarMap.inverse().get(jar)) + .addSourceJar(srcJar) + .build()); } NestedSet proguardSpecs = new ProguardLibrary(ruleContext).collectProguardSpecs(); 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 04dc95c6ac1f50..a09f018aa4872d 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 @@ -32,6 +32,7 @@ import com.google.devtools.build.lib.packages.BuiltinProvider; import com.google.devtools.build.lib.packages.NativeInfo; import com.google.devtools.build.lib.rules.java.JavaPluginInfoProvider.JavaPluginInfo; +import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.OutputJar; 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.starlarkbuildapi.FileApi; @@ -424,6 +425,11 @@ public JavaInfo javaInfo( FileApi outputJarApi, Object compileJarApi, Object sourceJarApi, + Object compileJdepsApi, + Object generatedClassJarApi, + Object generatedSourceJarApi, + Object nativeHeadersJarApi, + Object manifestProtoApi, Boolean neverlink, Sequence deps, Sequence runtimeDeps, @@ -434,20 +440,32 @@ public JavaInfo javaInfo( Artifact outputJar = (Artifact) outputJarApi; @Nullable Artifact compileJar = nullIfNone(compileJarApi, Artifact.class); @Nullable Artifact sourceJar = nullIfNone(sourceJarApi, Artifact.class); + @Nullable Artifact compileJdeps = nullIfNone(compileJdepsApi, Artifact.class); + @Nullable Artifact generatedClassJar = nullIfNone(generatedClassJarApi, Artifact.class); + @Nullable Artifact generatedSourceJar = nullIfNone(generatedSourceJarApi, Artifact.class); + @Nullable Artifact nativeHeadersJar = nullIfNone(nativeHeadersJarApi, Artifact.class); + @Nullable Artifact manifestProto = nullIfNone(manifestProtoApi, Artifact.class); @Nullable Artifact jdeps = nullIfNone(jdepsApi, Artifact.class); checkSequenceOfJavaInfo(deps, "deps"); checkSequenceOfJavaInfo(runtimeDeps, "runtime_deps"); checkSequenceOfJavaInfo(exports, "exports"); return JavaInfoBuildHelper.getInstance() .createJavaInfo( - outputJar, - compileJar, - sourceJar, + OutputJar.builder() + .setClassJar(outputJar) + .setCompileJar(compileJar) + .setCompileJdeps(compileJdeps) + .setGeneratedClassJar(generatedClassJar) + .setGeneratedSourceJar(generatedSourceJar) + .setNativeHeadersJar(nativeHeadersJar) + .setManifestProto(manifestProto) + .setJdeps(jdeps) + .addSourceJar(sourceJar) + .build(), neverlink, (Sequence) deps, (Sequence) runtimeDeps, (Sequence) exports, - jdeps, thread.getCallerLocation()); } } 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 9d09420c4ce971..9fa325230ca60b 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 @@ -37,6 +37,7 @@ 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.JavaCompilationArgsProvider.ClasspathType; +import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.OutputJar; import com.google.devtools.build.lib.shell.ShellUtils; import com.google.devtools.build.lib.vfs.FileSystemUtils; import java.util.ArrayList; @@ -62,32 +63,23 @@ public static JavaInfoBuildHelper getInstance() { /** * Creates JavaInfo instance from outputJar. * - * @param outputJar the jar that was created as a result of a compilation (e.g. javac, scalac, - * etc) - * @param compileJar Jar added as a compile-time dependency to other rules. Typically produced by - * ijar. - * @param sourceJar the source jar that was used to create the output jar + * @param outputs the artifacts that were created as a result of a compilation (e.g. javac, + * scalac, etc) * @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. java_library.exports - * @param jdeps optional jdeps information for outputJar * @return new created JavaInfo instance */ JavaInfo createJavaInfo( - Artifact outputJar, - @Nullable Artifact compileJar, - @Nullable Artifact sourceJar, + OutputJar outputs, Boolean neverlink, Sequence compileTimeDeps, Sequence runtimeDeps, Sequence exports, - @Nullable Artifact jdeps, Location location) { - ImmutableList sourceJars = - sourceJar != null ? ImmutableList.of(sourceJar) : ImmutableList.of(); JavaInfo.Builder javaInfoBuilder = JavaInfo.Builder.create(); javaInfoBuilder.setLocation(location); @@ -95,18 +87,15 @@ JavaInfo createJavaInfo( JavaCompilationArgsProvider.builder(); if (!neverlink) { - javaCompilationArgsBuilder.addRuntimeJar(outputJar); + javaCompilationArgsBuilder.addRuntimeJar(outputs.getClassJar()); } - if (compileJar != null) { + if (outputs.getCompileJar() != null) { javaCompilationArgsBuilder.addDirectCompileTimeJar( - /* interfaceJar= */ compileJar, /* fullJar= */ outputJar); + /* interfaceJar= */ outputs.getCompileJar(), /* fullJar= */ outputs.getClassJar()); } JavaRuleOutputJarsProvider javaRuleOutputJarsProvider = - JavaRuleOutputJarsProvider.builder() - .addOutputJar(outputJar, compileJar, null /* manifestProto */, sourceJars) - .setJdeps(jdeps) - .build(); + JavaRuleOutputJarsProvider.builder().addOutputJar(outputs).build(); javaInfoBuilder.addProvider(JavaRuleOutputJarsProvider.class, javaRuleOutputJarsProvider); ClasspathType type = neverlink ? COMPILE_ONLY : BOTH; @@ -130,19 +119,20 @@ JavaInfo createJavaInfo( javaInfoBuilder.addProvider( JavaSourceJarsProvider.class, - createJavaSourceJarsProvider(sourceJars, concat(compileTimeDeps, runtimeDeps, exports))); + createJavaSourceJarsProvider( + outputs.getSourceJars(), concat(compileTimeDeps, runtimeDeps, exports))); javaInfoBuilder.addProvider( JavaGenJarsProvider.class, JavaGenJarsProvider.create( false, - null, - null, + outputs.getGeneratedClassJar(), + outputs.getGeneratedSourceJar(), JavaPluginInfoProvider.empty(), JavaInfo.fetchProvidersFromList( concat(compileTimeDeps, exports), JavaGenJarsProvider.class))); - javaInfoBuilder.setRuntimeJars(ImmutableList.of(outputJar)); + javaInfoBuilder.setRuntimeJars(ImmutableList.of(outputs.getClassJar())); return javaInfoBuilder.build(); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java index 798dbdf34c6a67..693d5e568d9e3d 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java @@ -15,7 +15,6 @@ import static com.google.devtools.build.lib.collect.nestedset.Order.STABLE_ORDER; -import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException; import com.google.devtools.build.lib.analysis.ConfiguredTarget; @@ -29,6 +28,7 @@ import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.rules.cpp.LibraryToLink; import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider.ClasspathType; +import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.OutputJar; import com.google.devtools.build.lib.rules.java.proto.GeneratedExtensionRegistryProvider; /** Implementation for the java_library rule. */ @@ -117,11 +117,17 @@ final ConfiguredTarget init( if (attributes.hasSources() && jar != null) { iJar = helper.createCompileTimeJarAction(jar, javaArtifactsBuilder); } + JavaCompilationArtifacts javaArtifacts = javaArtifactsBuilder.build(); + JavaRuleOutputJarsProvider.Builder ruleOutputJarsProviderBuilder = JavaRuleOutputJarsProvider.builder() - .addOutputJar(classJar, iJar, outputs.manifestProto(), ImmutableList.of(srcJar)) - .setJdeps(outputs.depsProto()) - .setNativeHeaders(outputs.nativeHeader()); + .addOutputJar( + OutputJar.builder() + .fromJavaCompileOutputs(outputs) + .setCompileJar(iJar) + .setCompileJdeps(javaArtifacts.getCompileTimeDependencyArtifact()) + .addSourceJar(srcJar) + .build()); GeneratedExtensionRegistryProvider generatedExtensionRegistryProvider = null; if (includeGeneratedExtensionRegistry) { @@ -136,7 +142,7 @@ final ConfiguredTarget init( } boolean neverLink = JavaCommon.isNeverLink(ruleContext); - JavaCompilationArtifacts javaArtifacts = javaArtifactsBuilder.build(); + common.setJavaCompilationArtifacts(javaArtifacts); common.setClassPathFragment( new ClasspathConfiguredFragment( 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 17b582fd284385..81e8312c466099 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 @@ -265,14 +265,15 @@ public JavaCompilationArtifacts build( if (createOutputSourceJar) { helper.createSourceJarAction(outputSourceJar, outputs.genSource(), javaToolchainProvider); } - ImmutableList outputSourceJars = - outputSourceJar == null ? ImmutableList.of() : ImmutableList.of(outputSourceJar); - outputJarsBuilder - .addOutputJar(new OutputJar(output, iJar, outputs.manifestProto(), outputSourceJars)) - .setJdeps(outputs.depsProto()) - .setNativeHeaders(outputs.nativeHeader()); - JavaCompilationArtifacts javaArtifacts = artifactsBuilder.build(); + outputJarsBuilder.addOutputJar( + OutputJar.builder() + .fromJavaCompileOutputs(outputs) + .setCompileJar(iJar) + .setCompileJdeps(javaArtifacts.getCompileTimeDependencyArtifact()) + .addSourceJar(outputSourceJar) + .build()); + if (javaInfoBuilder != null) { ClasspathConfiguredFragment classpathFragment = new ClasspathConfiguredFragment( diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuleOutputJarsProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuleOutputJarsProvider.java index f37f30aa39b4bc..b5e142f11861ee 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuleOutputJarsProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuleOutputJarsProvider.java @@ -14,9 +14,9 @@ package com.google.devtools.build.lib.rules.java; -import static java.util.Objects.requireNonNull; +import static com.google.common.collect.ImmutableList.toImmutableList; -import com.google.common.base.Preconditions; +import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.Artifact; @@ -27,6 +27,7 @@ import com.google.devtools.build.lib.starlarkbuildapi.java.JavaRuleOutputJarsProviderApi; import com.google.devtools.build.lib.starlarkbuildapi.java.OutputJarApi; import java.util.Collection; +import java.util.Objects; import java.util.stream.Collectors; import javax.annotation.Nullable; import net.starlark.java.eval.Sequence; @@ -39,92 +40,164 @@ public final class JavaRuleOutputJarsProvider implements TransitiveInfoProvider, JavaRuleOutputJarsProviderApi { public static final JavaRuleOutputJarsProvider EMPTY = - new JavaRuleOutputJarsProvider( - ImmutableList.of(), /* jdeps= */ null, /* nativeHeaders= */ null); + new JavaRuleOutputJarsProvider(ImmutableList.of()); /** A collection of artifacts associated with a jar output. */ + @AutoValue @Immutable @AutoCodec - public static class OutputJar implements OutputJarApi { - private final Artifact classJar; - @Nullable private final Artifact iJar; - @Nullable private final Artifact manifestProto; - @Nullable private final ImmutableList srcJars; - - public OutputJar( - Artifact classJar, - @Nullable Artifact iJar, - @Nullable Artifact manifestProto, - @Nullable Iterable srcJars) { - this.classJar = classJar; - this.iJar = iJar; - this.manifestProto = manifestProto; - this.srcJars = ImmutableList.copyOf(srcJars); - } - + public abstract static class OutputJar implements OutputJarApi { @Override public boolean isImmutable() { return true; // immutable and Starlark-hashable } @Override - public Artifact getClassJar() { - return classJar; - } + public abstract Artifact getClassJar(); @Nullable @Override + public abstract Artifact getCompileJar(); + + @Nullable + @Deprecated + @Override public Artifact getIJar() { - return iJar; + return getCompileJar(); } @Nullable @Override - public Artifact getManifestProto() { - return manifestProto; - } + public abstract Artifact getCompileJdeps(); @Nullable @Override + public abstract Artifact getGeneratedClassJar(); + + @Nullable + @Override + public abstract Artifact getGeneratedSourceJar(); + + @Nullable + @Override + public abstract Artifact getNativeHeadersJar(); + + @Nullable + @Override + public abstract Artifact getManifestProto(); + + @Nullable + @Override + public abstract Artifact getJdeps(); + + @Nullable + @Deprecated + @Override public Artifact getSrcJar() { - return Iterables.getOnlyElement(srcJars, null); + return Iterables.getOnlyElement(getSourceJars(), null); } @Nullable @Override public Sequence getSrcJarsStarlark() { - return StarlarkList.immutableCopyOf(srcJars); + return StarlarkList.immutableCopyOf(getSourceJars()); + } + + /** A list of sources archive files. */ + public abstract ImmutableList getSourceJars(); + + @AutoCodec.Instantiator + public static OutputJar create( + Artifact classJar, + @Nullable Artifact compileJar, + @Nullable Artifact compileJdeps, + @Nullable Artifact generatedClassJar, + @Nullable Artifact generatedSourceJar, + @Nullable Artifact nativeHeadersJar, + @Nullable Artifact manifestProto, + @Nullable Artifact jdeps, + ImmutableList sourceJars) { + return builder() + .setClassJar(classJar) + .setCompileJar(compileJar) + .setCompileJdeps(compileJdeps) + .setGeneratedClassJar(generatedClassJar) + .setGeneratedSourceJar(generatedSourceJar) + .setNativeHeadersJar(nativeHeadersJar) + .setManifestProto(manifestProto) + .setJdeps(jdeps) + .addSourceJars(sourceJars) + .build(); } - public Iterable getSrcJars() { - return srcJars; + /** Builder for OutputJar. */ + @AutoValue.Builder + public abstract static class Builder { + + public abstract Builder setClassJar(Artifact value); + + public abstract Builder setCompileJar(Artifact value); + + public abstract Builder setCompileJdeps(Artifact value); + + public abstract Builder setGeneratedClassJar(Artifact value); + + public abstract Builder setGeneratedSourceJar(Artifact value); + + public abstract Builder setNativeHeadersJar(Artifact value); + + public abstract Builder setManifestProto(Artifact value); + + public abstract Builder setJdeps(Artifact value); + + public abstract Builder setSourceJars(Iterable value); + + abstract ImmutableList.Builder sourceJarsBuilder(); + + public Builder addSourceJar(@Nullable Artifact value) { + if (value != null) { + sourceJarsBuilder().add(value); + } + return this; + } + + public Builder addSourceJars(Iterable values) { + sourceJarsBuilder().addAll(values); + return this; + } + + /** Populates the builder with outputs from {@link JavaCompileOutputs}. */ + public Builder fromJavaCompileOutputs(JavaCompileOutputs value) { + setClassJar(value.output()); + setJdeps(value.depsProto()); + setGeneratedClassJar(value.genClass()); + setGeneratedSourceJar(value.genSource()); + setNativeHeadersJar(value.nativeHeader()); + setManifestProto(value.manifestProto()); + return this; + } + + public abstract OutputJar build(); + } + + public static Builder builder() { + return new AutoValue_JavaRuleOutputJarsProvider_OutputJar.Builder(); } } final ImmutableList outputJars; - @Nullable final Artifact jdeps; - /** An archive of native header files. */ - @Nullable final Artifact nativeHeaders; - - private JavaRuleOutputJarsProvider( - ImmutableList outputJars, - @Nullable Artifact jdeps, - @Nullable Artifact nativeHeaders) { + + private JavaRuleOutputJarsProvider(ImmutableList outputJars) { this.outputJars = outputJars; - this.jdeps = jdeps; - this.nativeHeaders = nativeHeaders; } @AutoCodec.VisibleForSerialization @AutoCodec.Instantiator - static JavaRuleOutputJarsProvider create( - ImmutableList outputJars, - @Nullable Artifact jdeps, - @Nullable Artifact nativeHeaders) { - if (outputJars.isEmpty() && jdeps == null && nativeHeaders == null) { + static JavaRuleOutputJarsProvider create(ImmutableList outputJars) { + if (outputJars.isEmpty()) { return EMPTY; } - return new JavaRuleOutputJarsProvider(outputJars, jdeps, nativeHeaders); + return new JavaRuleOutputJarsProvider(outputJars); } @Override @@ -143,22 +216,35 @@ public Iterable getAllClassOutputJars() { } /** Collects all source output jars from {@link #outputJars} */ - public Iterable getAllSrcOutputJars() { + public ImmutableList getAllSrcOutputJars() { return outputJars.stream() - .map(OutputJar::getSrcJars) - .reduce(ImmutableList.of(), Iterables::concat); + .map(OutputJar::getSourceJars) + .flatMap(ImmutableList::stream) + .collect(toImmutableList()); } @Nullable @Override + @Deprecated public Artifact getJdeps() { - return jdeps; + ImmutableList jdeps = + outputJars.stream() + .map(OutputJar::getJdeps) + .filter(Objects::nonNull) + .collect(toImmutableList()); + return jdeps.size() == 1 ? jdeps.get(0) : null; } @Nullable @Override + @Deprecated public Artifact getNativeHeaders() { - return nativeHeaders; + ImmutableList nativeHeaders = + outputJars.stream() + .map(OutputJar::getNativeHeadersJar) + .filter(Objects::nonNull) + .collect(toImmutableList()); + return nativeHeaders.size() == 1 ? nativeHeaders.get(0) : null; } public static Builder builder() { @@ -176,18 +262,6 @@ public static JavaRuleOutputJarsProvider merge(Collection outputJars = ImmutableList.builder(); - private Artifact jdeps; - private Artifact nativeHeaders; - - public Builder addOutputJar( - Artifact classJar, - @Nullable Artifact iJar, - @Nullable Artifact manifestProto, - @Nullable ImmutableList sourceJars) { - Preconditions.checkState(classJar != null); - outputJars.add(new OutputJar(classJar, iJar, manifestProto, sourceJars)); - return this; - } public Builder addOutputJar(OutputJar outputJar) { outputJars.add(outputJar); @@ -199,18 +273,8 @@ public Builder addOutputJars(Iterable outputJars) { return this; } - public Builder setJdeps(Artifact jdeps) { - this.jdeps = jdeps; - return this; - } - - public Builder setNativeHeaders(Artifact nativeHeaders) { - this.nativeHeaders = requireNonNull(nativeHeaders); - return this; - } - public JavaRuleOutputJarsProvider build() { - return new JavaRuleOutputJarsProvider(outputJars.build(), jdeps, nativeHeaders); + return new JavaRuleOutputJarsProvider(outputJars.build()); } } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java index 47eb60fba0f71c..5f35b2bda48c1b 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java @@ -42,6 +42,7 @@ import com.google.devtools.build.lib.rules.java.JavaInfo; import com.google.devtools.build.lib.rules.java.JavaRuleClasses; import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider; +import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.OutputJar; import com.google.devtools.build.lib.rules.java.JavaSemantics; import com.google.devtools.build.lib.rules.java.JavaSourceJarsProvider; import com.google.devtools.build.lib.rules.proto.ProtoCompileActionBuilder; @@ -185,10 +186,11 @@ void addProviders(ConfiguredAspect.Builder aspect) throws InterruptedException { JavaRuleOutputJarsProvider ruleOutputJarsProvider = JavaRuleOutputJarsProvider.builder() .addOutputJar( - outputJar, - compileTimeJar, - null /* manifestProto */, - ImmutableList.of(sourceJar)) + OutputJar.builder() + .setClassJar(outputJar) + .setCompileJar(compileTimeJar) + .addSourceJar(sourceJar) + .build()) .build(); JavaSourceJarsProvider sourceJarsProvider = JavaSourceJarsProvider.create( diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java index 58fed220ddd90c..715feae8bfa0e9 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java @@ -42,6 +42,7 @@ import com.google.devtools.build.lib.rules.java.JavaInfo; import com.google.devtools.build.lib.rules.java.JavaRuleClasses; import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider; +import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.OutputJar; import com.google.devtools.build.lib.rules.java.JavaSemantics; import com.google.devtools.build.lib.rules.java.JavaSourceJarsProvider; import com.google.devtools.build.lib.rules.proto.ProtoCompileActionBuilder; @@ -218,10 +219,11 @@ void addProviders(ConfiguredAspect.Builder aspect) throws InterruptedException { JavaRuleOutputJarsProvider ruleOutputJarsProvider = JavaRuleOutputJarsProvider.builder() .addOutputJar( - outputJar, - compileTimeJar, - null /* manifestProto */, - ImmutableList.of(sourceJar)) + OutputJar.builder() + .setClassJar(outputJar) + .setCompileJar(compileTimeJar) + .addSourceJar(sourceJar) + .build()) .build(); JavaSourceJarsProvider sourceJarsProvider = JavaSourceJarsProvider.create( diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/java/JavaInfoApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/java/JavaInfoApi.java index 1930a97e043f25..4f925359b21203 100644 --- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/java/JavaInfoApi.java +++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/java/JavaInfoApi.java @@ -203,6 +203,63 @@ interface JavaInfoProviderApi extends ProviderApi { "The source jar that was used to create the output jar. " + "Use " + "pack_sources to produce this source jar."), + @Param( + name = "compile_jdeps", + allowedTypes = { + @ParamType(type = FileApi.class), + @ParamType(type = NoneType.class), + }, + named = true, + defaultValue = "None", + doc = + "jdeps information about compile time dependencies to be consumed by" + + " JavaCompileAction. This should be a binary proto encoded using the" + + " deps.proto protobuf included with Bazel. If available this file is" + + " typically produced by a header compiler."), + @Param( + name = "generated_class_jar", + allowedTypes = { + @ParamType(type = FileApi.class), + @ParamType(type = NoneType.class), + }, + named = true, + defaultValue = "None", + doc = + "A jar file containing class files compiled from sources generated during" + + " annotation processing."), + @Param( + name = "generated_source_jar", + allowedTypes = { + @ParamType(type = FileApi.class), + @ParamType(type = NoneType.class), + }, + named = true, + defaultValue = "None", + doc = "The source jar that was created as a result of annotation processing."), + @Param( + name = "native_headers_jar", + allowedTypes = { + @ParamType(type = FileApi.class), + @ParamType(type = NoneType.class), + }, + named = true, + defaultValue = "None", + doc = + "A jar containing CC header files supporting native method implementation" + + " (typically output of javac -h)."), + @Param( + name = "manifest_proto", + allowedTypes = { + @ParamType(type = FileApi.class), + @ParamType(type = NoneType.class), + }, + named = true, + defaultValue = "None", + doc = + "Manifest information for the rule output (if available). This should be a" + + " binary proto encoded using the manifest.proto protobuf included with" + + " Bazel. IDEs and other tools can use this information for more efficient" + + " processing."), @Param( name = "neverlink", named = true, @@ -250,6 +307,11 @@ JavaInfoApi javaInfo( FileApi outputJarApi, Object compileJarApi, Object sourceJarApi, + Object compileJdepsApi, + Object generatedClassJarApi, + Object generatedSourceJarApi, + Object nativeHeadersJarApi, + Object manifestProtoApi, Boolean neverlink, Sequence deps, Sequence runtimeDeps, diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/java/JavaRuleOutputJarsProviderApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/java/JavaRuleOutputJarsProviderApi.java index c7ce584eb25157..3fcb898a56e5b3 100644 --- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/java/JavaRuleOutputJarsProviderApi.java +++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/java/JavaRuleOutputJarsProviderApi.java @@ -35,17 +35,25 @@ public interface JavaRuleOutputJarsProviderApi extends StarlarkValue { @StarlarkMethod(name = "class_jar", doc = "A classes jar file.", structField = true) FileT getClassJar(); + /** @deprecated Use {@link #getCompileJar}. */ @StarlarkMethod( name = "ijar", - doc = "A interface jar file.", + doc = "Deprecated: Please use compile_jar.", allowReturnNones = true, structField = true) + @Deprecated @Nullable FileT getIJar(); + @StarlarkMethod( + name = "compile_jar", + doc = "An interface jar file.", + allowReturnNones = true, + structField = true) + @Nullable + FileT getCompileJar(); + + @StarlarkMethod( + name = "compile_jdeps", + doc = "Compile time dependencies information (deps.proto file).", + allowReturnNones = true, + structField = true) + @Nullable + FileT getCompileJdeps(); + + @StarlarkMethod( + name = "generated_class_jar", + doc = + "A jar file containing class files compiled from sources generated during annotation" + + " processing.", + allowReturnNones = true, + structField = true) + @Nullable + FileT getGeneratedClassJar(); + + @StarlarkMethod( + name = "generated_source_jar", + doc = "The source jar that was created as a result of annotation processing.", + allowReturnNones = true, + structField = true) + @Nullable + FileT getGeneratedSourceJar(); + + @StarlarkMethod( + name = "native_headers_jar", + doc = "A jar containing CC header files supporting native method implementation.", + allowReturnNones = true, + structField = true) + @Nullable + FileT getNativeHeadersJar(); + @StarlarkMethod( name = "manifest_proto", doc = @@ -51,10 +95,18 @@ public interface OutputJarApi extends StarlarkValue { FileT getManifestProto(); @StarlarkMethod( - name = "source_jar", + name = "jdeps", doc = - "A sources archive file. Deprecated. Kept for migration reasons. " - + "Please use source_jars instead.", + "A manifest proto file. The protobuf file containing the manifest generated from " + + "JavaBuilder.", + allowReturnNones = true, + structField = true) + @Nullable + FileT getJdeps(); + + @StarlarkMethod( + name = "source_jar", + doc = "Deprecated: Please use source_jars instead.", allowReturnNones = true, structField = true) @Deprecated diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/java/FakeJavaInfo.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/java/FakeJavaInfo.java index 3e72f020f48464..62a3dfe5d2c04e 100644 --- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/java/FakeJavaInfo.java +++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/java/FakeJavaInfo.java @@ -118,6 +118,11 @@ public JavaInfoApi javaInfo( FileApi outputJarApi, Object compileJarApi, Object sourceJarApi, + Object compileJdepsApi, + Object generatedClassJarApi, + Object generatedSourceJarApi, + Object nativeHeadersJarApi, + Object manifestProtoApi, Boolean neverlink, Sequence deps, Sequence runtimeDeps, diff --git a/src/test/java/com/google/devtools/build/lib/rules/java/JavaInfoRoundtripTest.java b/src/test/java/com/google/devtools/build/lib/rules/java/JavaInfoRoundtripTest.java index dcf9573f58fbfb..dc3b9c936c4b36 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/java/JavaInfoRoundtripTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/java/JavaInfoRoundtripTest.java @@ -64,8 +64,12 @@ public void constructJavaInfo() throws Exception { " 'hjar': 'lib%s-hjar.jar',", " 'src': 'lib%s-src.jar',", " 'compile_jdeps': 'lib%s-hjar.jdeps',", + " 'genclass': 'lib%s-gen.jar',", + " 'gensource': 'lib%s-gensrc.jar',", " 'jdeps': 'lib%s.jdeps',", - " 'manifest': 'lib%s.jar_manifest_proto'}", + " 'manifest': 'lib%s.jar_manifest_proto',", + " 'headers': 'lib%s-native-header.jar',", + " }", " for file, name in OUTS.items():", " OUTS[file] = ctx.actions.declare_file(name % ctx.label.name)", " ctx.actions.write(OUTS[file], '')", @@ -74,6 +78,11 @@ public void constructJavaInfo() throws Exception { " output_jar = OUTS['lib'],", " compile_jar = OUTS['hjar'],", " source_jar = OUTS['src'],", + " compile_jdeps = OUTS['compile_jdeps'],", + " generated_class_jar = ctx.attr.plugins and OUTS['genclass'] or None,", + " generated_source_jar = ctx.attr.plugins and OUTS['gensource'] or None,", + " manifest_proto = OUTS['manifest'],", + " native_headers_jar = OUTS['headers'],", " deps = [d[JavaInfo] for d in ctx.attr.deps],", " runtime_deps = [d[JavaInfo] for d in ctx.attr.runtime_deps],", " exports = [d[JavaInfo] for d in ctx.attr.exports],", @@ -88,6 +97,7 @@ public void constructJavaInfo() throws Exception { " 'deps': attr.label_list(),", " 'runtime_deps': attr.label_list(),", " 'exports': attr.label_list(),", + " 'plugins': attr.bool(default = False),", " },", " fragments = ['java'],", ")"); @@ -117,28 +127,26 @@ private Dict getDictFromJavaInfo(String packageName, String java return javaInfo; } - // TODO(b/163811682): remove once JavaInfo supports setting manifest_proto and native_headers. - private Dict removeManifestAndNativeHeaders(Dict javaInfo) { - @SuppressWarnings("unchecked") // safe by specification - Dict outputs = (Dict) javaInfo.get("outputs"); - @SuppressWarnings("unchecked") // safe by specification - StarlarkList jars = (StarlarkList) outputs.get("jars"); + private Dict removeCompilationInfo(Dict javaInfo) { + return Dict.builder().putAll(javaInfo).put("compilation_info", Starlark.NONE).buildImmutable(); + } + + private Dict removeAnnotationClasses(Dict javaInfo) { @SuppressWarnings("unchecked") // safe by specification - Dict jar0 = (Dict) jars.get(0); + Dict annotationProcessing = + (Dict) javaInfo.get("annotation_processing"); - jar0 = Dict.builder().putAll(jar0).put("manifest_proto", Starlark.NONE).buildImmutable(); - jars = StarlarkList.immutableOf(jar0); - outputs = + annotationProcessing = Dict.builder() - .putAll((Map) javaInfo.get("outputs")) - .put("jars", jars) - .put("native_headers", Starlark.NONE) + .putAll(annotationProcessing) + .put("enabled", false) + .put("processor_classnames", StarlarkList.immutableOf()) + .put("processor_classpath", StarlarkList.immutableOf()) .buildImmutable(); - return Dict.builder().putAll(javaInfo).put("outputs", outputs).buildImmutable(); - } - - private Dict removeCompilationInfo(Dict javaInfo) { - return Dict.builder().putAll(javaInfo).put("compilation_info", Starlark.NONE).buildImmutable(); + return Dict.builder() + .putAll(javaInfo) + .put("annotation_processing", annotationProcessing) + .buildImmutable(); } @Test @@ -173,7 +181,6 @@ public void roundtripJavainfo_srcs() throws Exception { "construct_javainfo(name = 'java_lib', srcs = ['A.java'])"); Dict javaInfoB = getDictFromJavaInfo("foo", "java_lib"); - javaInfoA = removeManifestAndNativeHeaders(javaInfoA); javaInfoA = removeCompilationInfo(javaInfoA); assertThat((Map) javaInfoB).isEqualTo(javaInfoA); } @@ -200,7 +207,6 @@ public void roundtripJavaInfo_deps() throws Exception { ")"); Dict javaInfoB = getDictFromJavaInfo("foo", "java_lib"); - javaInfoA = removeManifestAndNativeHeaders(javaInfoA); javaInfoA = removeCompilationInfo(javaInfoA); assertThat((Map) javaInfoB).isEqualTo(javaInfoA); } @@ -227,7 +233,6 @@ public void roundtipJavaInfo_runtimeDeps() throws Exception { ")"); Dict javaInfoB = getDictFromJavaInfo("foo", "java_lib"); - javaInfoA = removeManifestAndNativeHeaders(javaInfoA); javaInfoA = removeCompilationInfo(javaInfoA); assertThat((Map) javaInfoB).isEqualTo(javaInfoA); } @@ -256,8 +261,36 @@ public void roundtipJavaInfo_exports() throws Exception { ")"); Dict javaInfoB = getDictFromJavaInfo("foo", "java_lib"); - javaInfoA = removeManifestAndNativeHeaders(javaInfoA); javaInfoA = removeCompilationInfo(javaInfoA); assertThat((Map) javaInfoB).isEqualTo(javaInfoA); } + + @Test + public void roundtipJavaInfo_plugin() throws Exception { + scratch.file( + "bar/BUILD", + "java_plugin(name = 'plugin', srcs = ['A.java'], processor_class = 'bar.Main')"); + + scratch.overwriteFile( + "foo/BUILD", + "java_library(", + " name = 'java_lib',", + " srcs = ['A.java'],", + " plugins = ['//bar:plugin']", + ")"); + Dict javaInfoA = getDictFromJavaInfo("foo", "java_lib"); + scratch.overwriteFile( + "foo/BUILD", + "load('//foo:construct_javainfo.bzl', 'construct_javainfo')", + "construct_javainfo(", + " name = 'java_lib', ", + " srcs = ['A.java'], ", + " plugins = True,", + ")"); + Dict javaInfoB = getDictFromJavaInfo("foo", "java_lib"); + + javaInfoA = removeCompilationInfo(javaInfoA); + javaInfoA = removeAnnotationClasses(javaInfoA); + assertThat((Map) javaInfoB).isEqualTo(javaInfoA); + } } 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 1e8a459cee0ae6..1236c502f2d4e9 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 @@ -13,12 +13,12 @@ // limitations under the License. package com.google.devtools.build.lib.rules.java; +import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.truth.Truth.assertThat; import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.prettyArtifactNames; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Streams; 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; @@ -115,7 +115,8 @@ public void buildHelperCreateJavaInfoJavaRuleOutputJarsProviderSourceJarOutputJa assertThat(javaRuleOutputJarsProvider.getOutputJars()).hasSize(1); OutputJar outputJar = javaRuleOutputJarsProvider.getOutputJars().get(0); - assertThat(outputJar.getIJar().prettyPrint()).isEqualTo("foo/my_starlark_rule_lib-ijar.jar"); + assertThat(outputJar.getCompileJar().prettyPrint()) + .isEqualTo("foo/my_starlark_rule_lib-ijar.jar"); } @Test @@ -675,19 +676,158 @@ public void buildHelperCreateJavaInfoWithJdeps_javaRuleOutputJarsProvider() thro JavaRuleOutputJarsProvider ruleOutputs = fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class); + assertThat(prettyArtifactNames(ruleOutputs.getAllClassOutputJars())) + .containsExactly("foo/my_starlark_rule_lib.jar"); + assertThat(prettyArtifactNames(ruleOutputs.getAllSrcOutputJars())) + .containsExactly("foo/my_starlark_rule_src.jar"); assertThat( prettyArtifactNames( ruleOutputs.getOutputJars().stream() - .map(o -> o.getClassJar()) - .collect(ImmutableList.toImmutableList()))) - .containsExactly("foo/my_starlark_rule_lib.jar"); + .map(OutputJar::getJdeps) + .collect(toImmutableList()))) + .containsExactly("foo/my_jdeps.pb"); + } + + @Test + public void buildHelperCreateJavaInfoWithGeneratedJars_javaRuleOutputJarsProvider() + throws Exception { + ruleBuilder().build(); + scratch.file( + "foo/BUILD", + "load(':extension.bzl', 'my_rule')", + "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])", + "my_rule(", + " name = 'my_starlark_rule',", + " output_jar = 'my_starlark_rule_lib.jar',", + " source_jars = ['my_starlark_rule_src.jar'],", + " dep = [':my_java_lib_direct'],", + " generated_class_jar = 'generated_class.jar',", + " generated_source_jar = 'generated_srcs.jar',", + ")"); + assertNoEvents(); + + JavaRuleOutputJarsProvider ruleOutputs = + fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class); + assertThat( prettyArtifactNames( ruleOutputs.getOutputJars().stream() - .flatMap(o -> Streams.stream(o.getSrcJars())) - .collect(ImmutableList.toImmutableList()))) - .containsExactly("foo/my_starlark_rule_src.jar"); - assertThat(ruleOutputs.getJdeps().prettyPrint()).isEqualTo("foo/my_jdeps.pb"); + .map(OutputJar::getGeneratedClassJar) + .collect(toImmutableList()))) + .containsExactly("foo/generated_class.jar"); + assertThat( + prettyArtifactNames( + ruleOutputs.getOutputJars().stream() + .map(OutputJar::getGeneratedSourceJar) + .collect(toImmutableList()))) + .containsExactly("foo/generated_srcs.jar"); + } + + @Test + public void buildHelperCreateJavaInfoWithGeneratedJars_javaGenJarsProvider() throws Exception { + ruleBuilder().build(); + scratch.file( + "foo/BUILD", + "load(':extension.bzl', 'my_rule')", + "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])", + "my_rule(", + " name = 'my_starlark_rule',", + " output_jar = 'my_starlark_rule_lib.jar',", + " source_jars = ['my_starlark_rule_src.jar'],", + " dep = [':my_java_lib_direct'],", + " generated_class_jar = 'generated_class.jar',", + " generated_source_jar = 'generated_srcs.jar',", + ")"); + assertNoEvents(); + + JavaGenJarsProvider ruleOutputs = fetchJavaInfo().getProvider(JavaGenJarsProvider.class); + + assertThat(ruleOutputs.getGenClassJar().prettyPrint()).isEqualTo("foo/generated_class.jar"); + assertThat(ruleOutputs.getGenSourceJar().prettyPrint()).isEqualTo("foo/generated_srcs.jar"); + } + + @Test + public void buildHelperCreateJavaInfoWithCompileJdeps_javaRuleOutputJarsProvider() + throws Exception { + ruleBuilder().build(); + scratch.file( + "foo/BUILD", + "load(':extension.bzl', 'my_rule')", + "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])", + "my_rule(", + " name = 'my_starlark_rule',", + " output_jar = 'my_starlark_rule_lib.jar',", + " source_jars = ['my_starlark_rule_src.jar'],", + " dep = [':my_java_lib_direct'],", + " compile_jdeps = 'compile.deps',", + ")"); + assertNoEvents(); + + JavaRuleOutputJarsProvider ruleOutputs = + fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class); + + assertThat( + prettyArtifactNames( + ruleOutputs.getOutputJars().stream() + .map(OutputJar::getCompileJdeps) + .collect(toImmutableList()))) + .containsExactly("foo/compile.deps"); + } + + @Test + public void buildHelperCreateJavaInfoWithNativeHeaders_javaRuleOutputJarsProvider() + throws Exception { + ruleBuilder().build(); + scratch.file( + "foo/BUILD", + "load(':extension.bzl', 'my_rule')", + "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])", + "my_rule(", + " name = 'my_starlark_rule',", + " output_jar = 'my_starlark_rule_lib.jar',", + " source_jars = ['my_starlark_rule_src.jar'],", + " dep = [':my_java_lib_direct'],", + " native_headers_jar = 'nativeheaders.jar',", + ")"); + assertNoEvents(); + + JavaRuleOutputJarsProvider ruleOutputs = + fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class); + + assertThat( + prettyArtifactNames( + ruleOutputs.getOutputJars().stream() + .map(OutputJar::getNativeHeadersJar) + .collect(toImmutableList()))) + .containsExactly("foo/nativeheaders.jar"); + } + + @Test + public void buildHelperCreateJavaInfoWithManifestProto_javaRuleOutputJarsProvider() + throws Exception { + ruleBuilder().build(); + scratch.file( + "foo/BUILD", + "load(':extension.bzl', 'my_rule')", + "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])", + "my_rule(", + " name = 'my_starlark_rule',", + " output_jar = 'my_starlark_rule_lib.jar',", + " source_jars = ['my_starlark_rule_src.jar'],", + " dep = [':my_java_lib_direct'],", + " manifest_proto = 'manifest.proto',", + ")"); + assertNoEvents(); + + JavaRuleOutputJarsProvider ruleOutputs = + fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class); + + assertThat( + prettyArtifactNames( + ruleOutputs.getOutputJars().stream() + .map(OutputJar::getManifestProto) + .collect(toImmutableList()))) + .containsExactly("foo/manifest.proto"); } private RuleBuilder ruleBuilder() { @@ -723,6 +863,14 @@ private RuleBuilder withSourceFiles() { private String[] newJavaInfo() { assertThat(useIJar && stampJar).isFalse(); ImmutableList.Builder lines = ImmutableList.builder(); + lines.add( + "result = provider()", + "def _impl(ctx):", + " ctx.actions.write(ctx.outputs.output_jar, 'JavaInfo API Test', is_executable=False) ", + " dp = [dep[java_common.provider] for dep in ctx.attr.dep]", + " dp_runtime = [dep[java_common.provider] for dep in ctx.attr.dep_runtime]", + " dp_exports = [dep[java_common.provider] for dep in ctx.attr.dep_exports]"); + if (useIJar) { lines.add( " compile_jar = java_common.run_ijar(", @@ -768,6 +916,11 @@ private String[] newJavaInfo() { " runtime_deps = dp_runtime,", " exports = dp_exports,", " jdeps = ctx.file.jdeps,", + " compile_jdeps = ctx.file.compile_jdeps,", + " generated_class_jar = ctx.file.generated_class_jar,", + " generated_source_jar = ctx.file.generated_source_jar,", + " native_headers_jar = ctx.file.native_headers_jar,", + " manifest_proto = ctx.file.manifest_proto,", " )", " return [result(property = javaInfo)]"); return lines.build().toArray(new String[] {}); @@ -779,13 +932,6 @@ private void build() throws Exception { } ImmutableList.Builder lines = ImmutableList.builder(); - lines.add( - "result = provider()", - "def _impl(ctx):", - " ctx.actions.write(ctx.outputs.output_jar, 'JavaInfo API Test', is_executable=False) ", - " dp = [dep[java_common.provider] for dep in ctx.attr.dep]", - " dp_runtime = [dep[java_common.provider] for dep in ctx.attr.dep_runtime]", - " dp_exports = [dep[java_common.provider] for dep in ctx.attr.dep_exports]"); lines.add(newJavaInfo()); lines.add( "my_rule = rule(", @@ -798,6 +944,11 @@ private void build() throws Exception { " 'source_jars' : attr.label_list(allow_files=['.jar']),", " 'sources' : attr.label_list(allow_files=['.java']),", " 'jdeps' : attr.label(allow_single_file=True),", + " 'compile_jdeps' : attr.label(allow_single_file=True),", + " 'generated_class_jar' : attr.label(allow_single_file=True),", + " 'generated_source_jar' : attr.label(allow_single_file=True),", + " 'native_headers_jar' : attr.label(allow_single_file=True),", + " 'manifest_proto' : attr.label(allow_single_file=True),", useIJar || stampJar || sourceFiles ? " '_toolchain': attr.label(default = Label('//java/com/google/test:toolchain'))," : "", diff --git a/src/test/java/com/google/devtools/build/lib/rules/java/JavaStarlarkApiTest.java b/src/test/java/com/google/devtools/build/lib/rules/java/JavaStarlarkApiTest.java index 9b7e3c2f78603e..8cea4374c7a34b 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/java/JavaStarlarkApiTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/java/JavaStarlarkApiTest.java @@ -289,9 +289,10 @@ public void testExposesJavaCommonProvider() throws Exception { assertThat(outputs.getOutputJars()).hasSize(1); OutputJar output = outputs.getOutputJars().get(0); assertThat(output.getClassJar().getFilename()).isEqualTo("libdep.jar"); - assertThat(output.getIJar().getFilename()).isEqualTo("libdep-hjar.jar"); - assertThat(artifactFilesNames(output.getSrcJars())).containsExactly("libdep-src.jar"); - assertThat(outputs.getJdeps().getFilename()).isEqualTo("libdep.jdeps"); + assertThat(output.getCompileJar().getFilename()).isEqualTo("libdep-hjar.jar"); + assertThat(artifactFilesNames(output.getSourceJars())).containsExactly("libdep-src.jar"); + assertThat(output.getJdeps().getFilename()).isEqualTo("libdep.jdeps"); + assertThat(output.getCompileJdeps().getFilename()).isEqualTo("libdep-hjar.jdeps"); } @Test @@ -400,11 +401,12 @@ public void testJavaCommonCompileExposesOutputJarProvider() throws Exception { OutputJar outputJar = outputs.getOutputJars().get(0); assertThat(outputJar.getClassJar().getFilename()).isEqualTo("libdep.jar"); - assertThat(outputJar.getIJar().getFilename()).isEqualTo("libdep-hjar.jar"); - assertThat(prettyArtifactNames(outputJar.getSrcJars())) + assertThat(outputJar.getCompileJar().getFilename()).isEqualTo("libdep-hjar.jar"); + assertThat(prettyArtifactNames(outputJar.getSourceJars())) .containsExactly("java/test/libdep-src.jar"); - assertThat(outputs.getJdeps().getFilename()).isEqualTo("libdep.jdeps"); - assertThat(outputs.getNativeHeaders().getFilename()).isEqualTo("libdep-native-header.jar"); + assertThat(outputJar.getJdeps().getFilename()).isEqualTo("libdep.jdeps"); + assertThat(outputJar.getNativeHeadersJar().getFilename()).isEqualTo("libdep-native-header.jar"); + assertThat(outputJar.getCompileJdeps().getFilename()).isEqualTo("libdep-hjar.jdeps"); } @Test @@ -768,10 +770,11 @@ public void testJavaCommonCompileWithOnlyOneSourceJar() throws Exception { JavaRuleOutputJarsProvider outputJars = info.getOutputJars(); assertThat(outputJars.getOutputJars()).hasSize(1); OutputJar outputJar = outputJars.getOutputJars().get(0); - assertThat((outputJar.getClassJar().getFilename())).isEqualTo("libcustom.jar"); + assertThat(outputJar.getClassJar().getFilename()).isEqualTo("libcustom.jar"); assertThat(outputJar.getSrcJar().getFilename()).isEqualTo("libcustom-src.jar"); - assertThat((outputJar.getIJar().getFilename())).isEqualTo("libcustom-hjar.jar"); - assertThat(outputJars.getJdeps().getFilename()).isEqualTo("libcustom.jdeps"); + assertThat(outputJar.getCompileJar().getFilename()).isEqualTo("libcustom-hjar.jar"); + assertThat(outputJar.getJdeps().getFilename()).isEqualTo("libcustom.jdeps"); + assertThat(outputJar.getCompileJdeps().getFilename()).isEqualTo("libcustom-hjar.jdeps"); } @Test @@ -869,8 +872,9 @@ public void testJavaCommonCompileCustomSourceJar() throws Exception { OutputJar outputJar = outputJars.getOutputJars().get(0); assertThat(outputJar.getClassJar().getFilename()).isEqualTo("libcustom.jar"); assertThat(outputJar.getSrcJar().getFilename()).isEqualTo("libcustom-mysrc.jar"); - assertThat(outputJar.getIJar().getFilename()).isEqualTo("libcustom-hjar.jar"); - assertThat(outputJars.getJdeps().getFilename()).isEqualTo("libcustom.jdeps"); + assertThat(outputJar.getCompileJar().getFilename()).isEqualTo("libcustom-hjar.jar"); + assertThat(outputJar.getJdeps().getFilename()).isEqualTo("libcustom.jdeps"); + assertThat(outputJar.getCompileJdeps().getFilename()).isEqualTo("libcustom-hjar.jdeps"); } @Test @@ -952,8 +956,10 @@ private void testAnnotationProcessingInfoIsStarlarkAccessible( " depj = ctx.attr.dep[JavaInfo]", " return [result(", " enabled = depj.annotation_processing.enabled,", - " class_jar = depj.annotation_processing.class_jar,", - " source_jar = depj.annotation_processing.source_jar,", + " class_jar = depj.outputs.jars[0].generated_class_jar,", + " source_jar = depj.outputs.jars[0].generated_source_jar,", + " old_class_jar = depj.annotation_processing.class_jar,", + " old_source_jar = depj.annotation_processing.source_jar,", " processor_classpath = depj.annotation_processing.processor_classpath,", " processor_classnames = depj.annotation_processing.processor_classnames,", " transitive_class_jars = depj.annotation_processing.transitive_class_jars,", @@ -1003,6 +1009,8 @@ private void testAnnotationProcessingInfoIsStarlarkAccessible( assertThat(info.getValue("enabled")).isEqualTo(Boolean.TRUE); assertThat(info.getValue("class_jar")).isNotNull(); assertThat(info.getValue("source_jar")).isNotNull(); + assertThat(info.getValue("class_jar")).isEqualTo(info.getValue("old_class_jar")); + assertThat(info.getValue("source_jar")).isEqualTo(info.getValue("old_source_jar")); assertThat((List) info.getValue("processor_classnames")) .containsExactly("com.google.process.stuff"); assertThat( @@ -2111,7 +2119,7 @@ public void testCompileOutputJarNotInRuntimePathWithoutAnySourcesDefined() throw assertThat(outputs.getOutputJars()).hasSize(1); OutputJar output = outputs.getOutputJars().get(0); assertThat(output.getClassJar().getFilename()).isEqualTo("libc.jar"); - assertThat(output.getIJar()).isNull(); + assertThat(output.getCompileJar()).isNull(); } @Test