diff --git a/crates/base-db/src/fixture.rs b/crates/base-db/src/fixture.rs index 1936eabdd9..cf3be9d07f 100644 --- a/crates/base-db/src/fixture.rs +++ b/crates/base-db/src/fixture.rs @@ -165,6 +165,7 @@ impl ChangeFixture { meta.edition, Some(crate_name.clone().into()), version, + None, meta.cfg, Default::default(), meta.env, @@ -205,6 +206,7 @@ impl ChangeFixture { Edition::CURRENT, Some(CrateName::new("test").unwrap().into()), None, + None, default_cfg, Default::default(), Env::default(), @@ -249,6 +251,7 @@ impl ChangeFixture { Edition::Edition2021, Some(CrateDisplayName::from_canonical_name("core".to_string())), None, + None, Default::default(), Default::default(), Env::default(), @@ -288,6 +291,7 @@ impl ChangeFixture { Edition::Edition2021, Some(CrateDisplayName::from_canonical_name("proc_macros".to_string())), None, + None, Default::default(), Default::default(), Env::default(), diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs index e6d265df67..466e2eab56 100644 --- a/crates/base-db/src/input.rs +++ b/crates/base-db/src/input.rs @@ -304,6 +304,7 @@ pub struct CrateData { /// For purposes of analysis, crates are anonymous (only names in /// `Dependency` matters), this name should only be used for UI. pub display_name: Option, + pub crate_root_path: Option, pub cfg_options: CfgOptions, /// The cfg options that could be used by the crate pub potential_cfg_options: Option, @@ -361,6 +362,7 @@ impl CrateGraph { edition: Edition, display_name: Option, version: Option, + crate_root_path: Option, cfg_options: CfgOptions, potential_cfg_options: Option, env: Env, @@ -374,6 +376,7 @@ impl CrateGraph { edition, version, display_name, + crate_root_path, cfg_options, potential_cfg_options, env, @@ -740,6 +743,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), @@ -753,6 +757,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), @@ -766,6 +771,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), @@ -793,6 +799,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), @@ -806,6 +813,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), @@ -830,6 +838,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), @@ -843,6 +852,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), @@ -856,6 +866,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), @@ -880,6 +891,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), @@ -893,6 +905,7 @@ mod tests { Edition2018, None, None, + None, Default::default(), Default::default(), Env::default(), diff --git a/crates/ide/src/fetch_crates.rs b/crates/ide/src/fetch_crates.rs index 5750d6b426..916c26855a 100644 --- a/crates/ide/src/fetch_crates.rs +++ b/crates/ide/src/fetch_crates.rs @@ -1,5 +1,5 @@ use ide_db::{ - base_db::{CrateOrigin, SourceDatabase, SourceDatabaseExt}, + base_db::{CrateOrigin, SourceDatabase}, FxIndexSet, RootDatabase, }; @@ -22,13 +22,13 @@ pub(crate) fn fetch_crates(db: &RootDatabase) -> FxIndexSet { .iter() .map(|crate_id| &crate_graph[crate_id]) .filter(|&data| !matches!(data.origin, CrateOrigin::Local { .. })) - .filter_map(|data| crate_info(data, db)) + .filter_map(|data| crate_info(data)) .collect() } -fn crate_info(data: &ide_db::base_db::CrateData, db: &RootDatabase) -> Option { +fn crate_info(data: &ide_db::base_db::CrateData) -> Option { let crate_name = crate_name(data); - let crate_path = crate_path(db, data, &crate_name); + let crate_path = data.crate_root_path.as_ref().map(|p| p.display().to_string()); if let Some(crate_path) = crate_path { let version = data.version.clone().unwrap_or_else(|| "".to_owned()); Some(CrateInfo { name: crate_name, version, path: crate_path }) @@ -43,29 +43,3 @@ fn crate_name(data: &ide_db::base_db::CrateData) -> String { .map(|it| it.canonical_name().to_owned()) .unwrap_or("unknown".to_string()) } - -fn crate_path( - db: &RootDatabase, - data: &ide_db::base_db::CrateData, - crate_name: &str, -) -> Option { - let source_root_id = db.file_source_root(data.root_file_id); - let source_root = db.source_root(source_root_id); - let source_root_path = source_root.path_for_file(&data.root_file_id); - source_root_path.cloned().and_then(|mut root_path| { - let mut crate_path = None; - while let Some(vfs_path) = root_path.parent() { - match vfs_path.name_and_extension() { - Some((name, _)) => { - if name.starts_with(crate_name) { - crate_path = Some(vfs_path.to_string()); - break; - } - } - None => break, - } - root_path = vfs_path; - } - crate_path - }) -} diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 24e2aed65a..131c781bee 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -239,6 +239,7 @@ impl Analysis { Edition::CURRENT, None, None, + None, cfg_options.clone(), None, Env::default(), diff --git a/crates/ide/src/shuffle_crate_graph.rs b/crates/ide/src/shuffle_crate_graph.rs index d94b15f60c..51ecc4001f 100644 --- a/crates/ide/src/shuffle_crate_graph.rs +++ b/crates/ide/src/shuffle_crate_graph.rs @@ -34,6 +34,7 @@ pub(crate) fn shuffle_crate_graph(db: &mut RootDatabase) { data.edition, data.display_name.clone(), data.version.clone(), + data.crate_root_path.clone(), data.cfg_options.clone(), data.potential_cfg_options.clone(), data.env.clone(), diff --git a/crates/paths/src/lib.rs b/crates/paths/src/lib.rs index ac09121aed..6a3c685016 100644 --- a/crates/paths/src/lib.rs +++ b/crates/paths/src/lib.rs @@ -213,6 +213,13 @@ impl AbsPath { pub fn exists(&self) -> bool { self.0.exists() } + + pub fn name_and_extension(&self) -> Option<(&str, Option<&str>)> { + Some(( + self.file_stem()?.to_str()?, + self.extension().and_then(|extension| extension.to_str()), + )) + } // endregion:delegate-methods } diff --git a/crates/project-model/src/tests.rs b/crates/project-model/src/tests.rs index 9acf60bf4a..ca28d742d5 100644 --- a/crates/project-model/src/tests.rs +++ b/crates/project-model/src/tests.rs @@ -102,6 +102,11 @@ fn replace_root(s: &mut String, direction: bool) { } } +fn replace_fake_sys_root(s: &mut String) { + let root = get_test_path("fake-sysroot"); + *s = s.replace(root.to_str().expect("expected str"), "$FAKESYSROOT$") +} + fn get_test_path(file: &str) -> PathBuf { let base = PathBuf::from(env!("CARGO_MANIFEST_DIR")); base.join("test_data").join(file) @@ -140,6 +145,7 @@ fn to_crate_graph(project_workspace: ProjectWorkspace) -> (CrateGraph, ProcMacro fn check_crate_graph(crate_graph: CrateGraph, expect: ExpectFile) { let mut crate_graph = format!("{crate_graph:#?}"); replace_root(&mut crate_graph, false); + replace_fake_sys_root(&mut crate_graph); expect.assert_eq(&crate_graph); } diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index 5924287a37..ba5a1c4e35 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -766,6 +766,7 @@ fn project_json_to_crate_graph( proc_macro_dylib_path, is_proc_macro, repository, + root_module, .. }, file_id, @@ -784,6 +785,7 @@ fn project_json_to_crate_graph( *edition, display_name.clone(), version.clone(), + crate_path(display_name.as_ref(), root_module), target_cfgs.iter().chain(cfg.iter()).cloned().collect(), None, env, @@ -832,6 +834,30 @@ fn project_json_to_crate_graph( res } +//Thats a best effort to try and find the crate path for a project configured using JsonProject model +fn crate_path( + crate_name: Option<&CrateDisplayName>, + root_module_path: &AbsPathBuf, +) -> Option { + crate_name.and_then(|crate_name| { + let mut crate_path = None; + let mut root_path = root_module_path.as_path(); + while let Some(path) = root_path.parent() { + match path.name_and_extension() { + Some((name, _)) => { + if name.starts_with(crate_name.canonical_name()) { + crate_path = Some(path.to_path_buf()); + break; + } + } + None => break, + } + root_path = path; + } + crate_path + }) +} + fn cargo_to_crate_graph( load: &mut dyn FnMut(&AbsPath) -> Option, rustc: Option<&(CargoWorkspace, WorkspaceBuildScripts)>, @@ -1053,6 +1079,7 @@ fn detached_files_to_crate_graph( Edition::CURRENT, display_name.clone(), None, + None, cfg_options.clone(), None, Env::default(), @@ -1249,6 +1276,7 @@ fn add_target_crate_root( edition, Some(display_name), Some(pkg.version.to_string()), + Some(pkg.manifest.parent().to_owned()), cfg_options, potential_cfg_options, env, @@ -1320,11 +1348,13 @@ fn sysroot_to_crate_graph( let env = Env::default(); let display_name = CrateDisplayName::from_canonical_name(sysroot[krate].name.clone()); - let crate_id = crate_graph.add_crate_root( + let crate_root_path = sysroot.src_root().join(display_name.canonical_name()); + let crate_id = crate_graph.add_crate_root( file_id, Edition::CURRENT, Some(display_name), None, + Some(crate_root_path), cfg_options.clone(), None, env, diff --git a/crates/vfs/src/vfs_path.rs b/crates/vfs/src/vfs_path.rs index 38501a8ba5..d327f2edf1 100644 --- a/crates/vfs/src/vfs_path.rs +++ b/crates/vfs/src/vfs_path.rs @@ -107,10 +107,7 @@ impl VfsPath { /// Returns `self`'s base name and file extension. pub fn name_and_extension(&self) -> Option<(&str, Option<&str>)> { match &self.0 { - VfsPathRepr::PathBuf(p) => Some(( - p.file_stem()?.to_str()?, - p.extension().and_then(|extension| extension.to_str()), - )), + VfsPathRepr::PathBuf(p) => p.name_and_extension(), VfsPathRepr::VirtualPath(p) => p.name_and_extension(), } } diff --git a/editors/code/src/dependencies_provider.ts b/editors/code/src/dependencies_provider.ts index 3edbb31681..aff5102e01 100644 --- a/editors/code/src/dependencies_provider.ts +++ b/editors/code/src/dependencies_provider.ts @@ -110,9 +110,13 @@ export class Dependency extends vscode.TreeItem { ) { super(label, collapsibleState); this.id = this.dependencyPath.toLowerCase(); - this.tooltip = `${this.label}-${this.version}`; this.description = this.version; this.resourceUri = vscode.Uri.file(dependencyPath); + if (this.version) { + this.tooltip = `${this.label}-${this.version}`; + } else { + this.tooltip = this.label; + } } } @@ -124,8 +128,8 @@ export class DependencyFile extends vscode.TreeItem { public readonly collapsibleState: vscode.TreeItemCollapsibleState ) { super(vscode.Uri.file(dependencyPath), collapsibleState); - const isDir = fs.lstatSync(this.dependencyPath).isDirectory(); this.id = this.dependencyPath.toLowerCase(); + const isDir = fs.lstatSync(this.dependencyPath).isDirectory(); if (!isDir) { this.command = { command: "vscode.open", title: "Open File",