aboutsummaryrefslogtreecommitdiff
path: root/rust/private/rust_analyzer.bzl
diff options
context:
space:
mode:
Diffstat (limited to 'rust/private/rust_analyzer.bzl')
-rw-r--r--rust/private/rust_analyzer.bzl104
1 files changed, 49 insertions, 55 deletions
diff --git a/rust/private/rust_analyzer.bzl b/rust/private/rust_analyzer.bzl
index 74b46648..2682d966 100644
--- a/rust/private/rust_analyzer.bzl
+++ b/rust/private/rust_analyzer.bzl
@@ -20,9 +20,9 @@ given targets. This file can be consumed by rust-analyzer as an alternative
to Cargo.toml files.
"""
-load("//proto/prost:providers.bzl", "ProstProtoInfo")
load("//rust/platform:triple_mappings.bzl", "system_to_dylib_ext", "triple_to_system")
load("//rust/private:common.bzl", "rust_common")
+load("//rust/private:providers.bzl", "RustAnalyzerGroupInfo", "RustAnalyzerInfo")
load("//rust/private:rustc.bzl", "BuildInfo")
load(
"//rust/private:utils.bzl",
@@ -32,25 +32,43 @@ load(
"find_toolchain",
)
-RustAnalyzerInfo = provider(
- doc = "RustAnalyzerInfo holds rust crate metadata for targets",
- fields = {
- "build_info": "BuildInfo: build info for this crate if present",
- "cfgs": "List[String]: features or other compilation --cfg settings",
- "crate": "rust_common.crate_info",
- "crate_specs": "Depset[File]: transitive closure of OutputGroupInfo files",
- "deps": "List[RustAnalyzerInfo]: direct dependencies",
- "env": "Dict{String: String}: Environment variables, used for the `env!` macro",
- "proc_macro_dylib_path": "File: compiled shared library output of proc-macro rule",
- },
-)
+def write_rust_analyzer_spec_file(ctx, attrs, owner, base_info):
+ """Write a rust-analyzer spec info file.
-RustAnalyzerGroupInfo = provider(
- doc = "RustAnalyzerGroupInfo holds multiple RustAnalyzerInfos",
- fields = {
- "deps": "List[RustAnalyzerInfo]: direct dependencies",
- },
-)
+ Args:
+ ctx (ctx): The current rule's context object.
+ attrs (dict): A mapping of attributes.
+ owner (Label): The label of the owner of the spec info.
+ base_info (RustAnalyzerInfo): The data the resulting RustAnalyzerInfo is based on.
+
+ Returns:
+ RustAnalyzerInfo: Info with the embedded spec file.
+ """
+ crate_spec = ctx.actions.declare_file("{}.rust_analyzer_crate_spec.json".format(owner.name))
+
+ rust_analyzer_info = RustAnalyzerInfo(
+ crate = base_info.crate,
+ cfgs = base_info.cfgs,
+ env = base_info.env,
+ deps = base_info.deps,
+ crate_specs = depset(direct = [crate_spec], transitive = [base_info.crate_specs]),
+ proc_macro_dylib_path = base_info.proc_macro_dylib_path,
+ build_info = base_info.build_info,
+ )
+
+ ctx.actions.write(
+ output = crate_spec,
+ content = json.encode_indent(
+ _create_single_crate(
+ ctx,
+ attrs,
+ rust_analyzer_info,
+ ),
+ indent = " " * 4,
+ ),
+ )
+
+ return rust_analyzer_info
def _rust_analyzer_aspect_impl(target, ctx):
if (rust_common.crate_info not in target and
@@ -58,6 +76,9 @@ def _rust_analyzer_aspect_impl(target, ctx):
rust_common.crate_group_info not in target):
return []
+ if RustAnalyzerInfo in target or RustAnalyzerGroupInfo in target:
+ return []
+
toolchain = find_toolchain(ctx)
# Always add `test` & `debug_assertions`. See rust-analyzer source code:
@@ -102,28 +123,7 @@ def _rust_analyzer_aspect_impl(target, ctx):
if RustAnalyzerGroupInfo in ctx.rule.attr.actual:
dep_infos.extend(ctx.rule.attr.actual[RustAnalyzerGroupInfo])
- if ProstProtoInfo in target:
- for info in target[ProstProtoInfo].transitive_dep_infos.to_list():
- crate_info = info.crate_info
- crate_spec = ctx.actions.declare_file(crate_info.owner.name + ".rust_analyzer_crate_spec")
- rust_analyzer_info = RustAnalyzerInfo(
- crate = crate_info,
- cfgs = cfgs,
- env = crate_info.rustc_env,
- deps = [],
- crate_specs = depset(direct = [crate_spec]),
- proc_macro_dylib_path = None,
- build_info = info.build_info,
- )
- ctx.actions.write(
- output = crate_spec,
- content = json.encode(_create_single_crate(ctx, rust_analyzer_info)),
- )
- dep_infos.append(rust_analyzer_info)
-
- if ProstProtoInfo in target:
- crate_info = target[ProstProtoInfo].dep_variant_info.crate_info
- elif rust_common.crate_group_info in target:
+ if rust_common.crate_group_info in target:
return [RustAnalyzerGroupInfo(deps = dep_infos)]
elif rust_common.crate_info in target:
crate_info = target[rust_common.crate_info]
@@ -132,22 +132,15 @@ def _rust_analyzer_aspect_impl(target, ctx):
else:
fail("Unexpected target type: {}".format(target))
- crate_spec = ctx.actions.declare_file(ctx.label.name + ".rust_analyzer_crate_spec")
-
- rust_analyzer_info = RustAnalyzerInfo(
+ rust_analyzer_info = write_rust_analyzer_spec_file(ctx, ctx.rule.attr, ctx.label, RustAnalyzerInfo(
crate = crate_info,
cfgs = cfgs,
env = crate_info.rustc_env,
deps = dep_infos,
- crate_specs = depset(direct = [crate_spec], transitive = [dep.crate_specs for dep in dep_infos]),
+ crate_specs = depset(transitive = [dep.crate_specs for dep in dep_infos]),
proc_macro_dylib_path = find_proc_macro_dylib_path(toolchain, target),
build_info = build_info,
- )
-
- ctx.actions.write(
- output = crate_spec,
- content = json.encode(_create_single_crate(ctx, rust_analyzer_info)),
- )
+ ))
return [
rust_analyzer_info,
@@ -201,12 +194,13 @@ def _crate_id(crate_info):
"""
return "ID-" + crate_info.root.path
-def _create_single_crate(ctx, info):
+def _create_single_crate(ctx, attrs, info):
"""Creates a crate in the rust-project.json format.
Args:
- ctx (ctx): The rule context
- info (RustAnalyzerInfo): RustAnalyzerInfo for the current crate
+ ctx (ctx): The rule context.
+ attrs (dict): A mapping of attributes.
+ info (RustAnalyzerInfo): RustAnalyzerInfo for the current crate.
Returns:
(dict) The crate rust-project.json representation
@@ -240,7 +234,7 @@ def _create_single_crate(ctx, info):
# TODO: The only imagined use case is an env var holding a filename in the workspace passed to a
# macro like include_bytes!. Other use cases might exist that require more complex logic.
- expand_targets = concat([getattr(ctx.rule.attr, attr, []) for attr in ["data", "compile_data"]])
+ expand_targets = concat([getattr(attrs, attr, []) for attr in ["data", "compile_data"]])
crate["env"].update({k: dedup_expand_location(ctx, v, expand_targets) for k, v in info.env.items()})