diff options
Diffstat (limited to 'crates/ra_project_model/src')
-rw-r--r-- | crates/ra_project_model/src/cargo_workspace.rs | 31 | ||||
-rw-r--r-- | crates/ra_project_model/src/json_project.rs | 1 | ||||
-rw-r--r-- | crates/ra_project_model/src/lib.rs | 41 |
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 | ||
249 | pub fn load_out_dirs( | 254 | #[derive(Debug, Clone, Default)] |
250 | cargo_toml: &Path, | 255 | pub 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 | |||
260 | pub 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 | }; |
26 | pub use ra_proc_macro::ProcMacroClient; | ||
26 | 27 | ||
27 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] | 28 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] |
28 | pub struct CargoTomlNotFoundError { | 29 | pub 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())); |