Add config setting which allows adding additional include paths to the VFS.

This commit is contained in:
Nicholas Rishel 2025-01-07 18:40:46 -08:00
parent 91fc0a239a
commit 1f9686993a
7 changed files with 67 additions and 3 deletions

View File

@ -92,6 +92,8 @@ pub struct CargoConfig {
pub sysroot_src: Option<AbsPathBuf>, pub sysroot_src: Option<AbsPathBuf>,
/// rustc private crate source /// rustc private crate source
pub rustc_source: Option<RustLibSource>, pub rustc_source: Option<RustLibSource>,
/// Extra includes to add to the VFS.
pub extra_includes: Vec<AbsPathBuf>,
pub cfg_overrides: CfgOverrides, pub cfg_overrides: CfgOverrides,
/// Invoke `cargo check` through the RUSTC_WRAPPER. /// Invoke `cargo check` through the RUSTC_WRAPPER.
pub wrap_rustc_in_build_scripts: bool, pub wrap_rustc_in_build_scripts: bool,

View File

@ -49,6 +49,7 @@ fn load_workspace_from_metadata(file: &str) -> ProjectWorkspace {
rustc_cfg: Vec::new(), rustc_cfg: Vec::new(),
toolchain: None, toolchain: None,
target_layout: Err("target_data_layout not loaded".into()), target_layout: Err("target_data_layout not loaded".into()),
extra_includes: Vec::new(),
} }
} }
@ -63,6 +64,7 @@ fn load_rust_project(file: &str) -> (CrateGraph, ProcMacroPaths) {
toolchain: None, toolchain: None,
target_layout: Err(Arc::from("test has no data layout")), target_layout: Err(Arc::from("test has no data layout")),
cfg_overrides: Default::default(), cfg_overrides: Default::default(),
extra_includes: Vec::new(),
}; };
to_crate_graph(project_workspace, &mut Default::default()) to_crate_graph(project_workspace, &mut Default::default())
} }
@ -284,6 +286,7 @@ fn smoke_test_real_sysroot_cargo() {
cfg_overrides: Default::default(), cfg_overrides: Default::default(),
toolchain: None, toolchain: None,
target_layout: Err("target_data_layout not loaded".into()), target_layout: Err("target_data_layout not loaded".into()),
extra_includes: Vec::new(),
}; };
project_workspace.to_crate_graph( project_workspace.to_crate_graph(
&mut { &mut {

View File

@ -63,6 +63,8 @@ pub struct ProjectWorkspace {
pub target_layout: TargetLayoutLoadResult, pub target_layout: TargetLayoutLoadResult,
/// A set of cfg overrides for this workspace. /// A set of cfg overrides for this workspace.
pub cfg_overrides: CfgOverrides, pub cfg_overrides: CfgOverrides,
/// Additional includes to add for the VFS.
pub extra_includes: Vec<AbsPathBuf>,
} }
#[derive(Clone)] #[derive(Clone)]
@ -104,7 +106,15 @@ pub enum ProjectWorkspaceKind {
impl fmt::Debug for ProjectWorkspace { impl fmt::Debug for ProjectWorkspace {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// Make sure this isn't too verbose. // Make sure this isn't too verbose.
let Self { kind, sysroot, rustc_cfg, toolchain, target_layout, cfg_overrides } = self; let Self {
kind,
sysroot,
rustc_cfg,
toolchain,
target_layout,
cfg_overrides,
extra_includes,
} = self;
match kind { match kind {
ProjectWorkspaceKind::Cargo { cargo, error: _, build_scripts, rustc, set_test } => f ProjectWorkspaceKind::Cargo { cargo, error: _, build_scripts, rustc, set_test } => f
.debug_struct("Cargo") .debug_struct("Cargo")
@ -117,6 +127,7 @@ impl fmt::Debug for ProjectWorkspace {
) )
.field("n_rustc_cfg", &rustc_cfg.len()) .field("n_rustc_cfg", &rustc_cfg.len())
.field("n_cfg_overrides", &cfg_overrides.len()) .field("n_cfg_overrides", &cfg_overrides.len())
.field("n_extra_includes", &extra_includes.len())
.field("toolchain", &toolchain) .field("toolchain", &toolchain)
.field("data_layout", &target_layout) .field("data_layout", &target_layout)
.field("set_test", set_test) .field("set_test", set_test)
@ -130,7 +141,8 @@ impl fmt::Debug for ProjectWorkspace {
.field("n_rustc_cfg", &rustc_cfg.len()) .field("n_rustc_cfg", &rustc_cfg.len())
.field("toolchain", &toolchain) .field("toolchain", &toolchain)
.field("data_layout", &target_layout) .field("data_layout", &target_layout)
.field("n_cfg_overrides", &cfg_overrides.len()); .field("n_cfg_overrides", &cfg_overrides.len())
.field("n_extra_includes", &extra_includes.len());
debug_struct.finish() debug_struct.finish()
} }
@ -144,6 +156,7 @@ impl fmt::Debug for ProjectWorkspace {
.field("toolchain", &toolchain) .field("toolchain", &toolchain)
.field("data_layout", &target_layout) .field("data_layout", &target_layout)
.field("n_cfg_overrides", &cfg_overrides.len()) .field("n_cfg_overrides", &cfg_overrides.len())
.field("n_extra_includes", &extra_includes.len())
.field("set_test", set_test) .field("set_test", set_test)
.finish(), .finish(),
} }
@ -320,6 +333,7 @@ impl ProjectWorkspace {
cfg_overrides, cfg_overrides,
toolchain, toolchain,
target_layout: data_layout.map(Arc::from).map_err(|it| Arc::from(it.to_string())), target_layout: data_layout.map(Arc::from).map_err(|it| Arc::from(it.to_string())),
extra_includes: config.extra_includes.clone(),
}) })
} }
@ -340,6 +354,7 @@ impl ProjectWorkspace {
toolchain, toolchain,
target_layout: data_layout.map(Arc::from).map_err(|it| Arc::from(it.to_string())), target_layout: data_layout.map(Arc::from).map_err(|it| Arc::from(it.to_string())),
cfg_overrides: config.cfg_overrides.clone(), cfg_overrides: config.cfg_overrides.clone(),
extra_includes: config.extra_includes.clone(),
} }
} }
@ -399,6 +414,7 @@ impl ProjectWorkspace {
toolchain, toolchain,
target_layout: data_layout.map(Arc::from).map_err(|it| Arc::from(it.to_string())), target_layout: data_layout.map(Arc::from).map_err(|it| Arc::from(it.to_string())),
cfg_overrides: config.cfg_overrides.clone(), cfg_overrides: config.cfg_overrides.clone(),
extra_includes: config.extra_includes.clone(),
}) })
} }
@ -565,7 +581,13 @@ impl ProjectWorkspace {
PackageRoot { PackageRoot {
is_local: krate.is_workspace_member, is_local: krate.is_workspace_member,
include: krate.include.iter().cloned().chain(build_file).collect(), include: krate
.include
.iter()
.cloned()
.chain(build_file)
.chain(self.extra_includes.iter().cloned())
.collect(),
exclude: krate.exclude.clone(), exclude: krate.exclude.clone(),
} }
}) })
@ -603,6 +625,8 @@ impl ProjectWorkspace {
let mut exclude = vec![pkg_root.join(".git")]; let mut exclude = vec![pkg_root.join(".git")];
if is_local { if is_local {
include.extend(self.extra_includes.iter().cloned());
exclude.push(pkg_root.join("target")); exclude.push(pkg_root.join("target"));
} else { } else {
exclude.push(pkg_root.join("tests")); exclude.push(pkg_root.join("tests"));
@ -661,6 +685,8 @@ impl ProjectWorkspace {
let mut exclude = vec![pkg_root.join(".git")]; let mut exclude = vec![pkg_root.join(".git")];
if is_local { if is_local {
include.extend(self.extra_includes.iter().cloned());
exclude.push(pkg_root.join("target")); exclude.push(pkg_root.join("target"));
} else { } else {
exclude.push(pkg_root.join("tests")); exclude.push(pkg_root.join("tests"));

View File

@ -93,6 +93,7 @@ impl Tester {
toolchain: None, toolchain: None,
target_layout: data_layout.map(Arc::from).map_err(|it| Arc::from(it.to_string())), target_layout: data_layout.map(Arc::from).map_err(|it| Arc::from(it.to_string())),
cfg_overrides: Default::default(), cfg_overrides: Default::default(),
extra_includes: vec![],
}; };
let load_cargo_config = LoadCargoConfig { let load_cargo_config = LoadCargoConfig {
load_out_dirs_from_check: false, load_out_dirs_from_check: false,

View File

@ -728,6 +728,10 @@ config_data! {
/// available on a nightly build. /// available on a nightly build.
rustfmt_rangeFormatting_enable: bool = false, rustfmt_rangeFormatting_enable: bool = false,
/// Additional paths to include in the VFS. Generally for code that is
/// generated or otherwise managed by a build system outside of Cargo,
/// though Cargo might be the eventual consumer.
vfs_extraIncludes: Vec<String> = vec![],
/// Workspace symbol search kind. /// Workspace symbol search kind.
workspace_symbol_search_kind: WorkspaceSymbolSearchKindDef = WorkspaceSymbolSearchKindDef::OnlyTypes, workspace_symbol_search_kind: WorkspaceSymbolSearchKindDef = WorkspaceSymbolSearchKindDef::OnlyTypes,
@ -1926,6 +1930,13 @@ impl Config {
}); });
let sysroot_src = let sysroot_src =
self.cargo_sysrootSrc(source_root).as_ref().map(|sysroot| self.root_path.join(sysroot)); self.cargo_sysrootSrc(source_root).as_ref().map(|sysroot| self.root_path.join(sysroot));
let extra_includes = self
.vfs_extraIncludes(source_root)
.iter()
.map(String::as_str)
.map(AbsPathBuf::try_from)
.filter_map(Result::ok)
.collect();
CargoConfig { CargoConfig {
all_targets: *self.cargo_allTargets(source_root), all_targets: *self.cargo_allTargets(source_root),
@ -1940,6 +1951,7 @@ impl Config {
sysroot, sysroot,
sysroot_src, sysroot_src,
rustc_source, rustc_source,
extra_includes,
cfg_overrides: project_model::CfgOverrides { cfg_overrides: project_model::CfgOverrides {
global: CfgDiff::new( global: CfgDiff::new(
self.cargo_cfgs(source_root) self.cargo_cfgs(source_root)

View File

@ -1051,6 +1051,13 @@ Show documentation.
-- --
Specify the characters to exclude from triggering typing assists. The default trigger characters are `.`, `=`, `<`, `>`, `{`, and `(`. Specify the characters to exclude from triggering typing assists. The default trigger characters are `.`, `=`, `<`, `>`, `{`, and `(`.
-- --
[[rust-analyzer.vfs.extraIncludes]]rust-analyzer.vfs.extraIncludes (default: `[]`)::
+
--
Additional paths to include in the VFS. Generally for code that is
generated or otherwise managed by a build system outside of Cargo,
though Cargo might be the eventual consumer.
--
[[rust-analyzer.workspace.discoverConfig]]rust-analyzer.workspace.discoverConfig (default: `null`):: [[rust-analyzer.workspace.discoverConfig]]rust-analyzer.workspace.discoverConfig (default: `null`)::
+ +
-- --

View File

@ -2718,6 +2718,19 @@
} }
} }
}, },
{
"title": "vfs",
"properties": {
"rust-analyzer.vfs.extraIncludes": {
"markdownDescription": "Additional paths to include in the VFS. Generally for code that is\ngenerated or otherwise managed by a build system outside of Cargo,\nthough Cargo might be the eventual consumer.",
"default": [],
"type": "array",
"items": {
"type": "string"
}
}
}
},
{ {
"title": "workspace", "title": "workspace",
"properties": { "properties": {