mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +00:00
Support build.rs cargo:rustc-cfg
This commit is contained in:
parent
6a48a94d47
commit
2980ba1fde
4 changed files with 158 additions and 3 deletions
|
@ -53,4 +53,13 @@ impl CfgOptions {
|
|||
pub fn insert_features(&mut self, iter: impl IntoIterator<Item = SmolStr>) {
|
||||
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<Item = SmolStr>) {
|
||||
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),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ pub struct PackageData {
|
|||
pub dependencies: Vec<PackageDependency>,
|
||||
pub edition: Edition,
|
||||
pub features: Vec<String>,
|
||||
pub cfgs: Vec<PathBuf>,
|
||||
pub out_dir: Option<PathBuf>,
|
||||
pub proc_macro_dylib_path: Option<PathBuf>,
|
||||
}
|
||||
|
@ -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<PackageId, PathBuf>,
|
||||
proc_dylib_paths: FxHashMap<PackageId, PathBuf>,
|
||||
cfgs: FxHashMap<PackageId, Vec<PathBuf>>,
|
||||
}
|
||||
|
||||
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) => {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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::<GotoTypeDefinition>(
|
||||
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::<GotoTypeDefinition>(
|
||||
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"
|
||||
}]),
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue