From 5cffef56e2c373f6d67b0f7b70d7ade995795c04 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sun, 8 Mar 2020 15:26:57 +0200 Subject: Consider crate declaration names --- crates/ra_db/src/fixture.rs | 11 +++- crates/ra_db/src/input.rs | 99 +++++++++++++++++++++++------- crates/ra_ide/src/hover.rs | 43 ++++--------- crates/ra_ide/src/lib.rs | 8 ++- crates/ra_ide/src/mock_analysis.rs | 10 ++- crates/ra_ide/src/parent_module.rs | 1 + crates/ra_ide_db/src/change.rs | 6 +- crates/ra_ide_db/src/lib.rs | 6 -- crates/ra_project_model/src/lib.rs | 13 ++-- crates/rust-analyzer/src/cli/load_cargo.rs | 11 ++-- crates/rust-analyzer/src/world.rs | 13 ++-- 11 files changed, 135 insertions(+), 86 deletions(-) (limited to 'crates') diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs index da7af110c..947d6ad56 100644 --- a/crates/ra_db/src/fixture.rs +++ b/crates/ra_db/src/fixture.rs @@ -56,6 +56,7 @@ fn with_single_file(db: &mut dyn SourceDatabaseExt, text: &str) -> FileId { crate_graph.add_crate_root( file_id, Edition::Edition2018, + None, CfgOptions::default(), Env::default(), ); @@ -98,8 +99,13 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option Option Result { @@ -97,7 +97,7 @@ impl CrateName { } } - /// Crates a crate name, unconditionally replacing the dashes with underscores. + /// Creates a crate name, unconditionally replacing the dashes with underscores. pub fn normalize_dashes(name: &str) -> CrateName { Self(SmolStr::new(name.replace('-', "_"))) } @@ -107,6 +107,7 @@ impl CrateName { struct CrateData { file_id: FileId, edition: Edition, + declaration_name: Option, cfg_options: CfgOptions, env: Env, dependencies: Vec, @@ -134,10 +135,11 @@ impl CrateGraph { &mut self, file_id: FileId, edition: Edition, + declaration_name: Option, cfg_options: CfgOptions, env: Env, ) -> CrateId { - let data = CrateData::new(file_id, edition, cfg_options, env); + let data = CrateData::new(file_id, edition, declaration_name, cfg_options, env); let crate_id = CrateId(self.arena.len() as u32); let prev = self.arena.insert(crate_id, data); assert!(prev.is_none()); @@ -177,6 +179,15 @@ impl CrateGraph { self.arena[&crate_id].edition } + /// Returns a name of a crate, declared in the root project. + /// May be missing for some cases, such as when the crate definition was created for a code snippet. + /// + /// This should not be considered as a normal crate name, since the actual name can be different in + /// a particular dependent crate, where it is specified. + pub fn declaration_name(&self, crate_id: &CrateId) -> Option<&String> { + self.arena[crate_id].declaration_name.as_ref() + } + // FIXME: this only finds one crate with the given root; we could have multiple pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option { let (&crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.file_id == file_id)?; @@ -230,8 +241,14 @@ impl CrateId { } impl CrateData { - fn new(file_id: FileId, edition: Edition, cfg_options: CfgOptions, env: Env) -> CrateData { - CrateData { file_id, edition, dependencies: Vec::new(), cfg_options, env } + fn new( + file_id: FileId, + edition: Edition, + declaration_name: Option, + cfg_options: CfgOptions, + env: Env, + ) -> CrateData { + CrateData { file_id, edition, declaration_name, dependencies: Vec::new(), cfg_options, env } } fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { @@ -290,12 +307,27 @@ mod tests { #[test] fn it_should_panic_because_of_cycle_dependencies() { let mut graph = CrateGraph::default(); - let crate1 = - graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default()); - let crate2 = - graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); - let crate3 = - graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default()); + let crate1 = graph.add_crate_root( + FileId(1u32), + Edition2018, + None, + CfgOptions::default(), + Env::default(), + ); + let crate2 = graph.add_crate_root( + FileId(2u32), + Edition2018, + None, + CfgOptions::default(), + Env::default(), + ); + let crate3 = graph.add_crate_root( + FileId(3u32), + Edition2018, + None, + CfgOptions::default(), + Env::default(), + ); assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); assert!(graph.add_dep(crate3, CrateName::new("crate1").unwrap(), crate1).is_err()); @@ -304,12 +336,27 @@ mod tests { #[test] fn it_works() { let mut graph = CrateGraph::default(); - let crate1 = - graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default()); - let crate2 = - graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); - let crate3 = - graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default()); + let crate1 = graph.add_crate_root( + FileId(1u32), + Edition2018, + None, + CfgOptions::default(), + Env::default(), + ); + let crate2 = graph.add_crate_root( + FileId(2u32), + Edition2018, + None, + CfgOptions::default(), + Env::default(), + ); + let crate3 = graph.add_crate_root( + FileId(3u32), + Edition2018, + None, + CfgOptions::default(), + Env::default(), + ); assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); } @@ -317,10 +364,20 @@ mod tests { #[test] fn dashes_are_normalized() { let mut graph = CrateGraph::default(); - let crate1 = - graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default()); - let crate2 = - graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); + let crate1 = graph.add_crate_root( + FileId(1u32), + Edition2018, + None, + CfgOptions::default(), + Env::default(), + ); + let crate2 = graph.add_crate_root( + FileId(2u32), + Edition2018, + None, + CfgOptions::default(), + Env::default(), + ); assert!(graph .add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2) .is_ok()); diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index da3b67943..f87054838 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs @@ -1,8 +1,10 @@ //! FIXME: write short doc here use hir::{ - Adt, AsAssocItem, AssocItemContainer, HasSource, HirDisplay, ModuleDef, ModuleSource, Semantics, + Adt, AsAssocItem, AssocItemContainer, FieldSource, HasSource, HirDisplay, ModuleDef, + ModuleSource, Semantics, }; +use ra_db::SourceDatabase; use ra_ide_db::{ defs::{classify_name, classify_name_ref, Definition}, RootDatabase, @@ -119,7 +121,7 @@ fn definition_owner_name(db: &RootDatabase, def: &Definition) -> Option fn determine_mod_path(db: &RootDatabase, def: &Definition) -> Option { let mod_path = def.module(db).map(|module| { - once(db.get_crate_original_name(&module.krate().into())) + once(db.crate_graph().declaration_name(&module.krate().into()).cloned()) .chain( module .path_to_root(db) @@ -144,7 +146,7 @@ fn hover_text_from_name_kind(db: &RootDatabase, def: Definition) -> Option { let src = it.source(db); match src.value { - hir::FieldSource::Named(it) => { + FieldSource::Named(it) => { hover_text(it.doc_comment_text(), it.short_label(), mod_path) } _ => None, @@ -576,21 +578,23 @@ fn func(foo: i32) { if true { <|>foo; }; } fn test_hover_infer_associated_method_exact() { let (analysis, position) = single_file_with_position( " - struct Thing { x: u32 } + mod wrapper { + struct Thing { x: u32 } - impl Thing { - fn new() -> Thing { - Thing { x: 0 } + impl Thing { + fn new() -> Thing { + Thing { x: 0 } + } } } fn main() { - let foo_test = Thing::new<|>(); + let foo_test = wrapper::Thing::new<|>(); } ", ); let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup_opt(hover.info.first()), Some("fn new() -> Thing")); + assert_eq!(trim_markup_opt(hover.info.first()), Some("wrapper::Thing\nfn new() -> Thing")); assert_eq!(hover.info.is_exact(), true); } @@ -863,25 +867,4 @@ fn func(foo: i32) { if true { <|>foo; }; } &["fn foo()\n```\n\n<- `\u{3000}` here"], ); } - - #[test] - fn zzz() { - check_hover_result( - " - //- /main.rs - mod vvv { - pub struct Test; - - impl Test { - pub fn whatever() {} - } - } - - fn main() { - vvv::Test::what<|>ever(); - } - ", - &["vvv::Test\npub fn whatever()"], - ); - } } diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs index 4dfe0553e..56bc57d5c 100644 --- a/crates/ra_ide/src/lib.rs +++ b/crates/ra_ide/src/lib.rs @@ -211,7 +211,13 @@ impl Analysis { // Default to enable test for single file. let mut cfg_options = CfgOptions::default(); cfg_options.insert_atom("test".into()); - crate_graph.add_crate_root(file_id, Edition::Edition2018, cfg_options, Env::default()); + crate_graph.add_crate_root( + file_id, + Edition::Edition2018, + None, + cfg_options, + Env::default(), + ); change.add_file(source_root, file_id, "main.rs".into(), Arc::new(text)); change.set_crate_graph(crate_graph); host.apply_change(change); diff --git a/crates/ra_ide/src/mock_analysis.rs b/crates/ra_ide/src/mock_analysis.rs index f4cd6deb7..90f84b052 100644 --- a/crates/ra_ide/src/mock_analysis.rs +++ b/crates/ra_ide/src/mock_analysis.rs @@ -99,13 +99,19 @@ impl MockAnalysis { root_crate = Some(crate_graph.add_crate_root( file_id, Edition2018, + None, cfg_options, Env::default(), )); } else if path.ends_with("/lib.rs") { - let other_crate = - crate_graph.add_crate_root(file_id, Edition2018, cfg_options, Env::default()); let crate_name = path.parent().unwrap().file_name().unwrap(); + let other_crate = crate_graph.add_crate_root( + file_id, + Edition2018, + Some(crate_name.to_owned()), + cfg_options, + Env::default(), + ); if let Some(root_crate) = root_crate { crate_graph .add_dep(root_crate, CrateName::new(crate_name).unwrap(), other_crate) diff --git a/crates/ra_ide/src/parent_module.rs b/crates/ra_ide/src/parent_module.rs index 2c4bdb039..b73cefd97 100644 --- a/crates/ra_ide/src/parent_module.rs +++ b/crates/ra_ide/src/parent_module.rs @@ -133,6 +133,7 @@ mod tests { let crate_id = crate_graph.add_crate_root( root_file, Edition2018, + None, CfgOptions::default(), Env::default(), ); diff --git a/crates/ra_ide_db/src/change.rs b/crates/ra_ide_db/src/change.rs index 8b5be9d21..628cf6416 100644 --- a/crates/ra_ide_db/src/change.rs +++ b/crates/ra_ide_db/src/change.rs @@ -5,7 +5,7 @@ use std::{fmt, sync::Arc, time}; use ra_db::{ salsa::{Database, Durability, SweepStrategy}, - CrateGraph, CrateId, FileId, RelativePathBuf, SourceDatabase, SourceDatabaseExt, SourceRoot, + CrateGraph, FileId, RelativePathBuf, SourceDatabase, SourceDatabaseExt, SourceRoot, SourceRootId, }; use ra_prof::{memory_usage, profile, Bytes}; @@ -88,10 +88,6 @@ impl AnalysisChange { self.crate_graph = Some(graph); } - pub fn set_debug_crate_name(&mut self, crate_id: CrateId, name: String) { - self.debug_data.crate_names.insert(crate_id, name); - } - pub fn set_debug_root_path(&mut self, source_root_id: SourceRootId, path: String) { self.debug_data.root_paths.insert(source_root_id, path); } diff --git a/crates/ra_ide_db/src/lib.rs b/crates/ra_ide_db/src/lib.rs index efa472c7d..a105c7556 100644 --- a/crates/ra_ide_db/src/lib.rs +++ b/crates/ra_ide_db/src/lib.rs @@ -104,10 +104,6 @@ impl RootDatabase { db.query_mut(hir::db::MacroExpandQuery).set_lru_capacity(lru_capacity); db } - - pub fn get_crate_original_name(&self, crate_id: &CrateId) -> Option { - self.debug_data.crate_names.get(crate_id).cloned() - } } impl salsa::ParallelDatabase for RootDatabase { @@ -135,12 +131,10 @@ fn line_index(db: &impl LineIndexDatabase, file_id: FileId) -> Arc { #[derive(Debug, Default, Clone)] pub(crate) struct DebugData { pub(crate) root_paths: FxHashMap, - pub(crate) crate_names: FxHashMap, } impl DebugData { pub(crate) fn merge(&mut self, other: DebugData) { self.root_paths.extend(other.root_paths.into_iter()); - self.crate_names.extend(other.crate_names.into_iter()); } } diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index bcf12460d..37845ca56 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -14,7 +14,7 @@ use std::{ use anyhow::{bail, Context, Result}; use ra_cfg::CfgOptions; -use ra_db::{CrateGraph, CrateId, CrateName, Edition, Env, FileId}; +use ra_db::{CrateGraph, CrateName, Edition, Env, FileId}; use rustc_hash::FxHashMap; use serde_json::from_reader; @@ -163,9 +163,8 @@ impl ProjectWorkspace { &self, default_cfg_options: &CfgOptions, load: &mut dyn FnMut(&Path) -> Option, - ) -> (CrateGraph, FxHashMap) { + ) -> CrateGraph { let mut crate_graph = CrateGraph::default(); - let mut names = FxHashMap::default(); match self { ProjectWorkspace::Json { project } => { let mut crates = FxHashMap::default(); @@ -191,6 +190,8 @@ impl ProjectWorkspace { crate_graph.add_crate_root( file_id, edition, + // FIXME json definitions can store the crate name + None, cfg_options, Env::default(), ), @@ -233,11 +234,11 @@ impl ProjectWorkspace { let crate_id = crate_graph.add_crate_root( file_id, Edition::Edition2018, + Some(krate.name(&sysroot).to_string()), cfg_options, Env::default(), ); sysroot_crates.insert(krate, crate_id); - names.insert(crate_id, krate.name(&sysroot).to_string()); } } for from in sysroot.crates() { @@ -277,10 +278,10 @@ impl ProjectWorkspace { let crate_id = crate_graph.add_crate_root( file_id, edition, + Some(pkg.name(&cargo).to_string()), cfg_options, Env::default(), ); - names.insert(crate_id, pkg.name(&cargo).to_string()); if tgt.kind(&cargo) == TargetKind::Lib { lib_tgt = Some(crate_id); pkg_to_lib_crate.insert(pkg, crate_id); @@ -381,7 +382,7 @@ impl ProjectWorkspace { } } } - (crate_graph, names) + crate_graph } pub fn workspace_root_for(&self, path: &Path) -> Option<&Path> { diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index 8cd08ecb6..4be987860 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs @@ -52,12 +52,11 @@ pub(crate) fn load_cargo( opts }; - let (crate_graph, _crate_names) = - ws.to_crate_graph(&default_cfg_options, &mut |path: &Path| { - let vfs_file = vfs.load(path); - log::debug!("vfs file {:?} -> {:?}", path, vfs_file); - vfs_file.map(vfs_file_to_id) - }); + let crate_graph = ws.to_crate_graph(&default_cfg_options, &mut |path: &Path| { + let vfs_file = vfs.load(path); + log::debug!("vfs file {:?} -> {:?}", path, vfs_file); + vfs_file.map(vfs_file_to_id) + }); log::debug!("crate graph: {:?}", crate_graph); let source_roots = roots diff --git a/crates/rust-analyzer/src/world.rs b/crates/rust-analyzer/src/world.rs index 96efab844..c92cf137c 100644 --- a/crates/rust-analyzer/src/world.rs +++ b/crates/rust-analyzer/src/world.rs @@ -123,13 +123,12 @@ impl WorldState { let vfs_file = vfs.load(path); vfs_file.map(|f| FileId(f.0)) }; - for ws in workspaces.iter() { - let (graph, crate_names) = ws.to_crate_graph(&default_cfg_options, &mut load); - let shift = crate_graph.extend(graph); - for (crate_id, name) in crate_names { - change.set_debug_crate_name(crate_id.shift(shift), name) - } - } + + workspaces.iter().map(|ws| ws.to_crate_graph(&default_cfg_options, &mut load)).for_each( + |graph| { + crate_graph.extend(graph); + }, + ); change.set_crate_graph(crate_graph); // FIXME: Figure out the multi-workspace situation -- cgit v1.2.3