diff options
-rw-r--r-- | crates/ra_cfg/src/lib.rs | 9 | ||||
-rw-r--r-- | crates/ra_project_model/src/cargo_workspace.rs | 15 | ||||
-rw-r--r-- | crates/ra_project_model/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/rust-analyzer/tests/heavy_tests/main.rs | 110 |
4 files changed, 130 insertions, 5 deletions
diff --git a/crates/ra_cfg/src/lib.rs b/crates/ra_cfg/src/lib.rs index 51d953f6e..697a04581 100644 --- a/crates/ra_cfg/src/lib.rs +++ b/crates/ra_cfg/src/lib.rs | |||
@@ -53,4 +53,13 @@ impl CfgOptions { | |||
53 | pub fn insert_features(&mut self, iter: impl IntoIterator<Item = SmolStr>) { | 53 | pub fn insert_features(&mut self, iter: impl IntoIterator<Item = SmolStr>) { |
54 | iter.into_iter().for_each(|feat| self.insert_key_value("feature".into(), feat)); | 54 | iter.into_iter().for_each(|feat| self.insert_key_value("feature".into(), feat)); |
55 | } | 55 | } |
56 | |||
57 | /// Shortcut to set cfgs | ||
58 | pub fn insert_cfgs(&mut self, iter: impl IntoIterator<Item = SmolStr>) { | ||
59 | iter.into_iter().for_each(|cfg| match cfg.find('=') { | ||
60 | Some(split) => self | ||
61 | .insert_key_value(cfg[0..split].into(), cfg[split + 1..].trim_matches('"').into()), | ||
62 | None => self.insert_atom(cfg), | ||
63 | }); | ||
64 | } | ||
56 | } | 65 | } |
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs index 59f46a2a0..16fff9f1c 100644 --- a/crates/ra_project_model/src/cargo_workspace.rs +++ b/crates/ra_project_model/src/cargo_workspace.rs | |||
@@ -87,6 +87,7 @@ pub struct PackageData { | |||
87 | pub dependencies: Vec<PackageDependency>, | 87 | pub dependencies: Vec<PackageDependency>, |
88 | pub edition: Edition, | 88 | pub edition: Edition, |
89 | pub features: Vec<String>, | 89 | pub features: Vec<String>, |
90 | pub cfgs: Vec<String>, | ||
90 | pub out_dir: Option<PathBuf>, | 91 | pub out_dir: Option<PathBuf>, |
91 | pub proc_macro_dylib_path: Option<PathBuf>, | 92 | pub proc_macro_dylib_path: Option<PathBuf>, |
92 | } | 93 | } |
@@ -172,10 +173,12 @@ impl CargoWorkspace { | |||
172 | })?; | 173 | })?; |
173 | 174 | ||
174 | let mut out_dir_by_id = FxHashMap::default(); | 175 | let mut out_dir_by_id = FxHashMap::default(); |
176 | let mut cfgs = FxHashMap::default(); | ||
175 | let mut proc_macro_dylib_paths = FxHashMap::default(); | 177 | let mut proc_macro_dylib_paths = FxHashMap::default(); |
176 | if cargo_features.load_out_dirs_from_check { | 178 | if cargo_features.load_out_dirs_from_check { |
177 | let resources = load_extern_resources(cargo_toml, cargo_features)?; | 179 | let resources = load_extern_resources(cargo_toml, cargo_features)?; |
178 | out_dir_by_id = resources.out_dirs; | 180 | out_dir_by_id = resources.out_dirs; |
181 | cfgs = resources.cfgs; | ||
179 | proc_macro_dylib_paths = resources.proc_dylib_paths; | 182 | proc_macro_dylib_paths = resources.proc_dylib_paths; |
180 | } | 183 | } |
181 | 184 | ||
@@ -201,6 +204,7 @@ impl CargoWorkspace { | |||
201 | edition, | 204 | edition, |
202 | dependencies: Vec::new(), | 205 | dependencies: Vec::new(), |
203 | features: Vec::new(), | 206 | features: Vec::new(), |
207 | cfgs: cfgs.get(&id).cloned().unwrap_or_default(), | ||
204 | out_dir: out_dir_by_id.get(&id).cloned(), | 208 | out_dir: out_dir_by_id.get(&id).cloned(), |
205 | proc_macro_dylib_path: proc_macro_dylib_paths.get(&id).cloned(), | 209 | proc_macro_dylib_path: proc_macro_dylib_paths.get(&id).cloned(), |
206 | }); | 210 | }); |
@@ -282,6 +286,7 @@ impl CargoWorkspace { | |||
282 | pub struct ExternResources { | 286 | pub struct ExternResources { |
283 | out_dirs: FxHashMap<PackageId, PathBuf>, | 287 | out_dirs: FxHashMap<PackageId, PathBuf>, |
284 | proc_dylib_paths: FxHashMap<PackageId, PathBuf>, | 288 | proc_dylib_paths: FxHashMap<PackageId, PathBuf>, |
289 | cfgs: FxHashMap<PackageId, Vec<String>>, | ||
285 | } | 290 | } |
286 | 291 | ||
287 | pub fn load_extern_resources( | 292 | pub fn load_extern_resources( |
@@ -307,8 +312,14 @@ pub fn load_extern_resources( | |||
307 | for message in cargo_metadata::parse_messages(output.stdout.as_slice()) { | 312 | for message in cargo_metadata::parse_messages(output.stdout.as_slice()) { |
308 | if let Ok(message) = message { | 313 | if let Ok(message) = message { |
309 | match message { | 314 | match message { |
310 | Message::BuildScriptExecuted(BuildScript { package_id, out_dir, .. }) => { | 315 | Message::BuildScriptExecuted(BuildScript { package_id, out_dir, cfgs, .. }) => { |
311 | res.out_dirs.insert(package_id, out_dir); | 316 | res.out_dirs.insert(package_id.clone(), out_dir); |
317 | res.cfgs.insert( | ||
318 | package_id, | ||
319 | // FIXME: Current `cargo_metadata` uses `PathBuf` instead of `String`, | ||
320 | // change when https://github.com/oli-obk/cargo_metadata/pulls/112 reaches crates.io | ||
321 | cfgs.iter().filter_map(|c| c.to_str().map(|s| s.to_owned())).collect(), | ||
322 | ); | ||
312 | } | 323 | } |
313 | 324 | ||
314 | Message::CompilerArtifact(message) => { | 325 | Message::CompilerArtifact(message) => { |
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index c2b33c1dc..8703429d4 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs | |||
@@ -399,6 +399,7 @@ impl ProjectWorkspace { | |||
399 | let cfg_options = { | 399 | let cfg_options = { |
400 | let mut opts = default_cfg_options.clone(); | 400 | let mut opts = default_cfg_options.clone(); |
401 | opts.insert_features(cargo[pkg].features.iter().map(Into::into)); | 401 | opts.insert_features(cargo[pkg].features.iter().map(Into::into)); |
402 | opts.insert_cfgs(cargo[pkg].cfgs.iter().map(Into::into)); | ||
402 | opts | 403 | opts |
403 | }; | 404 | }; |
404 | let mut env = Env::default(); | 405 | let mut env = Env::default(); |
diff --git a/crates/rust-analyzer/tests/heavy_tests/main.rs b/crates/rust-analyzer/tests/heavy_tests/main.rs index 1efa5dd63..e459e3a3c 100644 --- a/crates/rust-analyzer/tests/heavy_tests/main.rs +++ b/crates/rust-analyzer/tests/heavy_tests/main.rs | |||
@@ -9,7 +9,8 @@ use lsp_types::{ | |||
9 | }; | 9 | }; |
10 | use rust_analyzer::req::{ | 10 | use rust_analyzer::req::{ |
11 | CodeActionParams, CodeActionRequest, Completion, CompletionParams, DidOpenTextDocument, | 11 | CodeActionParams, CodeActionRequest, Completion, CompletionParams, DidOpenTextDocument, |
12 | Formatting, GotoDefinition, HoverRequest, OnEnter, Runnables, RunnablesParams, | 12 | Formatting, GotoDefinition, GotoTypeDefinition, HoverRequest, OnEnter, Runnables, |
13 | RunnablesParams, | ||
13 | }; | 14 | }; |
14 | use serde_json::json; | 15 | use serde_json::json; |
15 | use tempfile::TempDir; | 16 | use tempfile::TempDir; |
@@ -574,7 +575,7 @@ version = \"0.0.0\" | |||
574 | } | 575 | } |
575 | 576 | ||
576 | #[test] | 577 | #[test] |
577 | fn resolve_include_concat_env() { | 578 | fn out_dirs_check() { |
578 | if skip_slow_tests() { | 579 | if skip_slow_tests() { |
579 | return; | 580 | return; |
580 | } | 581 | } |
@@ -597,11 +598,28 @@ fn main() { | |||
597 | r#"pub fn message() -> &'static str { "Hello, World!" }"#, | 598 | r#"pub fn message() -> &'static str { "Hello, World!" }"#, |
598 | ) | 599 | ) |
599 | .unwrap(); | 600 | .unwrap(); |
601 | println!("cargo:rustc-cfg=atom_cfg"); | ||
602 | println!("cargo:rustc-cfg=featlike=\"set\""); | ||
600 | println!("cargo:rerun-if-changed=build.rs"); | 603 | println!("cargo:rerun-if-changed=build.rs"); |
601 | } | 604 | } |
602 | //- src/main.rs | 605 | //- src/main.rs |
603 | include!(concat!(env!("OUT_DIR"), "/hello.rs")); | 606 | include!(concat!(env!("OUT_DIR"), "/hello.rs")); |
604 | 607 | ||
608 | #[cfg(atom_cfg)] | ||
609 | struct A; | ||
610 | #[cfg(bad_atom_cfg)] | ||
611 | struct A; | ||
612 | #[cfg(featlike = "set")] | ||
613 | struct B; | ||
614 | #[cfg(featlike = "not_set")] | ||
615 | struct B; | ||
616 | |||
617 | fn main() { | ||
618 | let va = A; | ||
619 | let vb = B; | ||
620 | message(); | ||
621 | } | ||
622 | |||
605 | fn main() { message(); } | 623 | fn main() { message(); } |
606 | "###, | 624 | "###, |
607 | ) | 625 | ) |
@@ -613,12 +631,98 @@ fn main() { message(); } | |||
613 | let res = server.send_request::<GotoDefinition>(GotoDefinitionParams { | 631 | let res = server.send_request::<GotoDefinition>(GotoDefinitionParams { |
614 | text_document_position_params: TextDocumentPositionParams::new( | 632 | text_document_position_params: TextDocumentPositionParams::new( |
615 | server.doc_id("src/main.rs"), | 633 | server.doc_id("src/main.rs"), |
616 | Position::new(2, 15), | 634 | Position::new(14, 8), |
617 | ), | 635 | ), |
618 | work_done_progress_params: Default::default(), | 636 | work_done_progress_params: Default::default(), |
619 | partial_result_params: Default::default(), | 637 | partial_result_params: Default::default(), |
620 | }); | 638 | }); |
621 | assert!(format!("{}", res).contains("hello.rs")); | 639 | assert!(format!("{}", res).contains("hello.rs")); |
640 | server.request::<GotoTypeDefinition>( | ||
641 | GotoDefinitionParams { | ||
642 | text_document_position_params: TextDocumentPositionParams::new( | ||
643 | server.doc_id("src/main.rs"), | ||
644 | Position::new(12, 9), | ||
645 | ), | ||
646 | work_done_progress_params: Default::default(), | ||
647 | partial_result_params: Default::default(), | ||
648 | }, | ||
649 | json!([{ | ||
650 | "originSelectionRange": { | ||
651 | "end": { | ||
652 | "character": 10, | ||
653 | "line": 12 | ||
654 | }, | ||
655 | "start": { | ||
656 | "character": 8, | ||
657 | "line": 12 | ||
658 | } | ||
659 | }, | ||
660 | "targetRange": { | ||
661 | "end": { | ||
662 | "character": 9, | ||
663 | "line": 3 | ||
664 | }, | ||
665 | "start": { | ||
666 | "character": 0, | ||
667 | "line": 2 | ||
668 | } | ||
669 | }, | ||
670 | "targetSelectionRange": { | ||
671 | "end": { | ||
672 | "character": 8, | ||
673 | "line": 3 | ||
674 | }, | ||
675 | "start": { | ||
676 | "character": 7, | ||
677 | "line": 3 | ||
678 | } | ||
679 | }, | ||
680 | "targetUri": "file:///[..]src/main.rs" | ||
681 | }]), | ||
682 | ); | ||
683 | server.request::<GotoTypeDefinition>( | ||
684 | GotoDefinitionParams { | ||
685 | text_document_position_params: TextDocumentPositionParams::new( | ||
686 | server.doc_id("src/main.rs"), | ||
687 | Position::new(13, 9), | ||
688 | ), | ||
689 | work_done_progress_params: Default::default(), | ||
690 | partial_result_params: Default::default(), | ||
691 | }, | ||
692 | json!([{ | ||
693 | "originSelectionRange": { | ||
694 | "end": { | ||
695 | "character": 10, | ||
696 | "line": 13 | ||
697 | }, | ||
698 | "start": { | ||
699 | "character": 8, | ||
700 | "line":13 | ||
701 | } | ||
702 | }, | ||
703 | "targetRange": { | ||
704 | "end": { | ||
705 | "character": 9, | ||
706 | "line": 7 | ||
707 | }, | ||
708 | "start": { | ||
709 | "character": 0, | ||
710 | "line":6 | ||
711 | } | ||
712 | }, | ||
713 | "targetSelectionRange": { | ||
714 | "end": { | ||
715 | "character": 8, | ||
716 | "line": 7 | ||
717 | }, | ||
718 | "start": { | ||
719 | "character": 7, | ||
720 | "line": 7 | ||
721 | } | ||
722 | }, | ||
723 | "targetUri": "file:///[..]src/main.rs" | ||
724 | }]), | ||
725 | ); | ||
622 | } | 726 | } |
623 | 727 | ||
624 | #[test] | 728 | #[test] |