| // Copyright 2016 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.common.collect.ImmutableList; |
| import com.google.devtools.build.lib.actions.Artifact; |
| import com.google.devtools.build.lib.analysis.PlatformOptions; |
| import com.google.devtools.build.lib.analysis.platform.ToolchainInfo; |
| import com.google.devtools.build.lib.analysis.skylark.SkylarkActionFactory; |
| import com.google.devtools.build.lib.analysis.skylark.SkylarkRuleContext; |
| 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.events.Location; |
| import com.google.devtools.build.lib.packages.Provider; |
| import com.google.devtools.build.lib.skylarkbuildapi.ProviderApi; |
| import com.google.devtools.build.lib.skylarkbuildapi.java.JavaCommonApi; |
| import com.google.devtools.build.lib.skylarkbuildapi.java.JavaToolchainSkylarkApiProviderApi; |
| import com.google.devtools.build.lib.syntax.Environment; |
| import com.google.devtools.build.lib.syntax.EvalException; |
| import com.google.devtools.build.lib.syntax.Runtime; |
| import com.google.devtools.build.lib.syntax.SkylarkList; |
| import com.google.devtools.build.lib.syntax.SkylarkNestedSet; |
| import com.google.devtools.build.lib.syntax.StarlarkSemantics; |
| import java.util.List; |
| import javax.annotation.Nullable; |
| |
| /** A module that contains Skylark utilities for Java support. */ |
| public class JavaSkylarkCommon |
| implements JavaCommonApi< |
| Artifact, |
| JavaInfo, |
| JavaToolchainProvider, |
| JavaRuntimeInfo, |
| SkylarkRuleContext, |
| SkylarkActionFactory> { |
| private final JavaSemantics javaSemantics; |
| |
| @Override |
| public JavaInfo create( |
| @Nullable Object actionsUnchecked, |
| Object compileTimeJars, |
| Object runtimeJars, |
| Boolean useIjar, |
| @Nullable Object javaToolchain, |
| Object transitiveCompileTimeJars, |
| Object transitiveRuntimeJars, |
| Object sourceJars, |
| Location location, |
| Environment environment) |
| throws EvalException { |
| if (environment.getSemantics().incompatibleDisallowLegacyJavaInfo()) { |
| checkCallPathInWhitelistedPackages( |
| environment.getSemantics(), |
| location, |
| environment.getGlobals().getLabel().getPackageName()); |
| } |
| return JavaInfoBuildHelper.getInstance() |
| .create( |
| actionsUnchecked, |
| asArtifactNestedSet(compileTimeJars), |
| asArtifactNestedSet(runtimeJars), |
| useIjar, |
| javaToolchain == Runtime.NONE ? null : (JavaToolchainProvider) javaToolchain, |
| asArtifactNestedSet(transitiveCompileTimeJars), |
| asArtifactNestedSet(transitiveRuntimeJars), |
| asArtifactNestedSet(sourceJars), |
| environment.getSemantics(), |
| location); |
| } |
| |
| public JavaSkylarkCommon(JavaSemantics javaSemantics) { |
| this.javaSemantics = javaSemantics; |
| } |
| |
| @Override |
| public Provider getJavaProvider() { |
| return JavaInfo.PROVIDER; |
| } |
| |
| @Override |
| public JavaInfo createJavaCompileAction( |
| SkylarkRuleContext skylarkRuleContext, |
| SkylarkList<Artifact> sourceJars, |
| SkylarkList<Artifact> sourceFiles, |
| Artifact outputJar, |
| Object outputSourceJar, |
| SkylarkList<String> javacOpts, |
| SkylarkList<JavaInfo> deps, |
| SkylarkList<JavaInfo> exports, |
| SkylarkList<JavaInfo> plugins, |
| SkylarkList<JavaInfo> exportedPlugins, |
| String strictDepsMode, |
| JavaToolchainProvider javaToolchain, |
| JavaRuntimeInfo hostJavabase, |
| SkylarkList<Artifact> sourcepathEntries, |
| SkylarkList<Artifact> resources, |
| Boolean neverlink, |
| Location location, |
| Environment environment) |
| throws EvalException, InterruptedException { |
| |
| return JavaInfoBuildHelper.getInstance() |
| .createJavaCompileAction( |
| skylarkRuleContext, |
| sourceJars, |
| sourceFiles, |
| outputJar, |
| outputSourceJar == Runtime.NONE ? null : (Artifact) outputSourceJar, |
| javacOpts, |
| deps, |
| exports, |
| plugins, |
| exportedPlugins, |
| strictDepsMode, |
| javaToolchain, |
| hostJavabase, |
| sourcepathEntries, |
| resources, |
| neverlink, |
| javaSemantics, |
| location, |
| environment); |
| } |
| |
| @Override |
| public Artifact runIjar( |
| SkylarkActionFactory actions, |
| Artifact jar, |
| Object targetLabel, |
| JavaToolchainProvider javaToolchain, |
| Location location, |
| StarlarkSemantics semantics) |
| throws EvalException { |
| return JavaInfoBuildHelper.getInstance() |
| .buildIjar( |
| actions, |
| jar, |
| targetLabel != Runtime.NONE ? (Label) targetLabel : null, |
| javaToolchain, |
| location); |
| } |
| |
| @Override |
| public Artifact stampJar( |
| SkylarkActionFactory actions, |
| Artifact jar, |
| Label targetLabel, |
| JavaToolchainProvider javaToolchain, |
| Location location, |
| StarlarkSemantics semantics) |
| throws EvalException { |
| return JavaInfoBuildHelper.getInstance() |
| .stampJar(actions, jar, targetLabel, javaToolchain, location); |
| } |
| |
| @Override |
| public Artifact packSources( |
| SkylarkActionFactory actions, |
| Artifact outputJar, |
| SkylarkList<Artifact> sourceFiles, |
| SkylarkList<Artifact> sourceJars, |
| JavaToolchainProvider javaToolchain, |
| JavaRuntimeInfo hostJavabase, |
| Location location, |
| StarlarkSemantics semantics) |
| throws EvalException { |
| return JavaInfoBuildHelper.getInstance() |
| .packSourceFiles( |
| actions, |
| outputJar, |
| /* outputSourceJar= */ null, |
| sourceFiles, |
| sourceJars, |
| javaToolchain, |
| hostJavabase, |
| location); |
| } |
| |
| @Override |
| // TODO(b/78512644): migrate callers to passing explicit javacopts or using custom toolchains, and |
| // delete |
| public ImmutableList<String> getDefaultJavacOpts( |
| JavaToolchainProvider javaToolchain, Location location) throws EvalException { |
| // We don't have a rule context if the default_javac_opts.java_toolchain parameter is set |
| return ((JavaToolchainProvider) javaToolchain).getJavacOptions(/* ruleContext= */ null); |
| } |
| |
| @Override |
| public JavaInfo mergeJavaProviders(SkylarkList<JavaInfo> providers) { |
| return JavaInfo.merge(providers); |
| } |
| |
| // TODO(b/65113771): Remove this method because it's incorrect. |
| @Override |
| public JavaInfo makeNonStrict(JavaInfo javaInfo) { |
| return JavaInfo.Builder.copyOf(javaInfo) |
| // Overwrites the old provider. |
| .addProvider( |
| JavaCompilationArgsProvider.class, |
| JavaCompilationArgsProvider.makeNonStrict( |
| javaInfo.getProvider(JavaCompilationArgsProvider.class))) |
| .build(); |
| } |
| |
| @Override |
| public Provider getJavaToolchainProvider() { |
| return ToolchainInfo.PROVIDER; |
| } |
| |
| @Override |
| public Provider getJavaRuntimeProvider() { |
| return ToolchainInfo.PROVIDER; |
| } |
| |
| /** |
| * Takes an Object that is either a SkylarkNestedSet or a SkylarkList of Artifacts and returns it |
| * as a NestedSet. |
| */ |
| private NestedSet<Artifact> asArtifactNestedSet(Object o) throws EvalException { |
| return o instanceof SkylarkNestedSet |
| ? ((SkylarkNestedSet) o).getSet(Artifact.class) |
| : NestedSetBuilder.<Artifact>naiveLinkOrder() |
| .addAll(((SkylarkList<?>) o).getContents(Artifact.class, /*description=*/ null)) |
| .build(); |
| } |
| |
| /** |
| * Throws an {@link EvalException} if the given {@code callPath} is not listed under the {@code |
| * --experimental_java_common_create_provider_enabled_packages} flag. |
| */ |
| private static void checkCallPathInWhitelistedPackages( |
| StarlarkSemantics semantics, Location location, String callPath) throws EvalException { |
| List<String> whitelistedPackagesList = |
| semantics.experimentalJavaCommonCreateProviderEnabledPackages(); |
| if (whitelistedPackagesList.stream().noneMatch(path -> callPath.startsWith(path))) { |
| throw new EvalException( |
| location, |
| "java_common.create_provider is deprecated and cannot be used when " |
| + "--incompatible_disallow_legacy_javainfo is set. " |
| + "Please migrate to the JavaInfo constructor."); |
| } |
| } |
| |
| @Override |
| public boolean isJavaToolchainResolutionEnabled(SkylarkRuleContext ruleContext) |
| throws EvalException { |
| return ruleContext |
| .getConfiguration() |
| .getOptions() |
| .get(PlatformOptions.class) |
| .useToolchainResolutionForJavaRules; |
| } |
| |
| @Override |
| public ProviderApi getMessageBundleInfo() { |
| // No implementation in Bazel. This method not callable in Starlark except through |
| // (discouraged) use of --experimental_google_legacy_api. |
| return null; |
| } |
| |
| @Override |
| public JavaInfo addConstraints(JavaInfo javaInfo, SkylarkList<String> constraints) { |
| // No implementation in Bazel. This method not callable in Starlark except through |
| // (discouraged) use of --experimental_google_legacy_api. |
| return null; |
| } |
| |
| @Override |
| public JavaInfo removeAnnotationProcessors(JavaInfo javaInfo) { |
| // No implementation in Bazel. This method not callable in Starlark except through |
| // (discouraged) use of --experimental_google_legacy_api. |
| return null; |
| } |
| |
| @Override |
| public NestedSet<Artifact> getCompileTimeJavaDependencyArtifacts(JavaInfo javaInfo) { |
| // No implementation in Bazel. This method not callable in Starlark except through |
| // (discouraged) use of --experimental_google_legacy_api. |
| return null; |
| } |
| |
| @Override |
| public JavaInfo addCompileTimeJavaDependencyArtifacts( |
| JavaInfo javaInfo, SkylarkList<Artifact> compileTimeJavaDependencyArtifacts) { |
| // No implementation in Bazel. This method not callable in Starlark except through |
| // (discouraged) use of --experimental_google_legacy_api. |
| return null; |
| } |
| |
| @Override |
| public Label getJavaToolchainLabel( |
| JavaToolchainSkylarkApiProviderApi toolchain, Location location) throws EvalException { |
| // No implementation in Bazel. This method not callable in Starlark except through |
| // (discouraged) use of --experimental_google_legacy_api. |
| return null; |
| } |
| } |