@@ -20,9 +20,9 @@ given targets. This file can be consumed by rust-analyzer as an alternative
20
20
to Cargo.toml files.
21
21
"""
22
22
23
- load ("//proto/prost:providers.bzl" , "ProstProtoInfo" )
24
23
load ("//rust/platform:triple_mappings.bzl" , "system_to_dylib_ext" , "triple_to_system" )
25
24
load ("//rust/private:common.bzl" , "rust_common" )
25
+ load ("//rust/private:providers.bzl" , "RustAnalyzerGroupInfo" , "RustAnalyzerInfo" )
26
26
load ("//rust/private:rustc.bzl" , "BuildInfo" )
27
27
load (
28
28
"//rust/private:utils.bzl" ,
@@ -32,32 +32,53 @@ load(
32
32
"find_toolchain" ,
33
33
)
34
34
35
- RustAnalyzerInfo = provider (
36
- doc = "RustAnalyzerInfo holds rust crate metadata for targets" ,
37
- fields = {
38
- "build_info" : "BuildInfo: build info for this crate if present" ,
39
- "cfgs" : "List[String]: features or other compilation --cfg settings" ,
40
- "crate" : "rust_common.crate_info" ,
41
- "crate_specs" : "Depset[File]: transitive closure of OutputGroupInfo files" ,
42
- "deps" : "List[RustAnalyzerInfo]: direct dependencies" ,
43
- "env" : "Dict{String: String}: Environment variables, used for the `env!` macro" ,
44
- "proc_macro_dylib_path" : "File: compiled shared library output of proc-macro rule" ,
45
- },
46
- )
35
+ def write_rust_analyzer_spec_file (ctx , attrs , owner , base_info ):
36
+ """Write a rust-analyzer spec info file.
47
37
48
- RustAnalyzerGroupInfo = provider (
49
- doc = "RustAnalyzerGroupInfo holds multiple RustAnalyzerInfos" ,
50
- fields = {
51
- "deps" : "List[RustAnalyzerInfo]: direct dependencies" ,
52
- },
53
- )
38
+ Args:
39
+ ctx (ctx): The current rule's context object.
40
+ attrs (dict): A mapping of attributes.
41
+ owner (Label): The label of the owner of the spec info.
42
+ base_info (RustAnalyzerInfo): The data the resulting RustAnalyzerInfo is based on.
43
+
44
+ Returns:
45
+ RustAnalyzerInfo: Info with the embedded spec file.
46
+ """
47
+ crate_spec = ctx .actions .declare_file ("{}.rust_analyzer_crate_spec.json" .format (owner .name ))
48
+
49
+ rust_analyzer_info = RustAnalyzerInfo (
50
+ crate = base_info .crate ,
51
+ cfgs = base_info .cfgs ,
52
+ env = base_info .env ,
53
+ deps = base_info .deps ,
54
+ crate_specs = depset (direct = [crate_spec ], transitive = [base_info .crate_specs ]),
55
+ proc_macro_dylib_path = base_info .proc_macro_dylib_path ,
56
+ build_info = base_info .build_info ,
57
+ )
58
+
59
+ ctx .actions .write (
60
+ output = crate_spec ,
61
+ content = json .encode_indent (
62
+ _create_single_crate (
63
+ ctx ,
64
+ attrs ,
65
+ rust_analyzer_info ,
66
+ ),
67
+ indent = " " * 4 ,
68
+ ),
69
+ )
70
+
71
+ return rust_analyzer_info
54
72
55
73
def _rust_analyzer_aspect_impl (target , ctx ):
56
74
if (rust_common .crate_info not in target and
57
75
rust_common .test_crate_info not in target and
58
76
rust_common .crate_group_info not in target ):
59
77
return []
60
78
79
+ if RustAnalyzerInfo in target or RustAnalyzerGroupInfo in target :
80
+ return []
81
+
61
82
toolchain = find_toolchain (ctx )
62
83
63
84
# Always add `test` & `debug_assertions`. See rust-analyzer source code:
@@ -102,28 +123,7 @@ def _rust_analyzer_aspect_impl(target, ctx):
102
123
if RustAnalyzerGroupInfo in ctx .rule .attr .actual :
103
124
dep_infos .extend (ctx .rule .attr .actual [RustAnalyzerGroupInfo ])
104
125
105
- if ProstProtoInfo in target :
106
- for info in target [ProstProtoInfo ].transitive_dep_infos .to_list ():
107
- crate_info = info .crate_info
108
- crate_spec = ctx .actions .declare_file (crate_info .owner .name + ".rust_analyzer_crate_spec" )
109
- rust_analyzer_info = RustAnalyzerInfo (
110
- crate = crate_info ,
111
- cfgs = cfgs ,
112
- env = crate_info .rustc_env ,
113
- deps = [],
114
- crate_specs = depset (direct = [crate_spec ]),
115
- proc_macro_dylib_path = None ,
116
- build_info = info .build_info ,
117
- )
118
- ctx .actions .write (
119
- output = crate_spec ,
120
- content = json .encode (_create_single_crate (ctx , rust_analyzer_info )),
121
- )
122
- dep_infos .append (rust_analyzer_info )
123
-
124
- if ProstProtoInfo in target :
125
- crate_info = target [ProstProtoInfo ].dep_variant_info .crate_info
126
- elif rust_common .crate_group_info in target :
126
+ if rust_common .crate_group_info in target :
127
127
return [RustAnalyzerGroupInfo (deps = dep_infos )]
128
128
elif rust_common .crate_info in target :
129
129
crate_info = target [rust_common .crate_info ]
@@ -132,22 +132,15 @@ def _rust_analyzer_aspect_impl(target, ctx):
132
132
else :
133
133
fail ("Unexpected target type: {}" .format (target ))
134
134
135
- crate_spec = ctx .actions .declare_file (ctx .label .name + ".rust_analyzer_crate_spec" )
136
-
137
- rust_analyzer_info = RustAnalyzerInfo (
135
+ rust_analyzer_info = write_rust_analyzer_spec_file (ctx , ctx .rule .attr , ctx .label , RustAnalyzerInfo (
138
136
crate = crate_info ,
139
137
cfgs = cfgs ,
140
138
env = crate_info .rustc_env ,
141
139
deps = dep_infos ,
142
- crate_specs = depset (direct = [ crate_spec ], transitive = [dep .crate_specs for dep in dep_infos ]),
140
+ crate_specs = depset (transitive = [dep .crate_specs for dep in dep_infos ]),
143
141
proc_macro_dylib_path = find_proc_macro_dylib_path (toolchain , target ),
144
142
build_info = build_info ,
145
- )
146
-
147
- ctx .actions .write (
148
- output = crate_spec ,
149
- content = json .encode (_create_single_crate (ctx , rust_analyzer_info )),
150
- )
143
+ ))
151
144
152
145
return [
153
146
rust_analyzer_info ,
@@ -201,12 +194,13 @@ def _crate_id(crate_info):
201
194
"""
202
195
return "ID-" + crate_info .root .path
203
196
204
- def _create_single_crate (ctx , info ):
197
+ def _create_single_crate (ctx , attrs , info ):
205
198
"""Creates a crate in the rust-project.json format.
206
199
207
200
Args:
208
- ctx (ctx): The rule context
209
- info (RustAnalyzerInfo): RustAnalyzerInfo for the current crate
201
+ ctx (ctx): The rule context.
202
+ attrs (dict): A mapping of attributes.
203
+ info (RustAnalyzerInfo): RustAnalyzerInfo for the current crate.
210
204
211
205
Returns:
212
206
(dict) The crate rust-project.json representation
@@ -240,7 +234,7 @@ def _create_single_crate(ctx, info):
240
234
241
235
# TODO: The only imagined use case is an env var holding a filename in the workspace passed to a
242
236
# macro like include_bytes!. Other use cases might exist that require more complex logic.
243
- expand_targets = concat ([getattr (ctx . rule . attr , attr , []) for attr in ["data" , "compile_data" ]])
237
+ expand_targets = concat ([getattr (attrs , attr , []) for attr in ["data" , "compile_data" ]])
244
238
245
239
crate ["env" ].update ({k : dedup_expand_location (ctx , v , expand_targets ) for k , v in info .env .items ()})
246
240
0 commit comments