Skip to content

Commit 8ed576a

Browse files
Support toolchain-driven unused dependencies checking (Starlark changes)
1 parent 54439b9 commit 8ed576a

4 files changed

Lines changed: 77 additions & 1 deletion

File tree

java/common/java_semantics.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,5 +128,6 @@ semantics = struct(
128128
update_args_for_import_deps = _update_args_for_import_deps,
129129
expand_javacopts_make_variables = True,
130130
java_toolchain_supports_one_version = _bazel_version_ge("8.0.0"), # can be dropped once we no longer support Bazel 7
131+
create_compilation_action_supports_extra_args = _bazel_version_ge("10.0.0-pre"),
131132
TEST_SUITE_PROPERTY_NAME = "bazel.test_suite",
132133
)

java/common/rules/java_package_configuration.bzl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ JavaPackageConfigurationInfo = provider(
2828
"matches",
2929
"package_specs",
3030
"system",
31+
"unused_deps",
3132
],
3233
)
3334

@@ -50,6 +51,7 @@ def _rule_impl(ctx):
5051
matches = _matches,
5152
package_specs = package_specs,
5253
system = system,
54+
unused_deps = ctx.attr.unused_deps,
5355
),
5456
]
5557

@@ -116,6 +118,13 @@ The list of files needed by this configuration at runtime.
116118
providers = [BootClassPathInfo],
117119
doc = """
118120
Corresponds to javac's --system flag.
121+
""",
122+
),
123+
"unused_deps": attr.string(
124+
default = "off",
125+
values = ["off", "error"],
126+
doc = """
127+
Unused dependencies checking mode.
119128
""",
120129
),
121130
# buildifier: disable=attr-licenses

java/private/java_common_internal.bzl

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ load("//java/common/rules:java_helper.bzl", "helper")
2020
load("//java/common/rules:java_toolchain.bzl", "JavaToolchainInfo")
2121
load(
2222
":java_info.bzl",
23+
"JavaInfo",
2324
"JavaPluginInfo",
2425
"disable_plugin_info_annotation_processing",
2526
"java_info_for_compilation",
@@ -165,7 +166,8 @@ def compile(
165166
include_compilation_info = True,
166167
classpath_resources = [],
167168
resource_jars = [],
168-
injecting_rule_kind = None):
169+
injecting_rule_kind = None,
170+
extra_args = []):
169171
"""Compiles Java source files/jars from the implementation of a Starlark rule
170172
171173
The result is a provider that represents the results of the compilation and can be added to the
@@ -215,6 +217,7 @@ def compile(
215217
add_exports: ([str]) Allow this library to access the given <module>/<package>. Optional.
216218
add_opens: ([str]) Allow this library to reflectively access the given <module>/<package>.
217219
Optional.
220+
extra_args: (list[Args]) Additional args to pass to JavaBuilder. Optional.
218221
219222
Returns:
220223
(JavaInfo)
@@ -314,6 +317,32 @@ def compile(
314317
if uses_annotation_processing:
315318
generated_class_jar = _derive_output_file(ctx, output, name_suffix = "-gen")
316319
generated_source_jar = _derive_output_file(ctx, output, name_suffix = "-gensrc")
320+
321+
extra_args_list = list(extra_args)
322+
if semantics.create_compilation_action_supports_extra_args:
323+
repo_name = ctx.label.repo_name if hasattr(ctx.label, "repo_name") else ctx.label.workspace_name
324+
if not repo_name:
325+
resolved_unused_deps_mode = "off"
326+
for package_config in java_toolchain._package_configuration:
327+
if package_config.matches(package_config.package_specs, ctx.label):
328+
if hasattr(package_config, "unused_deps"):
329+
resolved_unused_deps_mode = package_config.unused_deps
330+
331+
if resolved_unused_deps_mode == "error" and hasattr(ctx.attr, "deps"):
332+
unused_deps_args = ctx.actions.args()
333+
for dep in ctx.attr.deps:
334+
if JavaInfo in dep:
335+
if hasattr(dep[JavaInfo], "java_outputs"):
336+
for output_info in dep[JavaInfo].java_outputs:
337+
dep_compile_jar = output_info.compile_jar if output_info.compile_jar else output_info.class_jar
338+
if dep_compile_jar:
339+
unused_deps_args.add("--declared_dep", dep_compile_jar, format = "%s::" + str(dep.label))
340+
extra_args_list.append(unused_deps_args)
341+
342+
extra_compilation_action_args = {}
343+
if extra_args_list and semantics.create_compilation_action_supports_extra_args:
344+
extra_compilation_action_args["extra_args"] = extra_args_list
345+
317346
get_internal_java_common().create_compilation_action(
318347
ctx,
319348
java_toolchain,
@@ -343,6 +372,7 @@ def compile(
343372
enable_direct_classpath,
344373
annotation_processor_additional_inputs,
345374
annotation_processor_additional_outputs,
375+
**extra_compilation_action_args
346376
)
347377

348378
create_output_source_jar = len(source_files) > 0 or source_jars != [output_source_jar]

test/java/toolchains/java_toolchain_tests.bzl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ load("//java:java_binary.bzl", "java_binary")
77
load("//java:java_library.bzl", "java_library")
88
load("//java:java_plugin.bzl", "java_plugin")
99
load("//java/common:java_common.bzl", "java_common")
10+
load("//java/common/rules:java_package_configuration.bzl", "JavaPackageConfigurationInfo", "java_package_configuration")
1011
load("//test/java/testutil:java_info_subject.bzl", "java_info_subject")
1112
load("//test/java/testutil:java_toolchain_info_subject.bzl", "java_toolchain_info_subject")
1213
load("//test/java/testutil:javac_action_subject.bzl", "javac_action_subject")
@@ -744,6 +745,39 @@ def _test_default_javac_opts_impl(env, target):
744745
"6",
745746
]).in_order()
746747

748+
def _test_java_package_configuration_unused_deps(name):
749+
util.helper_target(
750+
java_package_configuration,
751+
name = name + "/pkg_config",
752+
unused_deps = "error",
753+
)
754+
755+
analysis_test(
756+
name = name,
757+
impl = _test_java_package_configuration_unused_deps_impl,
758+
target = name + "/pkg_config",
759+
)
760+
761+
def _test_java_package_configuration_unused_deps_impl(env, target):
762+
info = target[JavaPackageConfigurationInfo]
763+
env.expect.that_str(info.unused_deps).equals("error")
764+
765+
def _test_java_package_configuration_default_unused_deps(name):
766+
util.helper_target(
767+
java_package_configuration,
768+
name = name + "/pkg_config_default",
769+
)
770+
771+
analysis_test(
772+
name = name,
773+
impl = _test_java_package_configuration_default_unused_deps_impl,
774+
target = name + "/pkg_config_default",
775+
)
776+
777+
def _test_java_package_configuration_default_unused_deps_impl(env, target):
778+
info = target[JavaPackageConfigurationInfo]
779+
env.expect.that_str(info.unused_deps).equals("off")
780+
747781
def java_toolchain_tests(name):
748782
test_suite(
749783
name = name,
@@ -772,5 +806,7 @@ def java_toolchain_tests(name):
772806
_test_java_toolchain_flag_set,
773807
_test_default_javac_opts_depset,
774808
_test_default_javac_opts,
809+
_test_java_package_configuration_unused_deps,
810+
_test_java_package_configuration_default_unused_deps,
775811
],
776812
)

0 commit comments

Comments
 (0)