Skip to content

Commit 6bf9700

Browse files
authored
Merge pull request #20342 from Veykril/push-zysqtqskuxvr
Reorganize proc-macro-srv more, add `--format` and `--version` args
2 parents cd0f643 + 7543395 commit 6bf9700

File tree

20 files changed

+848
-425
lines changed

20 files changed

+848
-425
lines changed

src/tools/rust-analyzer/Cargo.lock

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ version = "0.2.21"
2323
source = "registry+https://github.com/rust-lang/crates.io-index"
2424
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
2525

26+
[[package]]
27+
name = "anstyle"
28+
version = "1.0.11"
29+
source = "registry+https://github.com/rust-lang/crates.io-index"
30+
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
31+
2632
[[package]]
2733
name = "anyhow"
2834
version = "1.0.98"
@@ -44,6 +50,15 @@ version = "0.7.6"
4450
source = "registry+https://github.com/rust-lang/crates.io-index"
4551
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
4652

53+
[[package]]
54+
name = "atomic-polyfill"
55+
version = "1.0.3"
56+
source = "registry+https://github.com/rust-lang/crates.io-index"
57+
checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
58+
dependencies = [
59+
"critical-section",
60+
]
61+
4762
[[package]]
4863
name = "autocfg"
4964
version = "1.4.0"
@@ -119,6 +134,12 @@ version = "0.2.13"
119134
source = "registry+https://github.com/rust-lang/crates.io-index"
120135
checksum = "26c4925bc979b677330a8c7fe7a8c94af2dbb4a2d37b4a20a80d884400f46baa"
121136

137+
[[package]]
138+
name = "byteorder"
139+
version = "1.5.0"
140+
source = "registry+https://github.com/rust-lang/crates.io-index"
141+
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
142+
122143
[[package]]
123144
name = "camino"
124145
version = "1.1.10"
@@ -287,6 +308,40 @@ dependencies = [
287308
"tracing",
288309
]
289310

311+
[[package]]
312+
name = "clap"
313+
version = "4.5.42"
314+
source = "registry+https://github.com/rust-lang/crates.io-index"
315+
checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882"
316+
dependencies = [
317+
"clap_builder",
318+
]
319+
320+
[[package]]
321+
name = "clap_builder"
322+
version = "4.5.42"
323+
source = "registry+https://github.com/rust-lang/crates.io-index"
324+
checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966"
325+
dependencies = [
326+
"anstyle",
327+
"clap_lex",
328+
]
329+
330+
[[package]]
331+
name = "clap_lex"
332+
version = "0.7.5"
333+
source = "registry+https://github.com/rust-lang/crates.io-index"
334+
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
335+
336+
[[package]]
337+
name = "cobs"
338+
version = "0.3.0"
339+
source = "registry+https://github.com/rust-lang/crates.io-index"
340+
checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
341+
dependencies = [
342+
"thiserror 2.0.12",
343+
]
344+
290345
[[package]]
291346
name = "countme"
292347
version = "3.0.1"
@@ -308,6 +363,12 @@ dependencies = [
308363
"cfg-if",
309364
]
310365

366+
[[package]]
367+
name = "critical-section"
368+
version = "1.2.0"
369+
source = "registry+https://github.com/rust-lang/crates.io-index"
370+
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
371+
311372
[[package]]
312373
name = "crossbeam-channel"
313374
version = "0.5.15"
@@ -565,6 +626,15 @@ version = "0.31.1"
565626
source = "registry+https://github.com/rust-lang/crates.io-index"
566627
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
567628

629+
[[package]]
630+
name = "hash32"
631+
version = "0.2.1"
632+
source = "registry+https://github.com/rust-lang/crates.io-index"
633+
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
634+
dependencies = [
635+
"byteorder",
636+
]
637+
568638
[[package]]
569639
name = "hashbrown"
570640
version = "0.14.5"
@@ -591,6 +661,20 @@ dependencies = [
591661
"hashbrown 0.15.4",
592662
]
593663

664+
[[package]]
665+
name = "heapless"
666+
version = "0.7.17"
667+
source = "registry+https://github.com/rust-lang/crates.io-index"
668+
checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
669+
dependencies = [
670+
"atomic-polyfill",
671+
"hash32",
672+
"rustc_version",
673+
"serde",
674+
"spin",
675+
"stable_deref_trait",
676+
]
677+
594678
[[package]]
595679
name = "hermit-abi"
596680
version = "0.5.2"
@@ -1561,6 +1645,17 @@ version = "1.11.1"
15611645
source = "registry+https://github.com/rust-lang/crates.io-index"
15621646
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
15631647

1648+
[[package]]
1649+
name = "postcard"
1650+
version = "1.1.3"
1651+
source = "registry+https://github.com/rust-lang/crates.io-index"
1652+
checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
1653+
dependencies = [
1654+
"cobs",
1655+
"heapless",
1656+
"serde",
1657+
]
1658+
15641659
[[package]]
15651660
name = "potential_utf"
15661661
version = "0.1.2"
@@ -1608,13 +1703,16 @@ dependencies = [
16081703
"ra-ap-rustc_lexer 0.123.0",
16091704
"span",
16101705
"syntax-bridge",
1706+
"temp-dir",
16111707
"tt",
16121708
]
16131709

16141710
[[package]]
16151711
name = "proc-macro-srv-cli"
16161712
version = "0.0.0"
16171713
dependencies = [
1714+
"clap",
1715+
"postcard",
16181716
"proc-macro-api",
16191717
"proc-macro-srv",
16201718
"tt",
@@ -1991,6 +2089,15 @@ dependencies = [
19912089
"smallvec",
19922090
]
19932091

2092+
[[package]]
2093+
name = "rustc_version"
2094+
version = "0.4.1"
2095+
source = "registry+https://github.com/rust-lang/crates.io-index"
2096+
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
2097+
dependencies = [
2098+
"semver",
2099+
]
2100+
19942101
[[package]]
19952102
name = "ryu"
19962103
version = "1.0.20"
@@ -2208,6 +2315,15 @@ dependencies = [
22082315
"vfs",
22092316
]
22102317

2318+
[[package]]
2319+
name = "spin"
2320+
version = "0.9.8"
2321+
source = "registry+https://github.com/rust-lang/crates.io-index"
2322+
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
2323+
dependencies = [
2324+
"lock_api",
2325+
]
2326+
22112327
[[package]]
22122328
name = "stable_deref_trait"
22132329
version = "1.2.0"

src/tools/rust-analyzer/crates/load-cargo/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ impl ProcMacroExpander for Expander {
533533
current_dir,
534534
) {
535535
Ok(Ok(subtree)) => Ok(subtree),
536-
Ok(Err(err)) => Err(ProcMacroExpansionError::Panic(err.0)),
536+
Ok(Err(err)) => Err(ProcMacroExpansionError::Panic(err)),
537537
Err(err) => Err(ProcMacroExpansionError::System(err.to_string())),
538538
}
539539
}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
//! The initial proc-macro-srv protocol, soon to be deprecated.
2+
3+
pub mod json;
4+
pub mod msg;
5+
6+
use std::{
7+
io::{BufRead, Write},
8+
sync::Arc,
9+
};
10+
11+
use paths::AbsPath;
12+
use span::Span;
13+
14+
use crate::{
15+
ProcMacro, ProcMacroKind, ServerError,
16+
legacy_protocol::{
17+
json::{read_json, write_json},
18+
msg::{
19+
ExpandMacro, ExpandMacroData, ExpnGlobals, FlatTree, Message, Request, Response,
20+
ServerConfig, SpanDataIndexMap, deserialize_span_data_index_map,
21+
flat::serialize_span_data_index_map,
22+
},
23+
},
24+
process::ProcMacroServerProcess,
25+
version,
26+
};
27+
28+
pub(crate) use crate::legacy_protocol::msg::SpanMode;
29+
30+
/// Legacy span type, only defined here as it is still used by the proc-macro server.
31+
/// While rust-analyzer doesn't use this anymore at all, RustRover relies on the legacy type for
32+
/// proc-macro expansion.
33+
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
34+
pub struct SpanId(pub u32);
35+
36+
impl std::fmt::Debug for SpanId {
37+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38+
self.0.fmt(f)
39+
}
40+
}
41+
42+
pub(crate) fn version_check(srv: &ProcMacroServerProcess) -> Result<u32, ServerError> {
43+
let request = Request::ApiVersionCheck {};
44+
let response = send_task(srv, request)?;
45+
46+
match response {
47+
Response::ApiVersionCheck(version) => Ok(version),
48+
_ => Err(ServerError { message: "unexpected response".to_owned(), io: None }),
49+
}
50+
}
51+
52+
/// Enable support for rust-analyzer span mode if the server supports it.
53+
pub(crate) fn enable_rust_analyzer_spans(
54+
srv: &ProcMacroServerProcess,
55+
) -> Result<SpanMode, ServerError> {
56+
let request = Request::SetConfig(ServerConfig { span_mode: SpanMode::RustAnalyzer });
57+
let response = send_task(srv, request)?;
58+
59+
match response {
60+
Response::SetConfig(ServerConfig { span_mode }) => Ok(span_mode),
61+
_ => Err(ServerError { message: "unexpected response".to_owned(), io: None }),
62+
}
63+
}
64+
65+
/// Finds proc-macros in a given dynamic library.
66+
pub(crate) fn find_proc_macros(
67+
srv: &ProcMacroServerProcess,
68+
dylib_path: &AbsPath,
69+
) -> Result<Result<Vec<(String, ProcMacroKind)>, String>, ServerError> {
70+
let request = Request::ListMacros { dylib_path: dylib_path.to_path_buf().into() };
71+
72+
let response = send_task(srv, request)?;
73+
74+
match response {
75+
Response::ListMacros(it) => Ok(it),
76+
_ => Err(ServerError { message: "unexpected response".to_owned(), io: None }),
77+
}
78+
}
79+
80+
pub(crate) fn expand(
81+
proc_macro: &ProcMacro,
82+
subtree: tt::SubtreeView<'_, Span>,
83+
attr: Option<tt::SubtreeView<'_, Span>>,
84+
env: Vec<(String, String)>,
85+
def_site: Span,
86+
call_site: Span,
87+
mixed_site: Span,
88+
current_dir: String,
89+
) -> Result<Result<tt::TopSubtree<span::SpanData<span::SyntaxContext>>, String>, crate::ServerError>
90+
{
91+
let version = proc_macro.process.version();
92+
let mut span_data_table = SpanDataIndexMap::default();
93+
let def_site = span_data_table.insert_full(def_site).0;
94+
let call_site = span_data_table.insert_full(call_site).0;
95+
let mixed_site = span_data_table.insert_full(mixed_site).0;
96+
let task = ExpandMacro {
97+
data: ExpandMacroData {
98+
macro_body: FlatTree::new(subtree, version, &mut span_data_table),
99+
macro_name: proc_macro.name.to_string(),
100+
attributes: attr.map(|subtree| FlatTree::new(subtree, version, &mut span_data_table)),
101+
has_global_spans: ExpnGlobals {
102+
serialize: version >= version::HAS_GLOBAL_SPANS,
103+
def_site,
104+
call_site,
105+
mixed_site,
106+
},
107+
span_data_table: if proc_macro.process.rust_analyzer_spans() {
108+
serialize_span_data_index_map(&span_data_table)
109+
} else {
110+
Vec::new()
111+
},
112+
},
113+
lib: proc_macro.dylib_path.to_path_buf().into(),
114+
env,
115+
current_dir: Some(current_dir),
116+
};
117+
118+
let response = send_task(&proc_macro.process, Request::ExpandMacro(Box::new(task)))?;
119+
120+
match response {
121+
Response::ExpandMacro(it) => Ok(it
122+
.map(|tree| {
123+
let mut expanded = FlatTree::to_subtree_resolved(tree, version, &span_data_table);
124+
if proc_macro.needs_fixup_change() {
125+
proc_macro.change_fixup_to_match_old_server(&mut expanded);
126+
}
127+
expanded
128+
})
129+
.map_err(|msg| msg.0)),
130+
Response::ExpandMacroExtended(it) => Ok(it
131+
.map(|resp| {
132+
let mut expanded = FlatTree::to_subtree_resolved(
133+
resp.tree,
134+
version,
135+
&deserialize_span_data_index_map(&resp.span_data_table),
136+
);
137+
if proc_macro.needs_fixup_change() {
138+
proc_macro.change_fixup_to_match_old_server(&mut expanded);
139+
}
140+
expanded
141+
})
142+
.map_err(|msg| msg.0)),
143+
_ => Err(ServerError { message: "unexpected response".to_owned(), io: None }),
144+
}
145+
}
146+
147+
/// Sends a request to the proc-macro server and waits for a response.
148+
fn send_task(srv: &ProcMacroServerProcess, req: Request) -> Result<Response, ServerError> {
149+
if let Some(server_error) = srv.exited() {
150+
return Err(server_error.clone());
151+
}
152+
153+
srv.send_task(send_request, req)
154+
}
155+
156+
/// Sends a request to the server and reads the response.
157+
fn send_request(
158+
mut writer: &mut dyn Write,
159+
mut reader: &mut dyn BufRead,
160+
req: Request,
161+
buf: &mut String,
162+
) -> Result<Option<Response>, ServerError> {
163+
req.write(write_json, &mut writer).map_err(|err| ServerError {
164+
message: "failed to write request".into(),
165+
io: Some(Arc::new(err)),
166+
})?;
167+
let res = Response::read(read_json, &mut reader, buf).map_err(|err| ServerError {
168+
message: "failed to read response".into(),
169+
io: Some(Arc::new(err)),
170+
})?;
171+
Ok(res)
172+
}

0 commit comments

Comments
 (0)