aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/proc_macro_api/src/lib.rs73
-rw-r--r--crates/project_model/src/workspace.rs39
-rw-r--r--crates/rust-analyzer/src/cli/load_cargo.rs6
-rw-r--r--crates/rust-analyzer/src/global_state.rs4
-rw-r--r--crates/rust-analyzer/src/reload.rs8
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)]
61enum ProcMacroClientKind {
62 Process { process: Arc<ProcMacroProcessSrv>, thread: ProcMacroProcessThread },
63 Dummy,
64}
65
66#[derive(Debug)]
67pub struct ProcMacroClient { 61pub struct ProcMacroClient {
68 kind: ProcMacroClientKind, 62 process: Arc<ProcMacroProcessSrv>,
63 thread: ProcMacroProcessThread,
69} 64}
70 65
71impl ProcMacroClient { 66impl 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
5use std::{fmt, fs, path::Component, process::Command}; 5use std::{
6 fmt, fs,
7 path::{Component, Path},
8 process::Command,
9};
6 10
7use anyhow::{Context, Result}; 11use anyhow::{Context, Result};
8use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId}; 12use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro};
9use cfg::CfgOptions; 13use cfg::CfgOptions;
10use paths::{AbsPath, AbsPathBuf}; 14use paths::{AbsPath, AbsPathBuf};
11use proc_macro_api::ProcMacroClient; 15use 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
217fn project_json_to_crate_graph( 226fn 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
280fn cargo_to_crate_graph( 288fn 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 }