From 2980ba1fde50a6fc8863750b9dd7f09e3c1227ce Mon Sep 17 00:00:00 2001 From: robojumper Date: Mon, 4 May 2020 13:29:09 +0200 Subject: Support build.rs cargo:rustc-cfg --- crates/ra_cfg/src/lib.rs | 9 ++ crates/ra_project_model/src/cargo_workspace.rs | 10 +- crates/ra_project_model/src/lib.rs | 7 ++ crates/rust-analyzer/tests/heavy_tests/main.rs | 135 ++++++++++++++++++++++++- 4 files changed, 158 insertions(+), 3 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 { pub fn insert_features(&mut self, iter: impl IntoIterator) { iter.into_iter().for_each(|feat| self.insert_key_value("feature".into(), feat)); } + + /// Shortcut to set cfgs + pub fn insert_cfgs(&mut self, iter: impl IntoIterator) { + iter.into_iter().for_each(|cfg| match cfg.find('=') { + Some(split) => self + .insert_key_value(cfg[0..split].into(), cfg[split + 1..].trim_matches('"').into()), + None => self.insert_atom(cfg), + }); + } } diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs index 362ee30fe..afbd30164 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 { pub dependencies: Vec, pub edition: Edition, pub features: Vec, + pub cfgs: Vec, pub out_dir: Option, pub proc_macro_dylib_path: Option, } @@ -165,10 +166,12 @@ impl CargoWorkspace { })?; let mut out_dir_by_id = FxHashMap::default(); + let mut cfgs = FxHashMap::default(); let mut proc_macro_dylib_paths = FxHashMap::default(); if cargo_features.load_out_dirs_from_check { let resources = load_extern_resources(cargo_toml, cargo_features)?; out_dir_by_id = resources.out_dirs; + cfgs = resources.cfgs; proc_macro_dylib_paths = resources.proc_dylib_paths; } @@ -194,6 +197,7 @@ impl CargoWorkspace { edition, dependencies: Vec::new(), features: Vec::new(), + cfgs: cfgs.get(&id).cloned().unwrap_or_default(), out_dir: out_dir_by_id.get(&id).cloned(), proc_macro_dylib_path: proc_macro_dylib_paths.get(&id).cloned(), }); @@ -275,6 +279,7 @@ impl CargoWorkspace { pub struct ExternResources { out_dirs: FxHashMap, proc_dylib_paths: FxHashMap, + cfgs: FxHashMap>, } pub fn load_extern_resources( @@ -300,8 +305,9 @@ pub fn load_extern_resources( for message in cargo_metadata::parse_messages(output.stdout.as_slice()) { if let Ok(message) = message { match message { - Message::BuildScriptExecuted(BuildScript { package_id, out_dir, .. }) => { - res.out_dirs.insert(package_id, out_dir); + Message::BuildScriptExecuted(BuildScript { package_id, out_dir, cfgs, .. }) => { + res.out_dirs.insert(package_id.clone(), out_dir); + res.cfgs.insert(package_id, cfgs); } Message::CompilerArtifact(message) => { diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 731cbd291..2d5d61b61 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -399,6 +399,13 @@ impl ProjectWorkspace { let cfg_options = { let mut opts = default_cfg_options.clone(); opts.insert_features(cargo[pkg].features.iter().map(Into::into)); + opts.insert_cfgs( + cargo[pkg] + .cfgs + .iter() + .filter_map(|c| c.to_str()) + .map(Into::into), + ); opts }; 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 a218da76d..e94fbce3a 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::{ }; use rust_analyzer::req::{ CodeActionParams, CodeActionRequest, Completion, CompletionParams, DidOpenTextDocument, - Formatting, GotoDefinition, HoverRequest, OnEnter, Runnables, RunnablesParams, + Formatting, GotoDefinition, GotoTypeDefinition, HoverRequest, OnEnter, Runnables, + RunnablesParams, }; use serde_json::json; use tempfile::TempDir; @@ -707,3 +708,135 @@ pub fn foo(_input: TokenStream) -> TokenStream { let value = res.get("contents").unwrap().get("value").unwrap().to_string(); assert_eq!(value, r#""```rust\nfoo::Bar\nfn bar()\n```""#) } + +#[test] +fn build_rs_cfgs() { + if skip_slow_tests() { + return; + } + + let server = Project::with_fixture( + r###" +//- Cargo.toml +[package] +name = "foo" +version = "0.0.0" + +//- build.rs + +fn main() { + println!("cargo:rustc-cfg=atom_cfg"); + println!("cargo:rustc-cfg=featlike=\"set\""); + println!("cargo:rerun-if-changed=build.rs"); +} +//- src/main.rs +#[cfg(atom_cfg)] +struct A; + +#[cfg(bad_atom_cfg)] +struct A; + +#[cfg(featlike = "set")] +struct B; + +#[cfg(featlike = "not_set")] +struct B; + +fn main() { + let va = A; + let vb = B; +} +"###, + ) + .with_config(|config| { + config.cargo.load_out_dirs_from_check = true; + }) + .server(); + server.wait_until_workspace_is_loaded(); + server.request::( + GotoDefinitionParams { + text_document_position_params: TextDocumentPositionParams::new( + server.doc_id("src/main.rs"), + Position::new(13, 9), + ), + work_done_progress_params: Default::default(), + partial_result_params: Default::default(), + }, + json!([{ + "originSelectionRange": { + "end": { + "character": 10, + "line": 13 + }, + "start": { + "character": 8, + "line":13 + } + }, + "targetRange": { + "end": { + "character": 9, + "line": 1 + }, + "start": { + "character": 0, + "line":0 + } + }, + "targetSelectionRange": { + "end": { + "character": 8, + "line": 1 + }, + "start": { + "character": 7, + "line": 1 + } + }, + "targetUri": "file:///[..]src/main.rs" + }]), + ); + server.request::( + GotoDefinitionParams { + text_document_position_params: TextDocumentPositionParams::new( + server.doc_id("src/main.rs"), + Position::new(14, 9), + ), + work_done_progress_params: Default::default(), + partial_result_params: Default::default(), + }, + json!([{ + "originSelectionRange": { + "end": { + "character": 10, + "line": 14 + }, + "start": { + "character": 8, + "line":14 + } + }, + "targetRange": { + "end": { + "character": 9, + "line": 7 + }, + "start": { + "character": 0, + "line":6 + } + }, + "targetSelectionRange": { + "end": { + "character": 8, + "line": 7 + }, + "start": { + "character": 7, + "line": 7 + } + }, + "targetUri": "file:///[..]src/main.rs" + }]), + ); +} -- cgit v1.2.3