aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_project_model/src
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2020-03-18 12:56:46 +0000
committerEdwin Cheng <[email protected]>2020-03-25 19:29:45 +0000
commitd0b6ed4441469acfb6bc6555d78abf12637b6cf4 (patch)
treea4b39b33590c472a68fd76ceae96732e9cb54ebb /crates/ra_project_model/src
parenta617f24eae6c02f087759312e9aa08507fbecdf0 (diff)
Add ProcMacroClient
Diffstat (limited to 'crates/ra_project_model/src')
-rw-r--r--crates/ra_project_model/src/cargo_workspace.rs31
-rw-r--r--crates/ra_project_model/src/json_project.rs1
-rw-r--r--crates/ra_project_model/src/lib.rs41
3 files changed, 64 insertions, 9 deletions
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs
index c7f9bd873..291594e2a 100644
--- a/crates/ra_project_model/src/cargo_workspace.rs
+++ b/crates/ra_project_model/src/cargo_workspace.rs
@@ -83,6 +83,7 @@ pub struct PackageData {
83 pub edition: Edition, 83 pub edition: Edition,
84 pub features: Vec<String>, 84 pub features: Vec<String>,
85 pub out_dir: Option<PathBuf>, 85 pub out_dir: Option<PathBuf>,
86 pub proc_macro_dylib_path: Option<PathBuf>,
86} 87}
87 88
88#[derive(Debug, Clone)] 89#[derive(Debug, Clone)]
@@ -158,8 +159,11 @@ impl CargoWorkspace {
158 })?; 159 })?;
159 160
160 let mut out_dir_by_id = FxHashMap::default(); 161 let mut out_dir_by_id = FxHashMap::default();
162 let mut proc_macro_dylib_paths = FxHashMap::default();
161 if cargo_features.load_out_dirs_from_check { 163 if cargo_features.load_out_dirs_from_check {
162 out_dir_by_id = load_out_dirs(cargo_toml, cargo_features); 164 let resources = load_extern_resources(cargo_toml, cargo_features);
165 out_dir_by_id = resources.out_dirs;
166 proc_macro_dylib_paths = resources.proc_dylib_paths;
163 } 167 }
164 168
165 let mut pkg_by_id = FxHashMap::default(); 169 let mut pkg_by_id = FxHashMap::default();
@@ -183,6 +187,7 @@ impl CargoWorkspace {
183 dependencies: Vec::new(), 187 dependencies: Vec::new(),
184 features: Vec::new(), 188 features: Vec::new(),
185 out_dir: out_dir_by_id.get(&id).cloned(), 189 out_dir: out_dir_by_id.get(&id).cloned(),
190 proc_macro_dylib_path: proc_macro_dylib_paths.get(&id).cloned(),
186 }); 191 });
187 let pkg_data = &mut packages[pkg]; 192 let pkg_data = &mut packages[pkg];
188 pkg_by_id.insert(id, pkg); 193 pkg_by_id.insert(id, pkg);
@@ -246,10 +251,13 @@ impl CargoWorkspace {
246 } 251 }
247} 252}
248 253
249pub fn load_out_dirs( 254#[derive(Debug, Clone, Default)]
250 cargo_toml: &Path, 255pub struct ExternResources {
251 cargo_features: &CargoFeatures, 256 out_dirs: FxHashMap<PackageId, PathBuf>,
252) -> FxHashMap<PackageId, PathBuf> { 257 proc_dylib_paths: FxHashMap<PackageId, PathBuf>,
258}
259
260pub fn load_extern_resources(cargo_toml: &Path, cargo_features: &CargoFeatures) -> ExternResources {
253 let mut args: Vec<String> = vec![ 261 let mut args: Vec<String> = vec![
254 "check".to_string(), 262 "check".to_string(),
255 "--message-format=json".to_string(), 263 "--message-format=json".to_string(),
@@ -267,14 +275,21 @@ pub fn load_out_dirs(
267 args.extend(cargo_features.features.iter().cloned()); 275 args.extend(cargo_features.features.iter().cloned());
268 } 276 }
269 277
270 let mut acc = FxHashMap::default(); 278 let mut acc = ExternResources::default();
271 let res = run_cargo(&args, cargo_toml.parent(), &mut |message| { 279 let res = run_cargo(&args, cargo_toml.parent(), &mut |message| {
272 match message { 280 match message {
273 Message::BuildScriptExecuted(BuildScript { package_id, out_dir, .. }) => { 281 Message::BuildScriptExecuted(BuildScript { package_id, out_dir, .. }) => {
274 acc.insert(package_id, out_dir); 282 acc.out_dirs.insert(package_id, out_dir);
275 } 283 }
276 284
277 Message::CompilerArtifact(_) => (), 285 Message::CompilerArtifact(message) => {
286 if message.target.kind.contains(&"proc-macro".to_string()) {
287 let package_id = message.package_id;
288 if let Some(filename) = message.filenames.get(0) {
289 acc.proc_dylib_paths.insert(package_id, filename.clone());
290 }
291 }
292 }
278 Message::CompilerMessage(_) => (), 293 Message::CompilerMessage(_) => (),
279 Message::Unknown => (), 294 Message::Unknown => (),
280 } 295 }
diff --git a/crates/ra_project_model/src/json_project.rs b/crates/ra_project_model/src/json_project.rs
index 336446e58..b030c8a6a 100644
--- a/crates/ra_project_model/src/json_project.rs
+++ b/crates/ra_project_model/src/json_project.rs
@@ -23,6 +23,7 @@ pub struct Crate {
23 pub(crate) atom_cfgs: FxHashSet<String>, 23 pub(crate) atom_cfgs: FxHashSet<String>,
24 pub(crate) key_value_cfgs: FxHashMap<String, String>, 24 pub(crate) key_value_cfgs: FxHashMap<String, String>,
25 pub(crate) out_dir: Option<PathBuf>, 25 pub(crate) out_dir: Option<PathBuf>,
26 pub(crate) proc_macro_dylib_path: Option<PathBuf>,
26} 27}
27 28
28#[derive(Clone, Copy, Debug, Deserialize)] 29#[derive(Clone, Copy, Debug, Deserialize)]
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index a3ef9acdc..444d3bb3f 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -23,6 +23,7 @@ pub use crate::{
23 json_project::JsonProject, 23 json_project::JsonProject,
24 sysroot::Sysroot, 24 sysroot::Sysroot,
25}; 25};
26pub use ra_proc_macro::ProcMacroClient;
26 27
27#[derive(Clone, PartialEq, Eq, Hash, Debug)] 28#[derive(Clone, PartialEq, Eq, Hash, Debug)]
28pub struct CargoTomlNotFoundError { 29pub struct CargoTomlNotFoundError {
@@ -173,6 +174,29 @@ impl ProjectWorkspace {
173 } 174 }
174 } 175 }
175 176
177 pub fn proc_macro_dylib_paths(&self) -> Vec<PathBuf> {
178 match self {
179 ProjectWorkspace::Json { project } => {
180 let mut proc_macro_dylib_paths = Vec::with_capacity(project.crates.len());
181 for krate in &project.crates {
182 if let Some(out_dir) = &krate.proc_macro_dylib_path {
183 proc_macro_dylib_paths.push(out_dir.to_path_buf());
184 }
185 }
186 proc_macro_dylib_paths
187 }
188 ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => {
189 let mut proc_macro_dylib_paths = Vec::with_capacity(cargo.packages().len());
190 for pkg in cargo.packages() {
191 if let Some(dylib_path) = &cargo[pkg].proc_macro_dylib_path {
192 proc_macro_dylib_paths.push(dylib_path.to_path_buf());
193 }
194 }
195 proc_macro_dylib_paths
196 }
197 }
198 }
199
176 pub fn n_packages(&self) -> usize { 200 pub fn n_packages(&self) -> usize {
177 match self { 201 match self {
178 ProjectWorkspace::Json { project } => project.crates.len(), 202 ProjectWorkspace::Json { project } => project.crates.len(),
@@ -186,6 +210,7 @@ impl ProjectWorkspace {
186 &self, 210 &self,
187 default_cfg_options: &CfgOptions, 211 default_cfg_options: &CfgOptions,
188 extern_source_roots: &FxHashMap<PathBuf, ExternSourceId>, 212 extern_source_roots: &FxHashMap<PathBuf, ExternSourceId>,
213 proc_macro_client: &ProcMacroClient,
189 load: &mut dyn FnMut(&Path) -> Option<FileId>, 214 load: &mut dyn FnMut(&Path) -> Option<FileId>,
190 ) -> CrateGraph { 215 ) -> CrateGraph {
191 let mut crate_graph = CrateGraph::default(); 216 let mut crate_graph = CrateGraph::default();
@@ -219,7 +244,10 @@ impl ProjectWorkspace {
219 extern_source.set_extern_path(&out_dir, extern_source_id); 244 extern_source.set_extern_path(&out_dir, extern_source_id);
220 } 245 }
221 } 246 }
222 247 let proc_macro = krate
248 .proc_macro_dylib_path
249 .clone()
250 .map(|it| proc_macro_client.by_dylib_path(&it));
223 // FIXME: No crate name in json definition such that we cannot add OUT_DIR to env 251 // FIXME: No crate name in json definition such that we cannot add OUT_DIR to env
224 crates.insert( 252 crates.insert(
225 crate_id, 253 crate_id,
@@ -231,6 +259,7 @@ impl ProjectWorkspace {
231 cfg_options, 259 cfg_options,
232 env, 260 env,
233 extern_source, 261 extern_source,
262 proc_macro.unwrap_or_default(),
234 ), 263 ),
235 ); 264 );
236 } 265 }
@@ -270,6 +299,8 @@ impl ProjectWorkspace {
270 299
271 let env = Env::default(); 300 let env = Env::default();
272 let extern_source = ExternSource::default(); 301 let extern_source = ExternSource::default();
302 let proc_macro = vec![];
303
273 let crate_id = crate_graph.add_crate_root( 304 let crate_id = crate_graph.add_crate_root(
274 file_id, 305 file_id,
275 Edition::Edition2018, 306 Edition::Edition2018,
@@ -280,6 +311,7 @@ impl ProjectWorkspace {
280 cfg_options, 311 cfg_options,
281 env, 312 env,
282 extern_source, 313 extern_source,
314 proc_macro,
283 ); 315 );
284 sysroot_crates.insert(krate, crate_id); 316 sysroot_crates.insert(krate, crate_id);
285 } 317 }
@@ -327,6 +359,12 @@ impl ProjectWorkspace {
327 extern_source.set_extern_path(&out_dir, extern_source_id); 359 extern_source.set_extern_path(&out_dir, extern_source_id);
328 } 360 }
329 } 361 }
362 let proc_macro = cargo[pkg]
363 .proc_macro_dylib_path
364 .as_ref()
365 .map(|it| proc_macro_client.by_dylib_path(&it))
366 .unwrap_or_default();
367
330 let crate_id = crate_graph.add_crate_root( 368 let crate_id = crate_graph.add_crate_root(
331 file_id, 369 file_id,
332 edition, 370 edition,
@@ -334,6 +372,7 @@ impl ProjectWorkspace {
334 cfg_options, 372 cfg_options,
335 env, 373 env,
336 extern_source, 374 extern_source,
375 proc_macro.clone(),
337 ); 376 );
338 if cargo[tgt].kind == TargetKind::Lib { 377 if cargo[tgt].kind == TargetKind::Lib {
339 lib_tgt = Some((crate_id, cargo[tgt].name.clone())); 378 lib_tgt = Some((crate_id, cargo[tgt].name.clone()));