diff --git a/rust/private/rust_analyzer.bzl b/rust/private/rust_analyzer.bzl index da41867985..10df6805bc 100644 --- a/rust/private/rust_analyzer.bzl +++ b/rust/private/rust_analyzer.bzl @@ -141,6 +141,12 @@ def _rust_analyzer_aspect_impl(target, ctx): proc_macro_dylibs = [proc_macro_dylib] if proc_macro_dylib else None build_info_out_dirs = [build_info.out_dir] if build_info != None and build_info.out_dir != None else None + rust_generated_srcs = [] + for attr in ["srcs", "deps", "proc_macro_deps"]: + for dep in getattr(ctx.rule.attr, attr, []): + if OutputGroupInfo in dep and hasattr(dep[OutputGroupInfo], "rust_generated_srcs"): + rust_generated_srcs.append(dep[OutputGroupInfo].rust_generated_srcs) + rust_analyzer_info = write_rust_analyzer_spec_file(ctx, ctx.rule.attr, ctx.label, RustAnalyzerInfo( aliases = aliases, crate = crate_info, @@ -160,6 +166,7 @@ def _rust_analyzer_aspect_impl(target, ctx): rust_analyzer_crate_spec = rust_analyzer_info.crate_specs, rust_analyzer_proc_macro_dylib = rust_analyzer_info.proc_macro_dylibs, rust_analyzer_src = rust_analyzer_info.build_info_out_dirs, + rust_generated_srcs = depset(transitive = rust_generated_srcs), ), ] @@ -193,7 +200,7 @@ def find_proc_macro_dylib(toolchain, target): return None rust_analyzer_aspect = aspect( - attr_aspects = ["deps", "proc_macro_deps", "crate", "actual", "proto"], + attr_aspects = ["srcs", "deps", "proc_macro_deps", "crate", "actual", "proto"], implementation = _rust_analyzer_aspect_impl, toolchains = [str(Label("//rust:toolchain_type"))], doc = "Annotates rust rules with RustAnalyzerInfo later used to build a rust-project.json", diff --git a/test/rust_analyzer/generated_srcs_test/BUILD.bazel b/test/rust_analyzer/generated_srcs_test/BUILD.bazel index 6df7f0660e..a56b34adce 100644 --- a/test/rust_analyzer/generated_srcs_test/BUILD.bazel +++ b/test/rust_analyzer/generated_srcs_test/BUILD.bazel @@ -1,20 +1,17 @@ -load("@bazel_skylib//rules:write_file.bzl", "write_file") load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test") +load(":generated_srcs_test.bzl", "generated_srcs_analysis_test_suite", "rust_generated_src") -write_file( +rust_generated_src( name = "generated_rs", out = "generated.rs", - content = [ - "pub fn forty_two() -> i32 { 42 }", - "", - ], + content = "pub fn forty_two() -> i32 { 42 }\n", ) rust_library( name = "generated_srcs", srcs = [ "lib.rs", - ":generated.rs", + ":generated_rs", ], edition = "2021", ) @@ -39,3 +36,6 @@ rust_test( "//test/rust_analyzer/3rdparty/crates:serde_json", ], ) + +############################ UNIT TESTS ############################# +generated_srcs_analysis_test_suite(name = "generated_srcs_analysis_test_suite") diff --git a/test/rust_analyzer/generated_srcs_test/generated_srcs_test.bzl b/test/rust_analyzer/generated_srcs_test/generated_srcs_test.bzl new file mode 100644 index 0000000000..5157375550 --- /dev/null +++ b/test/rust_analyzer/generated_srcs_test/generated_srcs_test.bzl @@ -0,0 +1,53 @@ +"""Analysis test for rust_analyzer_aspect rust_generated_srcs propagation.""" + +load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") +load("@rules_rust//rust:defs.bzl", "rust_analyzer_aspect") + +def _rust_generated_src_impl(ctx): + out = ctx.actions.declare_file(ctx.attr.out) + ctx.actions.write(output = out, content = ctx.attr.content) + return [ + DefaultInfo(files = depset([out])), + OutputGroupInfo(rust_generated_srcs = depset([out])), + ] + +rust_generated_src = rule( + implementation = _rust_generated_src_impl, + attrs = { + "content": attr.string(mandatory = True), + "out": attr.string(mandatory = True), + }, + doc = "Test helper that generates a .rs file and provides rust_generated_srcs output group.", +) + +def _rust_generated_srcs_test_impl(ctx): + env = analysistest.begin(ctx) + target = analysistest.target_under_test(env) + + rust_generated_srcs = target[OutputGroupInfo].rust_generated_srcs.to_list() + asserts.equals(env, ["generated.rs"], [f.basename for f in rust_generated_srcs]) + + return analysistest.end(env) + +rust_generated_srcs_test = analysistest.make( + _rust_generated_srcs_test_impl, + extra_target_under_test_aspects = [rust_analyzer_aspect], +) + +def generated_srcs_analysis_test_suite(name): + """Test suite for rust_analyzer_aspect rust_generated_srcs propagation. + + Args: + name: Name of the test suite. + """ + rust_generated_srcs_test( + name = "rust_generated_srcs_propagation_test", + target_under_test = ":generated_srcs", + ) + + native.test_suite( + name = name, + tests = [ + ":rust_generated_srcs_propagation_test", + ], + )