diff options
author | cushon <cushon@google.com> | 2018-06-26 11:47:22 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-06-26 11:49:08 -0700 |
commit | 4a2002043ed3907223a403e8b8fc66975e516fd8 (patch) | |
tree | 6bd70399046aec075b1b61369ea60b8b4e9c2a2c /src/main/java/com/google/devtools/build/lib/rules/java | |
parent | dc041d1b5f8934a63df73d9bdd51511915218886 (diff) |
Flatten JavaCompilationAgs into JavaCompilationArgsProvider
Consolidate the creation of JavaCompilationArgsProviders, and avoid explicit
handling of the 'direct' and 'recursive' cases in clients. Also add some
higher-level methods to the builder API to support adding dependencies
with dep/export/runtime_dep-like semantics.
PiperOrigin-RevId: 202166383
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/java')
15 files changed, 414 insertions, 509 deletions
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 7a846c5aaa..e9d9c03789 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 @@ -44,7 +44,7 @@ import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider; import com.google.devtools.build.lib.rules.cpp.CppConfiguration; import com.google.devtools.build.lib.rules.cpp.CppHelper; import com.google.devtools.build.lib.rules.cpp.LinkerInput; -import com.google.devtools.build.lib.rules.java.JavaCompilationArgs.ClasspathType; +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.ProguardHelper.ProguardOutput; import com.google.devtools.build.lib.rules.java.proto.GeneratedExtensionRegistryProvider; diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java index 9557005d4b..1ade2c4c77 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java @@ -50,7 +50,7 @@ import com.google.devtools.build.lib.packages.NativeProvider; import com.google.devtools.build.lib.packages.Target; import com.google.devtools.build.lib.packages.TargetUtils; import com.google.devtools.build.lib.rules.cpp.LinkerInput; -import com.google.devtools.build.lib.rules.java.JavaCompilationArgs.ClasspathType; +import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider.ClasspathType; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.FileTypeSet; import com.google.devtools.build.lib.util.Pair; @@ -111,7 +111,9 @@ public class JavaCommon { private JavaCompilationHelper javaCompilationHelper; public JavaCommon(RuleContext ruleContext, JavaSemantics semantics) { - this(ruleContext, semantics, + this( + ruleContext, + semantics, ruleContext.getPrerequisiteArtifacts("srcs", Mode.TARGET).list(), collectTargetsTreatedAsDeps(ruleContext, semantics, ClasspathType.COMPILE_ONLY), collectTargetsTreatedAsDeps(ruleContext, semantics, ClasspathType.RUNTIME_ONLY), @@ -120,7 +122,9 @@ public class JavaCommon { public JavaCommon(RuleContext ruleContext, JavaSemantics semantics, ImmutableList<Artifact> sources) { - this(ruleContext, semantics, + this( + ruleContext, + semantics, sources, collectTargetsTreatedAsDeps(ruleContext, semantics, ClasspathType.COMPILE_ONLY), collectTargetsTreatedAsDeps(ruleContext, semantics, ClasspathType.RUNTIME_ONLY), @@ -147,10 +151,11 @@ public class JavaCommon { this.javaToolchain = JavaToolchainProvider.from(ruleContext); this.semantics = semantics; this.sources = sources; - this.targetsTreatedAsDeps = ImmutableMap.of( - ClasspathType.COMPILE_ONLY, compileDeps, - ClasspathType.RUNTIME_ONLY, runtimeDeps, - ClasspathType.BOTH, bothDeps); + this.targetsTreatedAsDeps = + ImmutableMap.of( + ClasspathType.COMPILE_ONLY, compileDeps, + ClasspathType.RUNTIME_ONLY, runtimeDeps, + ClasspathType.BOTH, bothDeps); } public JavaSemantics getJavaSemantics() { @@ -242,15 +247,13 @@ public class JavaCommon { /** * Collects Java compilation arguments for this target. * - * @param recursive Whether to scan dependencies recursively. * @param isNeverLink Whether the target has the 'neverlink' attr. * @param srcLessDepsExport If srcs is omitted, deps are exported (deprecated behaviour for * android_library only) */ - public JavaCompilationArgs collectJavaCompilationArgs( - boolean recursive, boolean isNeverLink, boolean srcLessDepsExport) { + public JavaCompilationArgsProvider collectJavaCompilationArgs( + boolean isNeverLink, boolean srcLessDepsExport) { return collectJavaCompilationArgs( - /* recursive= */ recursive, /* isNeverLink= */ isNeverLink, /* srcLessDepsExport= */ srcLessDepsExport, getJavaCompilationArtifacts(), @@ -262,8 +265,7 @@ public class JavaCommon { ImmutableList.of(JavaCompilationArgsProvider.legacyFromTargets(getExports(ruleContext)))); } - static JavaCompilationArgs collectJavaCompilationArgs( - boolean recursive, + static JavaCompilationArgsProvider collectJavaCompilationArgs( boolean isNeverLink, boolean srcLessDepsExport, JavaCompilationArtifacts compilationArtifacts, @@ -271,16 +273,18 @@ public class JavaCommon { List<JavaCompilationArgsProvider> runtimeDeps, List<JavaCompilationArgsProvider> exports) { ClasspathType type = isNeverLink ? ClasspathType.COMPILE_ONLY : ClasspathType.BOTH; - JavaCompilationArgs.Builder builder = - JavaCompilationArgs.builder() - .merge(compilationArtifacts, isNeverLink) - .addTransitiveCompilationArgs(exports, recursive, type); - // TODO(bazel-team): remove srcs-less behaviour after android_library users are refactored - if (recursive || srcLessDepsExport) { - builder - .addTransitiveCompilationArgs(deps, recursive, type) - .addTransitiveCompilationArgs(runtimeDeps, recursive, ClasspathType.RUNTIME_ONLY); + JavaCompilationArgsProvider.Builder builder = + JavaCompilationArgsProvider.builder().merge(compilationArtifacts, isNeverLink); + exports.forEach(export -> builder.addExports(export, type)); + if (srcLessDepsExport) { + deps.forEach(dep -> builder.addExports(dep, type)); + } else { + deps.forEach(dep -> builder.addDeps(dep, type)); } + runtimeDeps.forEach(dep -> builder.addDeps(dep, ClasspathType.RUNTIME_ONLY)); + builder.addCompileTimeJavaDependencyArtifacts( + collectCompileTimeDependencyArtifacts( + compilationArtifacts.getCompileTimeDependencyArtifact(), exports)); return builder.build(); } @@ -303,13 +307,15 @@ public class JavaCommon { * @param exports dependencies with export-like semantics */ public static NestedSet<Artifact> collectCompileTimeDependencyArtifacts( - @Nullable Artifact jdeps, Iterable<JavaCompilationArgsProvider> exports) { + @Nullable Artifact jdeps, Collection<JavaCompilationArgsProvider> exports) { NestedSetBuilder<Artifact> builder = NestedSetBuilder.stableOrder(); if (jdeps != null) { builder.add(jdeps); } - exports.forEach( - export -> builder.addTransitive(export.getCompileTimeJavaDependencyArtifacts())); + exports + .stream() + .map(JavaCompilationArgsProvider::getCompileTimeJavaDependencyArtifacts) + .forEach(builder::addTransitive); return builder.build(); } 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 deleted file mode 100644 index 166d9edb2f..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgs.java +++ /dev/null @@ -1,261 +0,0 @@ -// Copyright 2014 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 com.google.auto.value.AutoValue; -import com.google.devtools.build.lib.actions.Artifact; -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.skyframe.serialization.autocodec.AutoCodec; - -/** A container of Java compilation artifacts. */ -@AutoValue -@AutoCodec -public abstract class JavaCompilationArgs { - // TODO(bazel-team): It would be desirable to use LinkOrderNestedSet here so that - // parents-before-deps is preserved for graphs that are not trees. However, the legacy - // JavaLibraryCollector implemented naive link ordering and many targets in the - // depot depend on the consistency of left-to-right ordering that is not provided by - // LinkOrderNestedSet. They simply list their local dependencies before - // other targets that may use conflicting dependencies, and the local deps - // appear earlier on the classpath, as desired. Behavior of LinkOrderNestedSet - // can be very unintuitive in case of conflicting orders, because the order is - // decided by the rightmost branch in such cases. For example, if A depends on {junit4, - // B}, B depends on {C, D}, C depends on {junit3}, and D depends on {junit4}, - // the classpath of A will have junit3 before junit4. - - @AutoCodec - public static final JavaCompilationArgs EMPTY_ARGS = - JavaCompilationArgs.create( - NestedSetBuilder.<Artifact>create(Order.NAIVE_LINK_ORDER), - NestedSetBuilder.<Artifact>create(Order.NAIVE_LINK_ORDER), - NestedSetBuilder.<Artifact>create(Order.NAIVE_LINK_ORDER), - NestedSetBuilder.<Artifact>create(Order.NAIVE_LINK_ORDER)); - - @AutoCodec.VisibleForSerialization - @AutoCodec.Instantiator - static JavaCompilationArgs create( - NestedSet<Artifact> runtimeJars, - NestedSet<Artifact> compileTimeJars, - NestedSet<Artifact> fullCompileTimeJars, - NestedSet<Artifact> instrumentationMetadata) { - return new AutoValue_JavaCompilationArgs( - runtimeJars, compileTimeJars, fullCompileTimeJars, instrumentationMetadata); - } - - /** Returns transitive runtime jars. */ - public abstract NestedSet<Artifact> getRuntimeJars(); - - /** Returns transitive compile-time jars. */ - public abstract NestedSet<Artifact> getCompileTimeJars(); - - /** - * Returns transitive full jars for compilation time: the full jars for every interface jar and - * all the full jars on the compiletime classpath. - */ - public abstract NestedSet<Artifact> getFullCompileTimeJars(); - - /** Returns transitive instrumentation metadata jars. */ - public abstract NestedSet<Artifact> getInstrumentationMetadata(); - - /** - * Returns a new builder instance. - */ - public static final Builder builder() { - return new Builder(); - } - - /** - * Builder for {@link JavaCompilationArgs}. - */ - public static final class Builder { - private final NestedSetBuilder<Artifact> runtimeJarsBuilder = - NestedSetBuilder.naiveLinkOrder(); - private final NestedSetBuilder<Artifact> compileTimeJarsBuilder = - NestedSetBuilder.naiveLinkOrder(); - private final NestedSetBuilder<Artifact> fullCompileTimeJarsBuilder = - NestedSetBuilder.naiveLinkOrder(); - private final NestedSetBuilder<Artifact> instrumentationMetadataBuilder = - NestedSetBuilder.naiveLinkOrder(); - - /** - * Use {@code TransitiveJavaCompilationArgs#builder()} to instantiate the builder. - */ - 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. - */ - // TODO(bazel-team): Remove when we get rid of JavaCompilationArtifacts. - public Builder merge(JavaCompilationArtifacts other, boolean isNeverLink) { - if (!isNeverLink) { - addRuntimeJars(other.getRuntimeJars()); - } - addCompileTimeJars(other.getCompileTimeJars()); - addFullCompileTimeJars(other.getFullCompileTimeJars()); - addInstrumentationMetadata(other.getInstrumentationMetadata()); - return this; - } - - /** - * Legacy method for dealing with objects which construct - * {@link JavaCompilationArtifacts} objects. - */ - public Builder merge(JavaCompilationArtifacts other) { - return merge(other, false); - } - - public Builder addRuntimeJar(Artifact runtimeJar) { - this.runtimeJarsBuilder.add(runtimeJar); - return this; - } - - public Builder addRuntimeJars(Iterable<Artifact> runtimeJars) { - this.runtimeJarsBuilder.addAll(runtimeJars); - return this; - } - - public Builder addTransitiveRuntimeJars(NestedSet<Artifact> runtimeJars) { - this.runtimeJarsBuilder.addTransitive(runtimeJars); - return this; - } - - public Builder addCompileTimeJarAsFullJar(Artifact compileTimeJar) { - this.compileTimeJarsBuilder.add(compileTimeJar); - this.fullCompileTimeJarsBuilder.add(compileTimeJar); - return this; - } - - public Builder addCompileTimeJars(Iterable<Artifact> compileTimeJars) { - this.compileTimeJarsBuilder.addAll(compileTimeJars); - return this; - } - - public Builder addCompileTimeJar(Artifact compileTimeJar) { - this.compileTimeJarsBuilder.add(compileTimeJar); - return this; - } - - public Builder addFullCompileTimeJars(Iterable<Artifact> fullCompileTimeJars) { - this.fullCompileTimeJarsBuilder.addAll(fullCompileTimeJars); - 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; - } - - public Builder addTransitiveFullCompileTimeJars(NestedSet<Artifact> fullCompileTimeJars) { - this.fullCompileTimeJarsBuilder.addTransitive(fullCompileTimeJars); - return this; - } - - public Builder addInstrumentationMetadata(Artifact instrumentationMetadata) { - this.instrumentationMetadataBuilder.add(instrumentationMetadata); - return this; - } - - public Builder addInstrumentationMetadata(Iterable<Artifact> instrumentationMetadata) { - this.instrumentationMetadataBuilder.addAll(instrumentationMetadata); - return this; - } - - public Builder addTransitiveCompilationArgs( - JavaCompilationArgsProvider dep, boolean recursive, ClasspathType type) { - JavaCompilationArgs args = - recursive ? dep.getRecursiveJavaCompilationArgs() : dep.getJavaCompilationArgs(); - addTransitiveArgs(args, type); - return this; - } - - public Builder addTransitiveCompilationArgs( - Iterable<JavaCompilationArgsProvider> args, boolean recursive, ClasspathType type) { - for (JavaCompilationArgsProvider provider : args) { - addTransitiveCompilationArgs(provider, recursive, type); - } - return this; - } - - /** - * Includes the contents of another instance of {@link JavaCompilationArgs}. - * - * @param args the {@link JavaCompilationArgs} instance - * @param type the classpath(s) to consider - */ - public Builder addTransitiveArgs(JavaCompilationArgs args, ClasspathType type) { - if (!ClasspathType.RUNTIME_ONLY.equals(type)) { - compileTimeJarsBuilder.addTransitive(args.getCompileTimeJars()); - fullCompileTimeJarsBuilder.addTransitive(args.getFullCompileTimeJars()); - } - if (!ClasspathType.COMPILE_ONLY.equals(type)) { - runtimeJarsBuilder.addTransitive(args.getRuntimeJars()); - } - instrumentationMetadataBuilder.addTransitive( - args.getInstrumentationMetadata()); - return this; - } - - /** - * Builds a {@link JavaCompilationArgs} object. - */ - public JavaCompilationArgs build() { - if (runtimeJarsBuilder.isEmpty() - && compileTimeJarsBuilder.isEmpty() - && fullCompileTimeJarsBuilder.isEmpty() - && instrumentationMetadataBuilder.isEmpty()) { - return EMPTY_ARGS; - } - return JavaCompilationArgs.create( - runtimeJarsBuilder.build(), - compileTimeJarsBuilder.build(), - fullCompileTimeJarsBuilder.build(), - instrumentationMetadataBuilder.build()); - } - } - - /** - * Enum to specify transitive compilation args traversal - */ - public static enum ClasspathType { - /* treat the same for compile time and runtime */ - BOTH, - - /* Only include on compile classpath */ - COMPILE_ONLY, - - /* Only include on runtime classpath */ - RUNTIME_ONLY; - } - - JavaCompilationArgs() {} -} diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgsProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgsProvider.java index 45943e5707..5127bbf0ea 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgsProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgsProvider.java @@ -14,8 +14,10 @@ package com.google.devtools.build.lib.rules.java; +import static com.google.common.collect.Iterables.getOnlyElement; + import com.google.auto.value.AutoValue; -import com.google.common.collect.Iterables; +import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.FileProvider; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; @@ -24,92 +26,79 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; -import com.google.devtools.build.lib.rules.java.JavaCompilationArgs.ClasspathType; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.util.FileType; import java.util.Collection; -/** An interface for objects that provide information on how to include them in Java builds. */ +/** A collection of recursively collected Java build information. */ @AutoValue @Immutable @AutoCodec public abstract class JavaCompilationArgsProvider implements TransitiveInfoProvider { + @AutoCodec + public static final JavaCompilationArgsProvider EMPTY = + create( + NestedSetBuilder.create(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.create(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.create(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.create(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.create(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.create(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.create(Order.NAIVE_LINK_ORDER)); + @AutoCodec.Instantiator public static JavaCompilationArgsProvider create( - JavaCompilationArgs javaCompilationArgs, - JavaCompilationArgs recursiveJavaCompilationArgs, + NestedSet<Artifact> runtimeJars, + NestedSet<Artifact> directCompileTimeJars, + NestedSet<Artifact> transitiveCompileTimeJars, + NestedSet<Artifact> directFullCompileTimeJars, + NestedSet<Artifact> transitiveFullCompileTimeJars, + NestedSet<Artifact> instrumentationMetadata, NestedSet<Artifact> compileTimeJavaDependencyArtifacts) { return new AutoValue_JavaCompilationArgsProvider( - javaCompilationArgs, recursiveJavaCompilationArgs, compileTimeJavaDependencyArtifacts); + runtimeJars, + directCompileTimeJars, + transitiveCompileTimeJars, + directFullCompileTimeJars, + transitiveFullCompileTimeJars, + instrumentationMetadata, + compileTimeJavaDependencyArtifacts); } - public static JavaCompilationArgsProvider create( - JavaCompilationArgs javaCompilationArgs, - JavaCompilationArgs recursiveJavaCompilationArgs) { - return create( - javaCompilationArgs, - recursiveJavaCompilationArgs, - NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER)); - } - - /** - * Non-recursively collected Java compilation information, used when Strict Java Deps is enabled - * to implement {@link #getDirectCompileTimeJars}. - * - * @deprecated use {@link #getDirectCompileTimeJars} instead. - */ - @Deprecated - public abstract JavaCompilationArgs getJavaCompilationArgs(); + /** Returns recursively collected runtime jars. */ + public abstract NestedSet<Artifact> getRuntimeJars(); /** - * Returns recursively collected Java compilation information. + * Returns non-recursively collected compile-time jars. This is the set of jars that compilations + * are permitted to reference with Strict Java Deps enabled. * - * @deprecated use one of: {@link #getTransitiveCompileTimeJars}, {@link #getRuntimeJars}, {@link - * #getInstrumentationMetadata} instead. + * <p>If you're reading this, you probably want {@link #getTransitiveCompileTimeJars}. */ - @Deprecated - public abstract JavaCompilationArgs getRecursiveJavaCompilationArgs(); + public abstract NestedSet<Artifact> getDirectCompileTimeJars(); /** - * Returns non-recursively collected compile-time jars. This is the set of jars that compilations - * are permitted to reference with Strict Java Deps enabled. + * Returns recursively collected compile-time jars. This is the compile-time classpath passed to + * the compiler. */ - public NestedSet<Artifact> getDirectCompileTimeJars() { - return getJavaCompilationArgs().getCompileTimeJars(); - } + public abstract NestedSet<Artifact> getTransitiveCompileTimeJars(); /** * Returns non-recursively collected, non-interface compile-time jars. * * <p>If you're reading this, you probably want {@link #getTransitiveCompileTimeJars}. */ - public NestedSet<Artifact> getFullCompileTimeJars() { - return getJavaCompilationArgs().getFullCompileTimeJars(); - } + public abstract NestedSet<Artifact> getDirectFullCompileTimeJars(); /** - * Returns recursively collected compile-time jars. This is the compile-time classpath passed to - * the compiler. + * Returns recursively collected, non-interface compile-time jars. + * + * <p>If you're reading this, you probably want {@link #getTransitiveCompileTimeJars}. */ - public NestedSet<Artifact> getTransitiveCompileTimeJars() { - return getRecursiveJavaCompilationArgs().getCompileTimeJars(); - } - - /** Returns recursively collected, non-interface compile-time jars. */ - public NestedSet<Artifact> getFullTransitiveCompileTimeJars() { - return getRecursiveJavaCompilationArgs().getFullCompileTimeJars(); - } - - /** Returns recursively collected runtime jars. */ - public NestedSet<Artifact> getRuntimeJars() { - return getRecursiveJavaCompilationArgs().getRuntimeJars(); - } + public abstract NestedSet<Artifact> getTransitiveFullCompileTimeJars(); /** Returns recursively collected instrumentation metadata. */ - public NestedSet<Artifact> getInstrumentationMetadata() { - return getRecursiveJavaCompilationArgs().getInstrumentationMetadata(); - } + public abstract NestedSet<Artifact> getInstrumentationMetadata(); /** * Returns non-recursively collected Java dependency artifacts for @@ -123,30 +112,6 @@ public abstract class JavaCompilationArgsProvider implements TransitiveInfoProvi */ public abstract NestedSet<Artifact> getCompileTimeJavaDependencyArtifacts(); - public static JavaCompilationArgsProvider merge( - Collection<JavaCompilationArgsProvider> providers) { - if (providers.size() == 1) { - return Iterables.get(providers, 0); - } - - JavaCompilationArgs.Builder javaCompilationArgs = JavaCompilationArgs.builder(); - JavaCompilationArgs.Builder recursiveJavaCompilationArgs = JavaCompilationArgs.builder(); - NestedSetBuilder<Artifact> compileTimeJavaDepArtifacts = NestedSetBuilder.stableOrder(); - - for (JavaCompilationArgsProvider provider : providers) { - javaCompilationArgs.addTransitiveArgs( - provider.getJavaCompilationArgs(), JavaCompilationArgs.ClasspathType.BOTH); - recursiveJavaCompilationArgs.addTransitiveArgs( - provider.getRecursiveJavaCompilationArgs(), JavaCompilationArgs.ClasspathType.BOTH); - compileTimeJavaDepArtifacts.addTransitive(provider.getCompileTimeJavaDependencyArtifacts()); - } - - return JavaCompilationArgsProvider.create( - javaCompilationArgs.build(), - recursiveJavaCompilationArgs.build(), - compileTimeJavaDepArtifacts.build()); - } - /** * Returns a {@link JavaCompilationArgsProvider} for the given {@link TransitiveInfoCollection}s. * @@ -164,23 +129,270 @@ public abstract class JavaCompilationArgsProvider implements TransitiveInfoProvi @Deprecated public static JavaCompilationArgsProvider legacyFromTargets( Iterable<? extends TransitiveInfoCollection> infos) { - JavaCompilationArgs.Builder argsBuilder = JavaCompilationArgs.builder(); - JavaCompilationArgs.Builder recursiveArgsBuilder = JavaCompilationArgs.builder(); + Builder argsBuilder = builder(); for (TransitiveInfoCollection info : infos) { JavaCompilationArgsProvider provider = JavaInfo.getProvider(JavaCompilationArgsProvider.class, info); if (provider != null) { - argsBuilder.addTransitiveArgs(provider.getJavaCompilationArgs(), ClasspathType.BOTH); - recursiveArgsBuilder.addTransitiveArgs( - provider.getRecursiveJavaCompilationArgs(), ClasspathType.BOTH); + argsBuilder.addExports(provider); } else { NestedSet<Artifact> filesToBuild = info.getProvider(FileProvider.class).getFilesToBuild(); for (Artifact jar : FileType.filter(filesToBuild, JavaSemantics.JAR)) { - argsBuilder.addRuntimeJar(jar).addCompileTimeJarAsFullJar(jar); - recursiveArgsBuilder.addRuntimeJar(jar).addCompileTimeJarAsFullJar(jar); + argsBuilder + .addRuntimeJar(jar) + .addDirectCompileTimeJar(/* interfaceJar= */ jar, /* fullJar= */ jar); + } + } + } + return argsBuilder.build(); + } + + /** Enum to specify transitive compilation args traversal */ + public enum ClasspathType { + /* treat the same for compile time and runtime */ + BOTH, + + /* Only include on compile classpath */ + COMPILE_ONLY, + + /* Only include on runtime classpath */ + RUNTIME_ONLY + } + + /** + * Disable strict deps enforcement for the given {@link JavaCompilationArgsProvider}; the direct + * jars in the result include the full transitive compile-time classpath from the input. + */ + public static JavaCompilationArgsProvider makeNonStrict(JavaCompilationArgsProvider args) { + // Omit jdeps, which aren't available transitively and aren't useful for reduced classpath + // pruning for non-strict targets: the direct classpath and transitive classpath are the same, + // so there's nothing to prune, and reading jdeps at compile-time isn't free. + return builder() + .addDirectCompileTimeJars( + /* interfaceJars= */ args.getTransitiveCompileTimeJars(), + /* fullJars= */ args.getTransitiveFullCompileTimeJars()) + .addInstrumentationMetadata(args.getInstrumentationMetadata()) + .addRuntimeJars(args.getRuntimeJars()) + .build(); + } + + /** + * Returns a {@link JavaCompilationArgsProvider} that forwards the union of information from the + * inputs. Direct deps of the inputs are merged into the direct deps of the outputs. + * + * <p>This is moralley equivalent to an exports-only {@code java_import} rule that forwards some + * dependencies. + */ + public static JavaCompilationArgsProvider merge( + Collection<JavaCompilationArgsProvider> providers) { + if (providers.size() == 1) { + return getOnlyElement(providers); + } + Builder javaCompilationArgs = builder(); + for (JavaCompilationArgsProvider provider : providers) { + javaCompilationArgs.addExports(provider); + } + return javaCompilationArgs.build(); + } + + /** + * Returns a {@link JavaCompilationArgsProvider} that forwards the union of information from the + * inputs, see {@link #merge(Collection<JavaCompilationArgsProvider>)}. + */ + public static JavaCompilationArgsProvider merge(JavaCompilationArgsProvider... providers) { + return merge(ImmutableList.copyOf(providers)); + } + + /** Returns a new builder instance. */ + public static final Builder builder() { + return new Builder(); + } + + /** A {@link JavaCompilationArgsProvider}Builder. */ + public static final class Builder { + private final NestedSetBuilder<Artifact> runtimeJarsBuilder = NestedSetBuilder.naiveLinkOrder(); + private final NestedSetBuilder<Artifact> directCompileTimeJarsBuilder = + NestedSetBuilder.naiveLinkOrder(); + private final NestedSetBuilder<Artifact> transitiveCompileTimeJarsBuilder = + NestedSetBuilder.naiveLinkOrder(); + private final NestedSetBuilder<Artifact> directFullCompileTimeJarsBuilder = + NestedSetBuilder.naiveLinkOrder(); + private final NestedSetBuilder<Artifact> transitiveFullCompileTimeJarsBuilder = + NestedSetBuilder.naiveLinkOrder(); + private final NestedSetBuilder<Artifact> instrumentationMetadataBuilder = + NestedSetBuilder.naiveLinkOrder(); + private final NestedSetBuilder<Artifact> compileTimeJavaDependencyArtifactsBuilder = + NestedSetBuilder.naiveLinkOrder(); + + /** Use {@code TransitiveJavaCompilationArgs#builder()} to instantiate the builder. */ + private Builder() {} + + /** + * Legacy method for dealing with objects which construct {@link JavaCompilationArtifacts} + * objects. + */ + // TODO(bazel-team): Remove when we get rid of JavaCompilationArtifacts. + public Builder merge(JavaCompilationArtifacts other, boolean isNeverLink) { + if (!isNeverLink) { + addRuntimeJars(NestedSetBuilder.wrap(Order.NAIVE_LINK_ORDER, other.getRuntimeJars())); + } + addDirectCompileTimeJars( + /* interfaceJars= */ NestedSetBuilder.wrap( + Order.NAIVE_LINK_ORDER, other.getCompileTimeJars()), + /* fullJars= */ NestedSetBuilder.wrap( + Order.NAIVE_LINK_ORDER, other.getFullCompileTimeJars())); + addInstrumentationMetadata( + NestedSetBuilder.wrap(Order.NAIVE_LINK_ORDER, other.getInstrumentationMetadata())); + return this; + } + + /** + * Legacy method for dealing with objects which construct {@link JavaCompilationArtifacts} + * objects. + */ + public Builder merge(JavaCompilationArtifacts other) { + return merge(other, /* isNeverLink= */ false); + } + + public Builder addRuntimeJar(Artifact runtimeJar) { + this.runtimeJarsBuilder.add(runtimeJar); + return this; + } + + public Builder addRuntimeJars(NestedSet<Artifact> runtimeJars) { + this.runtimeJarsBuilder.addTransitive(runtimeJars); + return this; + } + + /** Adds a pair of direct interface and implementation jars. */ + public Builder addDirectCompileTimeJar(Artifact interfaceJar, Artifact fullJar) { + this.directCompileTimeJarsBuilder.add(interfaceJar); + this.transitiveCompileTimeJarsBuilder.add(interfaceJar); + this.directFullCompileTimeJarsBuilder.add(fullJar); + this.transitiveFullCompileTimeJarsBuilder.add(fullJar); + return this; + } + + /** Adds paired sets of direct interface and implementation jars. */ + public Builder addDirectCompileTimeJars( + NestedSet<Artifact> interfaceJars, NestedSet<Artifact> fullJars) { + this.directCompileTimeJarsBuilder.addTransitive(interfaceJars); + this.transitiveCompileTimeJarsBuilder.addTransitive(interfaceJars); + this.directFullCompileTimeJarsBuilder.addTransitive(fullJars); + this.transitiveFullCompileTimeJarsBuilder.addTransitive(fullJars); + return this; + } + + /** + * Adds transitive interface compile-time jars. + * + * @deprecated this is necessary to support java_common.create_provider, which is also + * deprecated. It allows creating providers where the direct compile-time jars aren't a + * subset of the transitive jars, and it doesn't provide a way to associate the 'full' jars. + */ + @Deprecated + public Builder addTransitiveCompileTimeJars(NestedSet<Artifact> transitiveCompileTimeJars) { + this.transitiveCompileTimeJarsBuilder.addTransitive(transitiveCompileTimeJars); + return this; + } + + public Builder addInstrumentationMetadata(Artifact instrumentationMetadata) { + this.instrumentationMetadataBuilder.add(instrumentationMetadata); + return this; + } + + public Builder addInstrumentationMetadata(NestedSet<Artifact> instrumentationMetadata) { + this.instrumentationMetadataBuilder.addTransitive(instrumentationMetadata); + return this; + } + + public Builder addCompileTimeJavaDependencyArtifacts( + NestedSet<Artifact> compileTimeJavaDependencyArtifacts) { + this.compileTimeJavaDependencyArtifactsBuilder.addTransitive( + compileTimeJavaDependencyArtifacts); + return this; + } + + /** + * Add the {@link JavaCompilationArgsProvider} for a dependency with export-like semantics; see + * also {@link #addExports(JavaCompilationArgsProvider, ClasspathType)}. + */ + public Builder addExports(JavaCompilationArgsProvider args) { + return addExports(args, ClasspathType.BOTH); + } + + /** + * Add the {@link JavaCompilationArgsProvider} for a dependency with export-like semantics: + * direct jars of the input are direct jars of the output. + * + * @param type of jars to collect; use {@link ClasspathType#RUNTIME_ONLY} for neverlink + */ + public Builder addExports(JavaCompilationArgsProvider args, ClasspathType type) { + return addArgs(args, type, true); + } + + /** + * Add the {@link JavaCompilationArgsProvider} for a dependency with dep-like semantics; see + * also {@link #addDeps(JavaCompilationArgsProvider, ClasspathType)}. + */ + public Builder addDeps(JavaCompilationArgsProvider args) { + return addDeps(args, ClasspathType.BOTH); + } + + /* + * Add the {@link JavaCompilationArgsProvider} for a dependency with dep-like semantics: + * direct jars of the input are <em>not</em> direct jars of the output. + + * @param type of jars to collect; use {@link ClasspathType#RUNTIME} for neverlink + */ + public Builder addDeps(JavaCompilationArgsProvider args, ClasspathType type) { + return addArgs(args, type, false); + } + + /** + * Includes the contents of another instance of {@link JavaCompilationArgsProvider}. + * + * @param args the {@link JavaCompilationArgsProvider} instance + * @param type the classpath(s) to consider + */ + private Builder addArgs( + JavaCompilationArgsProvider args, ClasspathType type, boolean recursive) { + if (!ClasspathType.RUNTIME_ONLY.equals(type)) { + if (recursive) { + directCompileTimeJarsBuilder.addTransitive(args.getDirectCompileTimeJars()); + directFullCompileTimeJarsBuilder.addTransitive(args.getDirectFullCompileTimeJars()); + compileTimeJavaDependencyArtifactsBuilder.addTransitive( + args.getCompileTimeJavaDependencyArtifacts()); } + transitiveCompileTimeJarsBuilder.addTransitive(args.getTransitiveCompileTimeJars()); + transitiveFullCompileTimeJarsBuilder.addTransitive(args.getTransitiveFullCompileTimeJars()); + } + if (!ClasspathType.COMPILE_ONLY.equals(type)) { + runtimeJarsBuilder.addTransitive(args.getRuntimeJars()); + } + instrumentationMetadataBuilder.addTransitive(args.getInstrumentationMetadata()); + return this; + } + + /** Builds a {@link JavaCompilationArgsProvider}. */ + public JavaCompilationArgsProvider build() { + if (runtimeJarsBuilder.isEmpty() + && directCompileTimeJarsBuilder.isEmpty() + && transitiveCompileTimeJarsBuilder.isEmpty() + && directFullCompileTimeJarsBuilder.isEmpty() + && transitiveFullCompileTimeJarsBuilder.isEmpty() + && instrumentationMetadataBuilder.isEmpty() + && compileTimeJavaDependencyArtifactsBuilder.isEmpty()) { + return EMPTY; } + return create( + runtimeJarsBuilder.build(), + directCompileTimeJarsBuilder.build(), + transitiveCompileTimeJarsBuilder.build(), + directFullCompileTimeJarsBuilder.build(), + transitiveFullCompileTimeJarsBuilder.build(), + instrumentationMetadataBuilder.build(), + compileTimeJavaDependencyArtifactsBuilder.build()); } - return create(argsBuilder.build(), recursiveArgsBuilder.build()); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java index e209ebc23d..42cb0d78d5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java @@ -39,7 +39,6 @@ import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; -import com.google.devtools.build.lib.rules.java.JavaCompilationArgs.ClasspathType; import com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaClasspathMode; import com.google.devtools.build.lib.util.FileType; import com.google.devtools.build.lib.vfs.FileSystemUtils; @@ -699,7 +698,7 @@ public final class JavaCompilationHelper { } private void addArgsAndJarsToAttributes( - JavaCompilationArgs args, NestedSet<Artifact> directJars) { + JavaCompilationArgsProvider args, NestedSet<Artifact> directJars) { // Can only be non-null when isStrict() returns true. if (directJars != null) { attributes.addDirectJars(directJars); @@ -709,8 +708,7 @@ public final class JavaCompilationHelper { } private void addLibrariesToAttributesInternal(Iterable<? extends TransitiveInfoCollection> deps) { - JavaCompilationArgs args = - JavaCompilationArgsProvider.legacyFromTargets(deps).getRecursiveJavaCompilationArgs(); + JavaCompilationArgsProvider args = JavaCompilationArgsProvider.legacyFromTargets(deps); NestedSet<Artifact> directJars = isStrict() ? getNonRecursiveCompileTimeJarsFromCollection(deps) : null; @@ -723,12 +721,7 @@ public final class JavaCompilationHelper { private NestedSet<Artifact> getNonRecursiveCompileTimeJarsFromCollection( Iterable<? extends TransitiveInfoCollection> deps) { - JavaCompilationArgs.Builder builder = JavaCompilationArgs.builder(); - builder.addTransitiveCompilationArgs( - JavaCompilationArgsProvider.legacyFromTargets(deps), - /*recursive=*/ false, - ClasspathType.BOTH); - return builder.build().getCompileTimeJars(); + return JavaCompilationArgsProvider.legacyFromTargets(deps).getDirectCompileTimeJars(); } static void addDependencyArtifactsToAttributes( 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 69fab34d73..e09e95a663 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 @@ -83,10 +83,8 @@ public class JavaImport implements RuleConfiguredTargetFactory { NestedSet<LinkerInput> transitiveJavaNativeLibraries = common.collectTransitiveJavaNativeLibraries(); boolean neverLink = JavaCommon.isNeverLink(ruleContext); - JavaCompilationArgs javaCompilationArgs = - common.collectJavaCompilationArgs(false, neverLink, false); - JavaCompilationArgs recursiveJavaCompilationArgs = - common.collectJavaCompilationArgs(true, neverLink, false); + JavaCompilationArgsProvider javaCompilationArgs = + common.collectJavaCompilationArgs(neverLink, false); NestedSet<Artifact> transitiveJavaSourceJars = collectTransitiveJavaSourceJars(ruleContext, srcJar); if (srcJar != null) { @@ -136,8 +134,7 @@ public class JavaImport implements RuleConfiguredTargetFactory { JavaRuleOutputJarsProvider ruleOutputJarsProvider = ruleOutputJarsProviderBuilder.build(); JavaSourceJarsProvider sourceJarsProvider = JavaSourceJarsProvider.create(transitiveJavaSourceJars, srcJars); - JavaCompilationArgsProvider compilationArgsProvider = - JavaCompilationArgsProvider.create(javaCompilationArgs, recursiveJavaCompilationArgs); + JavaCompilationArgsProvider compilationArgsProvider = javaCompilationArgs; JavaInfo.Builder javaInfoBuilder = JavaInfo.Builder.create(); common.addTransitiveInfoProviders(ruleBuilder, javaInfoBuilder, filesToBuild, null); 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 30b1bc329a..63dfa4528b 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 @@ -281,7 +281,8 @@ public final class JavaInfo extends NativeInfo implements JavaInfoApi<Artifact> public SkylarkNestedSet getFullCompileTimeJars() { NestedSet<Artifact> fullCompileTimeJars = getProviderAsNestedSet( - JavaCompilationArgsProvider.class, JavaCompilationArgsProvider::getFullCompileTimeJars); + JavaCompilationArgsProvider.class, + JavaCompilationArgsProvider::getDirectFullCompileTimeJars); return SkylarkNestedSet.of(Artifact.class, fullCompileTimeJars); } 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 369e198287..f1c2b699a7 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 @@ -14,9 +14,9 @@ package com.google.devtools.build.lib.rules.java; import static com.google.common.collect.Iterables.concat; -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 static com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider.ClasspathType.BOTH; +import static com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider.ClasspathType.COMPILE_ONLY; +import static com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider.ClasspathType.RUNTIME_ONLY; import static java.util.stream.Stream.concat; import com.google.common.collect.ImmutableList; @@ -39,7 +39,7 @@ 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.rules.java.JavaCompilationArgsProvider.ClasspathType; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.SkylarkList; import com.google.devtools.build.lib.vfs.FileSystemUtils; @@ -183,14 +183,14 @@ final class JavaInfoBuildHelper { JavaInfo.Builder javaInfoBuilder = JavaInfo.Builder.create(); javaInfoBuilder.setLocation(location); - JavaCompilationArgs.Builder javaCompilationArgsBuilder = JavaCompilationArgs.builder(); - - javaCompilationArgsBuilder.addFullCompileTimeJar(outputJar); + JavaCompilationArgsProvider.Builder javaCompilationArgsBuilder = + JavaCompilationArgsProvider.builder(); if (!neverlink) { javaCompilationArgsBuilder.addRuntimeJar(outputJar); } - javaCompilationArgsBuilder.addCompileTimeJar(compileJar); + javaCompilationArgsBuilder.addDirectCompileTimeJar( + /* interfaceJar= */ compileJar, /* fullJar= */ outputJar); JavaRuleOutputJarsProvider javaRuleOutputJarsProvider = JavaRuleOutputJarsProvider.builder() @@ -199,27 +199,18 @@ final class JavaInfoBuildHelper { .build(); javaInfoBuilder.addProvider(JavaRuleOutputJarsProvider.class, javaRuleOutputJarsProvider); - JavaCompilationArgs.Builder recursiveJavaCompilationArgsBuilder = - JavaCompilationArgs.Builder.copyOf(javaCompilationArgsBuilder); - ClasspathType type = neverlink ? COMPILE_ONLY : BOTH; fetchProviders(exports, JavaCompilationArgsProvider.class) - .map(JavaCompilationArgsProvider::getJavaCompilationArgs) - .forEach(args -> javaCompilationArgsBuilder.addTransitiveArgs(args, type)); - - fetchProviders(concat(exports, compileTimeDeps), JavaCompilationArgsProvider.class) - .map(JavaCompilationArgsProvider::getRecursiveJavaCompilationArgs) - .forEach(args -> recursiveJavaCompilationArgsBuilder.addTransitiveArgs(args, type)); + .forEach(args -> javaCompilationArgsBuilder.addExports(args, type)); + fetchProviders(compileTimeDeps, JavaCompilationArgsProvider.class) + .forEach(args -> javaCompilationArgsBuilder.addDeps(args, type)); fetchProviders(runtimeDeps, JavaCompilationArgsProvider.class) - .map(JavaCompilationArgsProvider::getRecursiveJavaCompilationArgs) - .forEach(args -> recursiveJavaCompilationArgsBuilder.addTransitiveArgs(args, RUNTIME_ONLY)); + .forEach(args -> javaCompilationArgsBuilder.addDeps(args, RUNTIME_ONLY)); javaInfoBuilder.addProvider( - JavaCompilationArgsProvider.class, - JavaCompilationArgsProvider.create( - javaCompilationArgsBuilder.build(), recursiveJavaCompilationArgsBuilder.build())); + JavaCompilationArgsProvider.class, javaCompilationArgsBuilder.build()); javaInfoBuilder.addProvider(JavaExportsProvider.class, createJavaExportsProvider(exports)); @@ -370,9 +361,9 @@ final class JavaInfoBuildHelper { Location location) throws EvalException { - JavaCompilationArgs.Builder javaCompilationArgsBuilder = JavaCompilationArgs.builder(); + JavaCompilationArgsProvider.Builder javaCompilationArgsBuilder = + JavaCompilationArgsProvider.builder(); if (useIjar && !compileTimeJars.isEmpty()) { - javaCompilationArgsBuilder.addFullCompileTimeJars(compileTimeJars); if (!(actions instanceof SkylarkActionFactory)) { throw new EvalException( location, @@ -383,34 +374,29 @@ final class JavaInfoBuildHelper { location, "The value of use_ijar is True. Make sure the java_toolchain argument is valid."); } + NestedSetBuilder<Artifact> builder = NestedSetBuilder.naiveLinkOrder(); for (Artifact compileJar : compileTimeJars) { - javaCompilationArgsBuilder.addCompileTimeJar( + builder.add( buildIjar( (SkylarkActionFactory) actions, compileJar, null, (ConfiguredTarget) javaToolchain)); } + javaCompilationArgsBuilder.addDirectCompileTimeJars( + /* interfaceJars = */ builder.build(), /* fullJars= */ compileTimeJars); } else { - javaCompilationArgsBuilder.addCompileTimeJars(compileTimeJars); - javaCompilationArgsBuilder.addFullCompileTimeJars(compileTimeJars); + javaCompilationArgsBuilder.addDirectCompileTimeJars( + /* interfaceJars = */ compileTimeJars, /* fullJars= */ compileTimeJars); } - - JavaCompilationArgs javaCompilationArgs = - javaCompilationArgsBuilder.addTransitiveRuntimeJars(runtimeJars).build(); - - JavaCompilationArgs.Builder recursiveJavaCompilationArgs = - JavaCompilationArgs.builder() - .addTransitiveArgs(javaCompilationArgs, ClasspathType.BOTH) - .addTransitiveCompileTimeJars(transitiveCompileTimeJars) - .addTransitiveRuntimeJars(transitiveRuntimeJars); + javaCompilationArgsBuilder + .addTransitiveCompileTimeJars(transitiveCompileTimeJars) + .addRuntimeJars(runtimeJars) + .addRuntimeJars(transitiveRuntimeJars); JavaInfo javaInfo = JavaInfo.Builder.create() - .addProvider( - JavaCompilationArgsProvider.class, - JavaCompilationArgsProvider.create( - javaCompilationArgs, recursiveJavaCompilationArgs.build())) + .addProvider(JavaCompilationArgsProvider.class, javaCompilationArgsBuilder.build()) .addProvider( JavaSourceJarsProvider.class, JavaSourceJarsProvider.create( 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 279a3f71da..c40d186e19 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 @@ -25,7 +25,7 @@ import com.google.devtools.build.lib.analysis.RunfilesProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.rules.cpp.LinkerInput; -import com.google.devtools.build.lib.rules.java.JavaCompilationArgs.ClasspathType; +import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider.ClasspathType; import com.google.devtools.build.lib.rules.java.proto.GeneratedExtensionRegistryProvider; /** @@ -162,12 +162,8 @@ public class JavaLibrary implements RuleConfiguredTargetFactory { new ClasspathConfiguredFragment( javaArtifacts, attributes, neverLink, helper.getBootclasspathOrDefault())); - JavaCompilationArgs javaCompilationArgs = - common.collectJavaCompilationArgs(false, neverLink, false); - JavaCompilationArgs recursiveJavaCompilationArgs = - common.collectJavaCompilationArgs(true, neverLink, false); - NestedSet<Artifact> compileTimeJavaDepArtifacts = common.collectCompileTimeDependencyArtifacts( - javaArtifacts.getCompileTimeDependencyArtifact()); + JavaCompilationArgsProvider javaCompilationArgs = + common.collectJavaCompilationArgs(neverLink, false); NestedSet<LinkerInput> transitiveJavaNativeLibraries = common.collectTransitiveJavaNativeLibraries(); @@ -179,9 +175,7 @@ public class JavaLibrary implements RuleConfiguredTargetFactory { builder.add(GeneratedExtensionRegistryProvider.class, generatedExtensionRegistryProvider); } - JavaCompilationArgsProvider compilationArgsProvider = - JavaCompilationArgsProvider.create( - javaCompilationArgs, recursiveJavaCompilationArgs, compileTimeJavaDepArtifacts); + JavaCompilationArgsProvider compilationArgsProvider = javaCompilationArgs; JavaSourceJarsProvider sourceJarsProvider = sourceJarsProviderBuilder.build(); JavaRuleOutputJarsProvider ruleOutputJarsProvider = ruleOutputJarsProviderBuilder.build(); 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 81de790938..3a28e17cca 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java @@ -24,7 +24,6 @@ import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.config.BuildConfiguration.StrictDepsMode; -import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaClasspathMode; import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.OutputJar; import java.util.ArrayList; @@ -122,6 +121,11 @@ public final class JavaLibraryHelper { return this; } + public JavaLibraryHelper addExport(JavaCompilationArgsProvider provider) { + exports.add(provider); + return this; + } + public JavaLibraryHelper addAllExports(Iterable<JavaCompilationArgsProvider> providers) { Iterables.addAll(exports, providers); return this; @@ -153,10 +157,9 @@ public final class JavaLibraryHelper { /** * When in strict mode, compiling the source-jars passed to this JavaLibraryHelper will break if * they depend on classes not in any of the {@link - * JavaCompilationArgsProvider#getJavaCompilationArgs()} passed in {@link #addDep}, even if they - * do appear in - * {@link JavaCompilationArgsProvider#getRecursiveJavaCompilationArgs()}. That is, depending - * on a class requires a direct dependency on it. + * JavaCompilationArgsProvider#getDirectCompileTimeJars()} passed in {@link #addDep}, even if they + * do appear in {@link JavaCompilationArgsProvider#getTransitiveCompileTimeJars()}. That is, + * depending on a class requires a direct dependency on it. * * <p>Contrast this with the strictness-parameter to {@link #buildCompilationArgsProvider}, which * controls whether others depending on the result of this compilation, can perform strict-deps @@ -325,18 +328,8 @@ public final class JavaLibraryHelper { public JavaCompilationArgsProvider buildCompilationArgsProvider( JavaCompilationArtifacts artifacts, boolean isReportedAsStrict, boolean isNeverlink) { - JavaCompilationArgs directArgs = - collectJavaCompilationArgs( - /* recursive= */ false, - /* isNeverLink= */ isNeverlink, - /* srcLessDepsExport= */ false, - artifacts, - deps, - /* runtimeDeps= */ ImmutableList.of(), - exports); - JavaCompilationArgs transitiveArgs = + JavaCompilationArgsProvider directArgs = collectJavaCompilationArgs( - /* recursive= */ true, /* isNeverLink= */ isNeverlink, /* srcLessDepsExport= */ false, artifacts, @@ -344,24 +337,17 @@ public final class JavaLibraryHelper { /* runtimeDeps= */ ImmutableList.of(), exports); - NestedSet<Artifact> compileTimeJavaDepArtifacts = - JavaCommon.collectCompileTimeDependencyArtifacts( - artifacts.getCompileTimeDependencyArtifact(), exports); - - return JavaCompilationArgsProvider.create( - isReportedAsStrict ? directArgs : transitiveArgs, - transitiveArgs, - compileTimeJavaDepArtifacts); + if (!isReportedAsStrict) { + directArgs = JavaCompilationArgsProvider.makeNonStrict(directArgs); + } + return directArgs; } private void addDepsToAttributes(JavaTargetAttributes.Builder attributes) { JavaCompilationArgsProvider argsProvider = JavaCompilationArgsProvider.merge(deps); if (isStrict()) { - NestedSet<Artifact> directJars = argsProvider.getDirectCompileTimeJars(); - if (directJars != null) { - attributes.addDirectJars(directJars); - } + attributes.addDirectJars(argsProvider.getDirectCompileTimeJars()); } attributes.addCompileTimeClassPathEntries(argsProvider.getTransitiveCompileTimeJars()); diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java index c85b3703ce..a105d72068 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java @@ -39,7 +39,7 @@ import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; import com.google.devtools.build.lib.packages.Attribute.LabelListLateBoundDefault; import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction; import com.google.devtools.build.lib.rules.java.DeployArchiveBuilder.Compression; -import com.google.devtools.build.lib.rules.java.JavaCompilationArgs.ClasspathType; +import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider.ClasspathType; import com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaOptimizationMode; import com.google.devtools.build.lib.rules.java.JavaConfiguration.OneVersionEnforcementLevel; import com.google.devtools.build.lib.rules.java.proto.GeneratedExtensionRegistryProvider; 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 585770de10..b44fb1138a 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 @@ -13,8 +13,6 @@ // 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 com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.Artifact; @@ -184,31 +182,16 @@ public class JavaSkylarkCommon implements JavaCommonApi<Artifact, JavaInfo, Skyl // TODO(b/65113771): Remove this method because it's incorrect. @Override public JavaInfo makeNonStrict(JavaInfo javaInfo) { - JavaCompilationArgsProvider directCompilationArgs = - makeNonStrict(javaInfo.getProvider(JavaCompilationArgsProvider.class)); - return JavaInfo.Builder.copyOf(javaInfo) // Overwrites the old provider. - .addProvider(JavaCompilationArgsProvider.class, directCompilationArgs) + .addProvider( + JavaCompilationArgsProvider.class, + JavaCompilationArgsProvider.makeNonStrict( + javaInfo.getProvider(JavaCompilationArgsProvider.class))) .build(); } - /** - * Returns a new JavaCompilationArgsProvider whose direct-jars part is the union of both the - * direct and indirect jars of 'provider'. - */ - private static JavaCompilationArgsProvider makeNonStrict(JavaCompilationArgsProvider provider) { - JavaCompilationArgs.Builder directCompilationArgs = JavaCompilationArgs.builder(); - directCompilationArgs - .addTransitiveArgs(provider.getJavaCompilationArgs(), BOTH) - .addTransitiveArgs(provider.getRecursiveJavaCompilationArgs(), BOTH); - return JavaCompilationArgsProvider.create( - directCompilationArgs.build(), - provider.getRecursiveJavaCompilationArgs(), - provider.getCompileTimeJavaDependencyArtifacts()); - } - @Override public Provider getJavaRuntimeProvider() { return JavaRuntimeInfo.PROVIDER; diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaTargetAttributes.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaTargetAttributes.java index 5ff0c25b12..9f51626b54 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaTargetAttributes.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaTargetAttributes.java @@ -138,9 +138,9 @@ public class JavaTargetAttributes { return this; } - public Builder merge(JavaCompilationArgs context) { + public Builder merge(JavaCompilationArgsProvider context) { Preconditions.checkArgument(!built); - addCompileTimeClassPathEntries(context.getCompileTimeJars()); + addCompileTimeClassPathEntries(context.getTransitiveCompileTimeJars()); addRuntimeClassPathEntries(context.getRuntimeJars()); addInstrumentationMetadataEntries(context.getInstrumentationMetadata()); return this; diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibraryAspectProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibraryAspectProvider.java index 55b185a251..d424c9792e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibraryAspectProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibraryAspectProvider.java @@ -18,7 +18,7 @@ import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap; import com.google.devtools.build.lib.analysis.WrappingProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSet; -import com.google.devtools.build.lib.rules.java.JavaCompilationArgs; +import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; /** A provider used to communicate information between java_proto_library and its aspect. */ @@ -33,12 +33,12 @@ public class JavaProtoLibraryAspectProvider implements WrappingProvider { * <p>Contains all transitively generated protos and all proto runtimes (but not the runtime's own * dependencies). */ - private final JavaCompilationArgs nonStrictCompArgs; + private final JavaCompilationArgsProvider nonStrictCompArgs; public JavaProtoLibraryAspectProvider( TransitiveInfoProviderMap transitiveInfoProviderMap, NestedSet<Artifact> jars, - JavaCompilationArgs nonStrictCompArgs) { + JavaCompilationArgsProvider nonStrictCompArgs) { this.transitiveInfoProviderMap = transitiveInfoProviderMap; this.jars = jars; this.nonStrictCompArgs = nonStrictCompArgs; @@ -53,7 +53,7 @@ public class JavaProtoLibraryAspectProvider implements WrappingProvider { return jars; } - public JavaCompilationArgs getNonStrictCompArgs() { + public JavaCompilationArgsProvider getNonStrictCompArgs() { return nonStrictCompArgs; } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/StrictDepsUtils.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/StrictDepsUtils.java index 85adb698af..08522e89df 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/StrictDepsUtils.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/StrictDepsUtils.java @@ -14,13 +14,11 @@ package com.google.devtools.build.lib.rules.java.proto; -import static com.google.devtools.build.lib.rules.java.JavaCompilationArgs.ClasspathType.BOTH; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.WrappingProvider; -import com.google.devtools.build.lib.rules.java.JavaCompilationArgs; import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider; import com.google.devtools.build.lib.rules.java.JavaConfiguration; import com.google.devtools.build.lib.rules.java.JavaInfo; @@ -43,14 +41,24 @@ public class StrictDepsUtils { if (StrictDepsUtils.isStrictDepsJavaProtoLibrary(ruleContext)) { return strictCompProvider; } else { - JavaCompilationArgs.Builder nonStrictDirectJars = JavaCompilationArgs.builder(); + JavaCompilationArgsProvider.Builder nonStrictDirectJars = + JavaCompilationArgsProvider.builder(); for (JavaProtoLibraryAspectProvider p : javaProtoLibraryAspectProviders) { - nonStrictDirectJars.addTransitiveArgs(p.getNonStrictCompArgs(), BOTH); + JavaCompilationArgsProvider args = p.getNonStrictCompArgs(); + nonStrictDirectJars + .addRuntimeJars(args.getRuntimeJars()) + .addDirectCompileTimeJars( + /* interfaceJars= */ args.getDirectCompileTimeJars(), + /* fullJars= */ args.getDirectFullCompileTimeJars()) + .addTransitiveCompileTimeJars(args.getTransitiveCompileTimeJars()) + .addInstrumentationMetadata(args.getInstrumentationMetadata()); } - return JavaCompilationArgsProvider.create( - nonStrictDirectJars.build(), - strictCompProvider.getRecursiveJavaCompilationArgs(), - strictCompProvider.getCompileTimeJavaDependencyArtifacts()); + // Don't collect .jdeps recursively for legacy "feature" compatibility reasons. Collecting + // .jdeps here is probably a mistake; see JavaCompilationArgsProvider#makeNonStrict. + return nonStrictDirectJars + .addCompileTimeJavaDependencyArtifacts( + strictCompProvider.getCompileTimeJavaDependencyArtifacts()) + .build(); } } @@ -59,19 +67,19 @@ public class StrictDepsUtils { * It contains the jars a proto_library (or the proto aspect) produced, as well as all transitive * proto jars, and the proto runtime jars, all described as direct dependencies. */ - public static JavaCompilationArgs createNonStrictCompilationArgsProvider( + public static JavaCompilationArgsProvider createNonStrictCompilationArgsProvider( Iterable<JavaProtoLibraryAspectProvider> deps, JavaCompilationArgsProvider directJars, ImmutableList<TransitiveInfoCollection> protoRuntimes) { - JavaCompilationArgs.Builder result = JavaCompilationArgs.builder(); + JavaCompilationArgsProvider.Builder result = JavaCompilationArgsProvider.builder(); for (JavaProtoLibraryAspectProvider p : deps) { - result.addTransitiveArgs(p.getNonStrictCompArgs(), BOTH); + result.addExports(p.getNonStrictCompArgs()); } - result.addTransitiveCompilationArgs(directJars, /* recursive= */ false, BOTH); + result.addExports(directJars); for (TransitiveInfoCollection t : protoRuntimes) { JavaCompilationArgsProvider p = JavaInfo.getProvider(JavaCompilationArgsProvider.class, t); if (p != null) { - result.addTransitiveArgs(p.getJavaCompilationArgs(), BOTH); + result.addExports(p); } } return result.build(); |