diff options
-rw-r--r-- | crates/proc_macro_api/src/lib.rs | 73 | ||||
-rw-r--r-- | crates/project_model/src/workspace.rs | 39 | ||||
-rw-r--r-- | crates/rust-analyzer/src/cli/load_cargo.rs | 6 | ||||
-rw-r--r-- | crates/rust-analyzer/src/global_state.rs | 4 | ||||
-rw-r--r-- | crates/rust-analyzer/src/reload.rs | 8 |
5 files changed, 59 insertions, 71 deletions
diff --git a/crates/proc_macro_api/src/lib.rs b/crates/proc_macro_api/src/lib.rs index bf1f90879..0d061fd53 100644 --- a/crates/proc_macro_api/src/lib.rs +++ b/crates/proc_macro_api/src/lib.rs | |||
@@ -58,14 +58,9 @@ impl tt::TokenExpander for ProcMacroProcessExpander { | |||
58 | } | 58 | } |
59 | 59 | ||
60 | #[derive(Debug)] | 60 | #[derive(Debug)] |
61 | enum ProcMacroClientKind { | ||
62 | Process { process: Arc<ProcMacroProcessSrv>, thread: ProcMacroProcessThread }, | ||
63 | Dummy, | ||
64 | } | ||
65 | |||
66 | #[derive(Debug)] | ||
67 | pub struct ProcMacroClient { | 61 | pub struct ProcMacroClient { |
68 | kind: ProcMacroClientKind, | 62 | process: Arc<ProcMacroProcessSrv>, |
63 | thread: ProcMacroProcessThread, | ||
69 | } | 64 | } |
70 | 65 | ||
71 | impl ProcMacroClient { | 66 | impl ProcMacroClient { |
@@ -74,47 +69,35 @@ impl ProcMacroClient { | |||
74 | args: impl IntoIterator<Item = impl AsRef<OsStr>>, | 69 | args: impl IntoIterator<Item = impl AsRef<OsStr>>, |
75 | ) -> io::Result<ProcMacroClient> { | 70 | ) -> io::Result<ProcMacroClient> { |
76 | let (thread, process) = ProcMacroProcessSrv::run(process_path, args)?; | 71 | let (thread, process) = ProcMacroProcessSrv::run(process_path, args)?; |
77 | Ok(ProcMacroClient { | 72 | Ok(ProcMacroClient { process: Arc::new(process), thread }) |
78 | kind: ProcMacroClientKind::Process { process: Arc::new(process), thread }, | ||
79 | }) | ||
80 | } | ||
81 | |||
82 | pub fn dummy() -> ProcMacroClient { | ||
83 | ProcMacroClient { kind: ProcMacroClientKind::Dummy } | ||
84 | } | 73 | } |
85 | 74 | ||
86 | pub fn by_dylib_path(&self, dylib_path: &Path) -> Vec<ProcMacro> { | 75 | pub fn by_dylib_path(&self, dylib_path: &Path) -> Vec<ProcMacro> { |
87 | match &self.kind { | 76 | let macros = match self.process.find_proc_macros(dylib_path) { |
88 | ProcMacroClientKind::Dummy => vec![], | 77 | Err(err) => { |
89 | ProcMacroClientKind::Process { process, .. } => { | 78 | eprintln!("Failed to find proc macros. Error: {:#?}", err); |
90 | let macros = match process.find_proc_macros(dylib_path) { | 79 | return vec![]; |
91 | Err(err) => { | ||
92 | eprintln!("Failed to find proc macros. Error: {:#?}", err); | ||
93 | return vec![]; | ||
94 | } | ||
95 | Ok(macros) => macros, | ||
96 | }; | ||
97 | |||
98 | macros | ||
99 | .into_iter() | ||
100 | .map(|(name, kind)| { | ||
101 | let name = SmolStr::new(&name); | ||
102 | let kind = match kind { | ||
103 | ProcMacroKind::CustomDerive => base_db::ProcMacroKind::CustomDerive, | ||
104 | ProcMacroKind::FuncLike => base_db::ProcMacroKind::FuncLike, | ||
105 | ProcMacroKind::Attr => base_db::ProcMacroKind::Attr, | ||
106 | }; | ||
107 | let expander: Arc<dyn tt::TokenExpander> = | ||
108 | Arc::new(ProcMacroProcessExpander { | ||
109 | process: process.clone(), | ||
110 | name: name.clone(), | ||
111 | dylib_path: dylib_path.into(), | ||
112 | }); | ||
113 | |||
114 | ProcMacro { name, kind, expander } | ||
115 | }) | ||
116 | .collect() | ||
117 | } | 80 | } |
118 | } | 81 | Ok(macros) => macros, |
82 | }; | ||
83 | |||
84 | macros | ||
85 | .into_iter() | ||
86 | .map(|(name, kind)| { | ||
87 | let name = SmolStr::new(&name); | ||
88 | let kind = match kind { | ||
89 | ProcMacroKind::CustomDerive => base_db::ProcMacroKind::CustomDerive, | ||
90 | ProcMacroKind::FuncLike => base_db::ProcMacroKind::FuncLike, | ||
91 | ProcMacroKind::Attr => base_db::ProcMacroKind::Attr, | ||
92 | }; | ||
93 | let expander: Arc<dyn tt::TokenExpander> = Arc::new(ProcMacroProcessExpander { | ||
94 | process: self.process.clone(), | ||
95 | name: name.clone(), | ||
96 | dylib_path: dylib_path.into(), | ||
97 | }); | ||
98 | |||
99 | ProcMacro { name, kind, expander } | ||
100 | }) | ||
101 | .collect() | ||
119 | } | 102 | } |
120 | } | 103 | } |
diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index a71f96164..ab5cbae11 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs | |||
@@ -2,10 +2,14 @@ | |||
2 | //! metadata` or `rust-project.json`) into representation stored in the salsa | 2 | //! metadata` or `rust-project.json`) into representation stored in the salsa |
3 | //! database -- `CrateGraph`. | 3 | //! database -- `CrateGraph`. |
4 | 4 | ||
5 | use std::{fmt, fs, path::Component, process::Command}; | 5 | use std::{ |
6 | fmt, fs, | ||
7 | path::{Component, Path}, | ||
8 | process::Command, | ||
9 | }; | ||
6 | 10 | ||
7 | use anyhow::{Context, Result}; | 11 | use anyhow::{Context, Result}; |
8 | use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId}; | 12 | use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro}; |
9 | use cfg::CfgOptions; | 13 | use cfg::CfgOptions; |
10 | use paths::{AbsPath, AbsPathBuf}; | 14 | use paths::{AbsPath, AbsPathBuf}; |
11 | use proc_macro_api::ProcMacroClient; | 15 | use proc_macro_api::ProcMacroClient; |
@@ -194,15 +198,20 @@ impl ProjectWorkspace { | |||
194 | pub fn to_crate_graph( | 198 | pub fn to_crate_graph( |
195 | &self, | 199 | &self, |
196 | target: Option<&str>, | 200 | target: Option<&str>, |
197 | proc_macro_client: &ProcMacroClient, | 201 | proc_macro_client: Option<&ProcMacroClient>, |
198 | load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, | 202 | load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, |
199 | ) -> CrateGraph { | 203 | ) -> CrateGraph { |
204 | let proc_macro_loader = |path: &Path| match proc_macro_client { | ||
205 | Some(client) => client.by_dylib_path(path), | ||
206 | None => Vec::new(), | ||
207 | }; | ||
208 | |||
200 | let mut crate_graph = match self { | 209 | let mut crate_graph = match self { |
201 | ProjectWorkspace::Json { project, sysroot } => { | 210 | ProjectWorkspace::Json { project, sysroot } => { |
202 | project_json_to_crate_graph(target, proc_macro_client, load, project, sysroot) | 211 | project_json_to_crate_graph(target, &proc_macro_loader, load, project, sysroot) |
203 | } | 212 | } |
204 | ProjectWorkspace::Cargo { cargo, sysroot, rustc } => { | 213 | ProjectWorkspace::Cargo { cargo, sysroot, rustc } => { |
205 | cargo_to_crate_graph(target, proc_macro_client, load, cargo, sysroot, rustc) | 214 | cargo_to_crate_graph(target, &proc_macro_loader, load, cargo, sysroot, rustc) |
206 | } | 215 | } |
207 | }; | 216 | }; |
208 | if crate_graph.patch_cfg_if() { | 217 | if crate_graph.patch_cfg_if() { |
@@ -216,7 +225,7 @@ impl ProjectWorkspace { | |||
216 | 225 | ||
217 | fn project_json_to_crate_graph( | 226 | fn project_json_to_crate_graph( |
218 | target: Option<&str>, | 227 | target: Option<&str>, |
219 | proc_macro_client: &ProcMacroClient, | 228 | proc_macro_loader: &dyn Fn(&Path) -> Vec<ProcMacro>, |
220 | load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, | 229 | load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, |
221 | project: &ProjectJson, | 230 | project: &ProjectJson, |
222 | sysroot: &Option<Sysroot>, | 231 | sysroot: &Option<Sysroot>, |
@@ -236,8 +245,7 @@ fn project_json_to_crate_graph( | |||
236 | }) | 245 | }) |
237 | .map(|(crate_id, krate, file_id)| { | 246 | .map(|(crate_id, krate, file_id)| { |
238 | let env = krate.env.clone().into_iter().collect(); | 247 | let env = krate.env.clone().into_iter().collect(); |
239 | let proc_macro = | 248 | let proc_macro = krate.proc_macro_dylib_path.clone().map(|it| proc_macro_loader(&it)); |
240 | krate.proc_macro_dylib_path.clone().map(|it| proc_macro_client.by_dylib_path(&it)); | ||
241 | 249 | ||
242 | let target = krate.target.as_deref().or(target); | 250 | let target = krate.target.as_deref().or(target); |
243 | let target_cfgs = | 251 | let target_cfgs = |
@@ -279,7 +287,7 @@ fn project_json_to_crate_graph( | |||
279 | 287 | ||
280 | fn cargo_to_crate_graph( | 288 | fn cargo_to_crate_graph( |
281 | target: Option<&str>, | 289 | target: Option<&str>, |
282 | proc_macro_client: &ProcMacroClient, | 290 | proc_macro_loader: &dyn Fn(&Path) -> Vec<ProcMacro>, |
283 | load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, | 291 | load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, |
284 | cargo: &CargoWorkspace, | 292 | cargo: &CargoWorkspace, |
285 | sysroot: &Sysroot, | 293 | sysroot: &Sysroot, |
@@ -309,7 +317,7 @@ fn cargo_to_crate_graph( | |||
309 | &mut crate_graph, | 317 | &mut crate_graph, |
310 | &cargo[pkg], | 318 | &cargo[pkg], |
311 | &cfg_options, | 319 | &cfg_options, |
312 | proc_macro_client, | 320 | proc_macro_loader, |
313 | file_id, | 321 | file_id, |
314 | ); | 322 | ); |
315 | if cargo[tgt].kind == TargetKind::Lib { | 323 | if cargo[tgt].kind == TargetKind::Lib { |
@@ -385,7 +393,7 @@ fn cargo_to_crate_graph( | |||
385 | &mut crate_graph, | 393 | &mut crate_graph, |
386 | &rustc_workspace[pkg], | 394 | &rustc_workspace[pkg], |
387 | &cfg_options, | 395 | &cfg_options, |
388 | proc_macro_client, | 396 | proc_macro_loader, |
389 | file_id, | 397 | file_id, |
390 | ); | 398 | ); |
391 | pkg_to_lib_crate.insert(pkg, crate_id); | 399 | pkg_to_lib_crate.insert(pkg, crate_id); |
@@ -433,7 +441,7 @@ fn add_target_crate_root( | |||
433 | crate_graph: &mut CrateGraph, | 441 | crate_graph: &mut CrateGraph, |
434 | pkg: &cargo_workspace::PackageData, | 442 | pkg: &cargo_workspace::PackageData, |
435 | cfg_options: &CfgOptions, | 443 | cfg_options: &CfgOptions, |
436 | proc_macro_client: &ProcMacroClient, | 444 | proc_macro_loader: &dyn Fn(&Path) -> Vec<ProcMacro>, |
437 | file_id: FileId, | 445 | file_id: FileId, |
438 | ) -> CrateId { | 446 | ) -> CrateId { |
439 | let edition = pkg.edition; | 447 | let edition = pkg.edition; |
@@ -452,11 +460,8 @@ fn add_target_crate_root( | |||
452 | env.set("OUT_DIR", out_dir); | 460 | env.set("OUT_DIR", out_dir); |
453 | } | 461 | } |
454 | } | 462 | } |
455 | let proc_macro = pkg | 463 | let proc_macro = |
456 | .proc_macro_dylib_path | 464 | pkg.proc_macro_dylib_path.as_ref().map(|it| proc_macro_loader(&it)).unwrap_or_default(); |
457 | .as_ref() | ||
458 | .map(|it| proc_macro_client.by_dylib_path(&it)) | ||
459 | .unwrap_or_default(); | ||
460 | 465 | ||
461 | let display_name = CrateDisplayName::from_canonical_name(pkg.name.clone()); | 466 | let display_name = CrateDisplayName::from_canonical_name(pkg.name.clone()); |
462 | let crate_id = crate_graph.add_crate_root( | 467 | let crate_id = crate_graph.add_crate_root( |
diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index 76526c66c..d51f4a93a 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs | |||
@@ -33,12 +33,12 @@ pub fn load_cargo( | |||
33 | 33 | ||
34 | let proc_macro_client = if with_proc_macro { | 34 | let proc_macro_client = if with_proc_macro { |
35 | let path = std::env::current_exe()?; | 35 | let path = std::env::current_exe()?; |
36 | ProcMacroClient::extern_process(path, &["proc-macro"]).unwrap() | 36 | Some(ProcMacroClient::extern_process(path, &["proc-macro"]).unwrap()) |
37 | } else { | 37 | } else { |
38 | ProcMacroClient::dummy() | 38 | None |
39 | }; | 39 | }; |
40 | 40 | ||
41 | let crate_graph = ws.to_crate_graph(None, &proc_macro_client, &mut |path: &AbsPath| { | 41 | let crate_graph = ws.to_crate_graph(None, proc_macro_client.as_ref(), &mut |path: &AbsPath| { |
42 | let contents = loader.load_sync(path); | 42 | let contents = loader.load_sync(path); |
43 | let path = vfs::VfsPath::from(path.to_path_buf()); | 43 | let path = vfs::VfsPath::from(path.to_path_buf()); |
44 | vfs.set_file_contents(path.clone(), contents); | 44 | vfs.set_file_contents(path.clone(), contents); |
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index defe11c55..a27495d0d 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs | |||
@@ -75,7 +75,7 @@ pub(crate) struct GlobalState { | |||
75 | pub(crate) shutdown_requested: bool, | 75 | pub(crate) shutdown_requested: bool, |
76 | pub(crate) status: Status, | 76 | pub(crate) status: Status, |
77 | pub(crate) source_root_config: SourceRootConfig, | 77 | pub(crate) source_root_config: SourceRootConfig, |
78 | pub(crate) proc_macro_client: ProcMacroClient, | 78 | pub(crate) proc_macro_client: Option<ProcMacroClient>, |
79 | pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>, | 79 | pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>, |
80 | latest_requests: Arc<RwLock<LatestRequests>>, | 80 | latest_requests: Arc<RwLock<LatestRequests>>, |
81 | } | 81 | } |
@@ -127,7 +127,7 @@ impl GlobalState { | |||
127 | shutdown_requested: false, | 127 | shutdown_requested: false, |
128 | status: Status::default(), | 128 | status: Status::default(), |
129 | source_root_config: SourceRootConfig::default(), | 129 | source_root_config: SourceRootConfig::default(), |
130 | proc_macro_client: ProcMacroClient::dummy(), | 130 | proc_macro_client: None, |
131 | workspaces: Arc::new(Vec::new()), | 131 | workspaces: Arc::new(Vec::new()), |
132 | latest_requests: Default::default(), | 132 | latest_requests: Default::default(), |
133 | } | 133 | } |
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index b2d35f535..79e39e3a5 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs | |||
@@ -171,16 +171,16 @@ impl GlobalState { | |||
171 | let project_folders = ProjectFolders::new(&workspaces); | 171 | let project_folders = ProjectFolders::new(&workspaces); |
172 | 172 | ||
173 | self.proc_macro_client = match &self.config.proc_macro_srv { | 173 | self.proc_macro_client = match &self.config.proc_macro_srv { |
174 | None => ProcMacroClient::dummy(), | 174 | None => None, |
175 | Some((path, args)) => match ProcMacroClient::extern_process(path.into(), args) { | 175 | Some((path, args)) => match ProcMacroClient::extern_process(path.into(), args) { |
176 | Ok(it) => it, | 176 | Ok(it) => Some(it), |
177 | Err(err) => { | 177 | Err(err) => { |
178 | log::error!( | 178 | log::error!( |
179 | "Failed to run proc_macro_srv from path {}, error: {:?}", | 179 | "Failed to run proc_macro_srv from path {}, error: {:?}", |
180 | path.display(), | 180 | path.display(), |
181 | err | 181 | err |
182 | ); | 182 | ); |
183 | ProcMacroClient::dummy() | 183 | None |
184 | } | 184 | } |
185 | }, | 185 | }, |
186 | }; | 186 | }; |
@@ -212,7 +212,7 @@ impl GlobalState { | |||
212 | for ws in workspaces.iter() { | 212 | for ws in workspaces.iter() { |
213 | crate_graph.extend(ws.to_crate_graph( | 213 | crate_graph.extend(ws.to_crate_graph( |
214 | self.config.cargo.target.as_deref(), | 214 | self.config.cargo.target.as_deref(), |
215 | &self.proc_macro_client, | 215 | self.proc_macro_client.as_ref(), |
216 | &mut load, | 216 | &mut load, |
217 | )); | 217 | )); |
218 | } | 218 | } |