mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +00:00
Auto merge of #17857 - ChayimFriedman2:rust-project-cfg-group, r=Veykril
feat: Allow declaring cfg groups in rust-project.json, to help sharing common cfgs Closes #17815.
This commit is contained in:
commit
ae420e353e
5 changed files with 619 additions and 4 deletions
|
@ -52,7 +52,7 @@
|
|||
use base_db::{CrateDisplayName, CrateName};
|
||||
use cfg::CfgAtom;
|
||||
use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use serde::{de, Deserialize, Serialize};
|
||||
use span::Edition;
|
||||
|
||||
|
@ -122,6 +122,25 @@ impl ProjectJson {
|
|||
None => None,
|
||||
};
|
||||
|
||||
let cfg = crate_data
|
||||
.cfg_groups
|
||||
.iter()
|
||||
.flat_map(|cfg_extend| {
|
||||
let cfg_group = data.cfg_groups.get(cfg_extend);
|
||||
match cfg_group {
|
||||
Some(cfg_group) => cfg_group.0.iter().cloned(),
|
||||
None => {
|
||||
tracing::error!(
|
||||
"Unknown cfg group `{cfg_extend}` in crate `{}`",
|
||||
crate_data.display_name.as_deref().unwrap_or("<unknown>"),
|
||||
);
|
||||
[].iter().cloned()
|
||||
}
|
||||
}
|
||||
})
|
||||
.chain(crate_data.cfg.0)
|
||||
.collect();
|
||||
|
||||
Crate {
|
||||
display_name: crate_data
|
||||
.display_name
|
||||
|
@ -131,7 +150,7 @@ impl ProjectJson {
|
|||
edition: crate_data.edition.into(),
|
||||
version: crate_data.version.as_ref().map(ToString::to_string),
|
||||
deps: crate_data.deps,
|
||||
cfg: crate_data.cfg,
|
||||
cfg,
|
||||
target: crate_data.target,
|
||||
env: crate_data.env,
|
||||
proc_macro_dylib_path: crate_data
|
||||
|
@ -306,11 +325,17 @@ pub enum RunnableKind {
|
|||
pub struct ProjectJsonData {
|
||||
sysroot: Option<Utf8PathBuf>,
|
||||
sysroot_src: Option<Utf8PathBuf>,
|
||||
#[serde(default)]
|
||||
cfg_groups: FxHashMap<String, CfgList>,
|
||||
crates: Vec<CrateData>,
|
||||
#[serde(default)]
|
||||
runnables: Vec<RunnableData>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Default)]
|
||||
#[serde(transparent)]
|
||||
struct CfgList(#[serde(with = "cfg_")] Vec<CfgAtom>);
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
||||
struct CrateData {
|
||||
display_name: Option<String>,
|
||||
|
@ -320,8 +345,9 @@ struct CrateData {
|
|||
version: Option<semver::Version>,
|
||||
deps: Vec<Dep>,
|
||||
#[serde(default)]
|
||||
#[serde(with = "cfg_")]
|
||||
cfg: Vec<CfgAtom>,
|
||||
cfg_groups: FxHashSet<String>,
|
||||
#[serde(default)]
|
||||
cfg: CfgList,
|
||||
target: Option<String>,
|
||||
#[serde(default)]
|
||||
env: FxHashMap<String, String>,
|
||||
|
|
|
@ -233,6 +233,12 @@ fn rust_project_hello_world_project_model() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rust_project_cfg_groups() {
|
||||
let (crate_graph, _proc_macros) = load_rust_project("cfg-groups.json");
|
||||
check_crate_graph(crate_graph, expect_file!["../test_data/output/rust_project_cfg_groups.txt"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rust_project_is_proc_macro_has_proc_macro_dep() {
|
||||
let (crate_graph, _proc_macros) = load_rust_project("is-proc-macro-project.json");
|
||||
|
|
26
crates/project-model/test_data/cfg-groups.json
Normal file
26
crates/project-model/test_data/cfg-groups.json
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"sysroot_src": null,
|
||||
"cfg_groups": {
|
||||
"group1": ["group1_cfg=\"some_config\"", "group1_other_cfg=\"other_config\""],
|
||||
"group2": ["group2_cfg=\"yet_another_config\""]
|
||||
},
|
||||
"crates": [
|
||||
{
|
||||
"display_name": "hello_world",
|
||||
"root_module": "$ROOT$src/lib.rs",
|
||||
"edition": "2018",
|
||||
"cfg_groups": ["group1", "group2"],
|
||||
"deps": [],
|
||||
"is_workspace_member": true
|
||||
},
|
||||
{
|
||||
"display_name": "other_crate",
|
||||
"root_module": "$ROOT$src/lib.rs",
|
||||
"edition": "2018",
|
||||
"cfg_groups": ["group2"],
|
||||
"cfg": ["group2_cfg=\"fourth_config\"", "unrelated_cfg"],
|
||||
"deps": [],
|
||||
"is_workspace_member": true
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,545 @@
|
|||
{
|
||||
0: CrateData {
|
||||
root_file_id: FileId(
|
||||
1,
|
||||
),
|
||||
edition: Edition2021,
|
||||
version: None,
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"alloc",
|
||||
),
|
||||
canonical_name: "alloc",
|
||||
},
|
||||
),
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"debug_assertions",
|
||||
"miri",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {},
|
||||
},
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(1),
|
||||
name: CrateName(
|
||||
"core",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Lang(
|
||||
Alloc,
|
||||
),
|
||||
is_proc_macro: false,
|
||||
},
|
||||
1: CrateData {
|
||||
root_file_id: FileId(
|
||||
2,
|
||||
),
|
||||
edition: Edition2021,
|
||||
version: None,
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"core",
|
||||
),
|
||||
canonical_name: "core",
|
||||
},
|
||||
),
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"debug_assertions",
|
||||
"miri",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {},
|
||||
},
|
||||
dependencies: [],
|
||||
origin: Lang(
|
||||
Core,
|
||||
),
|
||||
is_proc_macro: false,
|
||||
},
|
||||
2: CrateData {
|
||||
root_file_id: FileId(
|
||||
3,
|
||||
),
|
||||
edition: Edition2021,
|
||||
version: None,
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"panic_abort",
|
||||
),
|
||||
canonical_name: "panic_abort",
|
||||
},
|
||||
),
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"debug_assertions",
|
||||
"miri",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {},
|
||||
},
|
||||
dependencies: [],
|
||||
origin: Lang(
|
||||
Other,
|
||||
),
|
||||
is_proc_macro: false,
|
||||
},
|
||||
3: CrateData {
|
||||
root_file_id: FileId(
|
||||
4,
|
||||
),
|
||||
edition: Edition2021,
|
||||
version: None,
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"panic_unwind",
|
||||
),
|
||||
canonical_name: "panic_unwind",
|
||||
},
|
||||
),
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"debug_assertions",
|
||||
"miri",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {},
|
||||
},
|
||||
dependencies: [],
|
||||
origin: Lang(
|
||||
Other,
|
||||
),
|
||||
is_proc_macro: false,
|
||||
},
|
||||
4: CrateData {
|
||||
root_file_id: FileId(
|
||||
5,
|
||||
),
|
||||
edition: Edition2021,
|
||||
version: None,
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"proc_macro",
|
||||
),
|
||||
canonical_name: "proc_macro",
|
||||
},
|
||||
),
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"debug_assertions",
|
||||
"miri",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {},
|
||||
},
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(6),
|
||||
name: CrateName(
|
||||
"std",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(1),
|
||||
name: CrateName(
|
||||
"core",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Lang(
|
||||
ProcMacro,
|
||||
),
|
||||
is_proc_macro: false,
|
||||
},
|
||||
5: CrateData {
|
||||
root_file_id: FileId(
|
||||
6,
|
||||
),
|
||||
edition: Edition2021,
|
||||
version: None,
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"profiler_builtins",
|
||||
),
|
||||
canonical_name: "profiler_builtins",
|
||||
},
|
||||
),
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"debug_assertions",
|
||||
"miri",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {},
|
||||
},
|
||||
dependencies: [],
|
||||
origin: Lang(
|
||||
Other,
|
||||
),
|
||||
is_proc_macro: false,
|
||||
},
|
||||
6: CrateData {
|
||||
root_file_id: FileId(
|
||||
7,
|
||||
),
|
||||
edition: Edition2021,
|
||||
version: None,
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"std",
|
||||
),
|
||||
canonical_name: "std",
|
||||
},
|
||||
),
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"debug_assertions",
|
||||
"miri",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {},
|
||||
},
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(0),
|
||||
name: CrateName(
|
||||
"alloc",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(3),
|
||||
name: CrateName(
|
||||
"panic_unwind",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(2),
|
||||
name: CrateName(
|
||||
"panic_abort",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(1),
|
||||
name: CrateName(
|
||||
"core",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(5),
|
||||
name: CrateName(
|
||||
"profiler_builtins",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(9),
|
||||
name: CrateName(
|
||||
"unwind",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(7),
|
||||
name: CrateName(
|
||||
"std_detect",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(8),
|
||||
name: CrateName(
|
||||
"test",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Lang(
|
||||
Std,
|
||||
),
|
||||
is_proc_macro: false,
|
||||
},
|
||||
7: CrateData {
|
||||
root_file_id: FileId(
|
||||
8,
|
||||
),
|
||||
edition: Edition2021,
|
||||
version: None,
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"std_detect",
|
||||
),
|
||||
canonical_name: "std_detect",
|
||||
},
|
||||
),
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"debug_assertions",
|
||||
"miri",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {},
|
||||
},
|
||||
dependencies: [],
|
||||
origin: Lang(
|
||||
Other,
|
||||
),
|
||||
is_proc_macro: false,
|
||||
},
|
||||
8: CrateData {
|
||||
root_file_id: FileId(
|
||||
9,
|
||||
),
|
||||
edition: Edition2021,
|
||||
version: None,
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"test",
|
||||
),
|
||||
canonical_name: "test",
|
||||
},
|
||||
),
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"debug_assertions",
|
||||
"miri",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {},
|
||||
},
|
||||
dependencies: [],
|
||||
origin: Lang(
|
||||
Test,
|
||||
),
|
||||
is_proc_macro: false,
|
||||
},
|
||||
9: CrateData {
|
||||
root_file_id: FileId(
|
||||
10,
|
||||
),
|
||||
edition: Edition2021,
|
||||
version: None,
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"unwind",
|
||||
),
|
||||
canonical_name: "unwind",
|
||||
},
|
||||
),
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"debug_assertions",
|
||||
"miri",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {},
|
||||
},
|
||||
dependencies: [],
|
||||
origin: Lang(
|
||||
Other,
|
||||
),
|
||||
is_proc_macro: false,
|
||||
},
|
||||
10: CrateData {
|
||||
root_file_id: FileId(
|
||||
11,
|
||||
),
|
||||
edition: Edition2018,
|
||||
version: None,
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
canonical_name: "hello_world",
|
||||
},
|
||||
),
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"group1_cfg=some_config",
|
||||
"group1_other_cfg=other_config",
|
||||
"group2_cfg=yet_another_config",
|
||||
"rust_analyzer",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {},
|
||||
},
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(1),
|
||||
name: CrateName(
|
||||
"core",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: true,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(0),
|
||||
name: CrateName(
|
||||
"alloc",
|
||||
),
|
||||
prelude: false,
|
||||
sysroot: true,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(6),
|
||||
name: CrateName(
|
||||
"std",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: true,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(8),
|
||||
name: CrateName(
|
||||
"test",
|
||||
),
|
||||
prelude: false,
|
||||
sysroot: true,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(4),
|
||||
name: CrateName(
|
||||
"proc_macro",
|
||||
),
|
||||
prelude: false,
|
||||
sysroot: true,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello_world",
|
||||
),
|
||||
},
|
||||
is_proc_macro: false,
|
||||
},
|
||||
11: CrateData {
|
||||
root_file_id: FileId(
|
||||
12,
|
||||
),
|
||||
edition: Edition2018,
|
||||
version: None,
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"other_crate",
|
||||
),
|
||||
canonical_name: "other_crate",
|
||||
},
|
||||
),
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"group2_cfg=fourth_config",
|
||||
"group2_cfg=yet_another_config",
|
||||
"rust_analyzer",
|
||||
"unrelated_cfg",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {},
|
||||
},
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(1),
|
||||
name: CrateName(
|
||||
"core",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: true,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(0),
|
||||
name: CrateName(
|
||||
"alloc",
|
||||
),
|
||||
prelude: false,
|
||||
sysroot: true,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(6),
|
||||
name: CrateName(
|
||||
"std",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: true,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(8),
|
||||
name: CrateName(
|
||||
"test",
|
||||
),
|
||||
prelude: false,
|
||||
sysroot: true,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(4),
|
||||
name: CrateName(
|
||||
"proc_macro",
|
||||
),
|
||||
prelude: false,
|
||||
sysroot: true,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"other_crate",
|
||||
),
|
||||
},
|
||||
is_proc_macro: false,
|
||||
},
|
||||
}
|
|
@ -705,6 +705,12 @@ interface JsonProject {
|
|||
/// several different "sysroots" in one graph of
|
||||
/// crates.
|
||||
sysroot_src?: string;
|
||||
/// List of groups of common cfg values, to allow
|
||||
/// sharing them between crates.
|
||||
///
|
||||
/// Maps from group name to its cfgs. Cfg follow
|
||||
/// the same format as `Crate.cfg`.
|
||||
cfg_groups?: { [key: string]: string[]; };
|
||||
/// The set of crates comprising the current
|
||||
/// project. Must include all transitive
|
||||
/// dependencies as well as sysroot crate (libstd,
|
||||
|
@ -754,6 +760,12 @@ interface Crate {
|
|||
include_dirs: string[],
|
||||
exclude_dirs: string[],
|
||||
},
|
||||
/// List of cfg groups this crate inherits.
|
||||
///
|
||||
/// All cfg in these groups will be concatenated to
|
||||
/// `cfg`. It is impossible to replace a value from
|
||||
/// the groups.
|
||||
cfg_groups?: string[];
|
||||
/// The set of cfgs activated for a given crate, like
|
||||
/// `["unix", "feature=\"foo\"", "feature=\"bar\""]`.
|
||||
cfg: string[];
|
||||
|
|
Loading…
Reference in a new issue