From 32f5276465266522ebc01b8417feeba99bf00f6f Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 6 Mar 2020 01:02:14 +0200 Subject: Show mod path in hover tooltip --- crates/ra_hir/src/code_model.rs | 24 ++++++++ crates/ra_ide/src/display.rs | 14 +++-- crates/ra_ide/src/hover.rs | 119 +++++++++++++++++++++++++++++++--------- crates/ra_ide_db/src/lib.rs | 4 ++ 4 files changed, 132 insertions(+), 29 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 2944926e6..dca5f27b2 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -480,6 +480,14 @@ impl Adt { pub fn krate(self, db: &impl HirDatabase) -> Option { Some(self.module(db).krate()) } + + pub fn name(&self, db: &impl HirDatabase) -> Name { + match self { + Adt::Struct(s) => s.name(db), + Adt::Union(u) => u.name(db), + Adt::Enum(e) => e.name(db), + } + } } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] @@ -507,6 +515,14 @@ impl VariantDef { } } + pub fn name(&self, db: &impl HirDatabase) -> Name { + match self { + VariantDef::Struct(s) => s.name(db), + VariantDef::Union(u) => u.name(db), + VariantDef::EnumVariant(e) => e.name(db), + } + } + pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc { match self { VariantDef::Struct(it) => it.variant_data(db), @@ -534,6 +550,14 @@ impl DefWithBody { DefWithBody::Static(s) => s.module(db), } } + + pub fn name(self, db: &impl HirDatabase) -> Option { + match self { + DefWithBody::Function(f) => Some(f.name(db)), + DefWithBody::Static(s) => s.name(db), + DefWithBody::Const(c) => c.name(db), + } + } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] diff --git a/crates/ra_ide/src/display.rs b/crates/ra_ide/src/display.rs index 1c26a8697..eaeaaa2b4 100644 --- a/crates/ra_ide/src/display.rs +++ b/crates/ra_ide/src/display.rs @@ -68,17 +68,23 @@ pub(crate) fn macro_label(node: &ast::MacroCall) -> String { } pub(crate) fn rust_code_markup>(val: CODE) -> String { - rust_code_markup_with_doc::<_, &str>(val, None) + rust_code_markup_with_doc::<_, &str>(val, None, None) } -pub(crate) fn rust_code_markup_with_doc(val: CODE, doc: Option) -> String +pub(crate) fn rust_code_markup_with_doc( + val: CODE, + doc: Option, + mod_path: Option, +) -> String where CODE: AsRef, DOC: AsRef, { + let mod_path = + mod_path.filter(|path| !path.is_empty()).map(|path| path + "\n").unwrap_or_default(); if let Some(doc) = doc { - format!("```rust\n{}\n```\n\n{}", val.as_ref(), doc.as_ref()) + format!("```rust\n{}{}\n```\n\n{}", mod_path, val.as_ref(), doc.as_ref()) } else { - format!("```rust\n{}\n```", val.as_ref()) + format!("```rust\n{}{}\n```", mod_path, val.as_ref()) } } diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index e9c682557..da3b67943 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs @@ -1,6 +1,8 @@ //! FIXME: write short doc here -use hir::{Adt, HasSource, HirDisplay, Semantics}; +use hir::{ + Adt, AsAssocItem, AssocItemContainer, HasSource, HirDisplay, ModuleDef, ModuleSource, Semantics, +}; use ra_ide_db::{ defs::{classify_name, classify_name_ref, Definition}, RootDatabase, @@ -16,6 +18,8 @@ use crate::{ display::{macro_label, rust_code_markup, rust_code_markup_with_doc, ShortLabel}, FilePosition, RangeInfo, }; +use itertools::Itertools; +use std::iter::once; /// Contains the results when hovering over an item #[derive(Debug, Clone)] @@ -83,44 +87,86 @@ impl HoverResult { } } -fn hover_text(docs: Option, desc: Option) -> Option { - match (desc, docs) { - (Some(desc), docs) => Some(rust_code_markup_with_doc(desc, docs)), - (None, Some(docs)) => Some(docs), +fn hover_text( + docs: Option, + desc: Option, + mod_path: Option, +) -> Option { + match (desc, docs, mod_path) { + (Some(desc), docs, mod_path) => Some(rust_code_markup_with_doc(desc, docs, mod_path)), + (None, Some(docs), _) => Some(docs), _ => None, } } +fn definition_owner_name(db: &RootDatabase, def: &Definition) -> Option { + match def { + Definition::StructField(f) => Some(f.parent_def(db).name(db)), + Definition::Local(l) => l.parent(db).name(db), + Definition::ModuleDef(md) => match md { + ModuleDef::Function(f) => match f.as_assoc_item(db)?.container(db) { + AssocItemContainer::Trait(t) => Some(t.name(db)), + AssocItemContainer::ImplDef(i) => i.target_ty(db).as_adt().map(|adt| adt.name(db)), + }, + ModuleDef::EnumVariant(e) => Some(e.parent_enum(db).name(db)), + _ => None, + }, + Definition::SelfType(i) => i.target_ty(db).as_adt().map(|adt| adt.name(db)), + _ => None, + } + .map(|name| name.to_string()) +} + +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())) + .chain( + module + .path_to_root(db) + .into_iter() + .rev() + .map(|it| it.name(db).map(|name| name.to_string())), + ) + .chain(once(definition_owner_name(db, def))) + .filter_map(std::convert::identity) + .join("::") + }); + mod_path +} + fn hover_text_from_name_kind(db: &RootDatabase, def: Definition) -> Option { + let mod_path = determine_mod_path(db, &def); return match def { Definition::Macro(it) => { let src = it.source(db); - hover_text(src.value.doc_comment_text(), Some(macro_label(&src.value))) + hover_text(src.value.doc_comment_text(), Some(macro_label(&src.value)), mod_path) } Definition::StructField(it) => { let src = it.source(db); match src.value { - hir::FieldSource::Named(it) => hover_text(it.doc_comment_text(), it.short_label()), + hir::FieldSource::Named(it) => { + hover_text(it.doc_comment_text(), it.short_label(), mod_path) + } _ => None, } } Definition::ModuleDef(it) => match it { - hir::ModuleDef::Module(it) => match it.definition_source(db).value { - hir::ModuleSource::Module(it) => { - hover_text(it.doc_comment_text(), it.short_label()) + ModuleDef::Module(it) => match it.definition_source(db).value { + ModuleSource::Module(it) => { + hover_text(it.doc_comment_text(), it.short_label(), mod_path) } _ => None, }, - hir::ModuleDef::Function(it) => from_def_source(db, it), - hir::ModuleDef::Adt(Adt::Struct(it)) => from_def_source(db, it), - hir::ModuleDef::Adt(Adt::Union(it)) => from_def_source(db, it), - hir::ModuleDef::Adt(Adt::Enum(it)) => from_def_source(db, it), - hir::ModuleDef::EnumVariant(it) => from_def_source(db, it), - hir::ModuleDef::Const(it) => from_def_source(db, it), - hir::ModuleDef::Static(it) => from_def_source(db, it), - hir::ModuleDef::Trait(it) => from_def_source(db, it), - hir::ModuleDef::TypeAlias(it) => from_def_source(db, it), - hir::ModuleDef::BuiltinType(it) => Some(it.to_string()), + ModuleDef::Function(it) => from_def_source(db, it, mod_path), + ModuleDef::Adt(Adt::Struct(it)) => from_def_source(db, it, mod_path), + ModuleDef::Adt(Adt::Union(it)) => from_def_source(db, it, mod_path), + ModuleDef::Adt(Adt::Enum(it)) => from_def_source(db, it, mod_path), + ModuleDef::EnumVariant(it) => from_def_source(db, it, mod_path), + ModuleDef::Const(it) => from_def_source(db, it, mod_path), + ModuleDef::Static(it) => from_def_source(db, it, mod_path), + ModuleDef::Trait(it) => from_def_source(db, it, mod_path), + ModuleDef::TypeAlias(it) => from_def_source(db, it, mod_path), + ModuleDef::BuiltinType(it) => Some(it.to_string()), }, Definition::Local(it) => { Some(rust_code_markup(it.ty(db).display_truncated(db, None).to_string())) @@ -131,13 +177,13 @@ fn hover_text_from_name_kind(db: &RootDatabase, def: Definition) -> Option(db: &RootDatabase, def: D) -> Option + fn from_def_source(db: &RootDatabase, def: D, mod_path: Option) -> Option where D: HasSource, A: ast::DocCommentsOwner + ast::NameOwner + ShortLabel, { let src = def.source(db); - hover_text(src.value.doc_comment_text(), src.value.short_label()) + hover_text(src.value.doc_comment_text(), src.value.short_label(), mod_path) } } @@ -345,7 +391,7 @@ mod tests { }; } "#, - &["field_a: u32"], + &["Foo\nfield_a: u32"], ); // Hovering over the field in the definition @@ -362,7 +408,7 @@ mod tests { }; } "#, - &["field_a: u32"], + &["Foo\nfield_a: u32"], ); } @@ -415,7 +461,7 @@ fn main() { ", ); let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup_opt(hover.info.first()), Some("Some")); + assert_eq!(trim_markup_opt(hover.info.first()), Some("Option\nSome")); let (analysis, position) = single_file_with_position( " @@ -442,6 +488,7 @@ fn main() { } "#, &[" +Option None ``` @@ -462,6 +509,7 @@ The None variant } "#, &[" +Option Some ``` @@ -815,4 +863,25 @@ 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_db/src/lib.rs b/crates/ra_ide_db/src/lib.rs index 79f48c9e3..efa472c7d 100644 --- a/crates/ra_ide_db/src/lib.rs +++ b/crates/ra_ide_db/src/lib.rs @@ -104,6 +104,10 @@ 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 { -- cgit v1.2.3 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 From e1aa96f2c5b6cdbf0fb7f49b47209055b7a937f2 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 9 Mar 2020 11:26:46 +0200 Subject: Less abstract CrateData api --- crates/ra_db/src/input.rs | 60 ++++++++++++++---------------- crates/ra_hir/src/code_model.rs | 13 ++++--- crates/ra_hir_def/src/find_path.rs | 2 +- crates/ra_hir_def/src/lang_item.rs | 4 +- crates/ra_hir_def/src/nameres.rs | 3 +- crates/ra_hir_def/src/nameres/collector.rs | 7 ++-- crates/ra_hir_ty/src/traits.rs | 2 +- crates/ra_ide/src/hover.rs | 4 +- crates/ra_ide/src/lib.rs | 4 +- 9 files changed, 48 insertions(+), 51 deletions(-) (limited to 'crates') diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index 7b9f4efe4..4069c0fed 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs @@ -104,13 +104,16 @@ impl CrateName { } #[derive(Debug, Clone, PartialEq, Eq)] -struct CrateData { - file_id: FileId, - edition: Edition, - declaration_name: Option, +pub struct CrateData { + pub root_file_id: FileId, + pub edition: Edition, + /// The name to display to the end user. + /// This actual crate name can be different in a particular dependent crate + /// or may even be missing for some cases, such as a dummy crate for the code snippet. + pub display_name: Option, cfg_options: CfgOptions, env: Env, - dependencies: Vec, + pub dependencies: Vec, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -135,11 +138,11 @@ impl CrateGraph { &mut self, file_id: FileId, edition: Edition, - declaration_name: Option, + display_name: Option, cfg_options: CfgOptions, env: Env, ) -> CrateId { - let data = CrateData::new(file_id, edition, declaration_name, cfg_options, env); + let data = CrateData::new(file_id, edition, display_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()); @@ -171,33 +174,17 @@ impl CrateGraph { self.arena.keys().copied() } - pub fn crate_root(&self, crate_id: CrateId) -> FileId { - self.arena[&crate_id].file_id - } - - pub fn edition(&self, crate_id: CrateId) -> Edition { - 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() + pub fn crate_data(&self, crate_id: &CrateId) -> &CrateData { + &self.arena[crate_id] } // 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)?; + let (&crate_id, _) = + self.arena.iter().find(|(_crate_id, data)| data.root_file_id == file_id)?; Some(crate_id) } - pub fn dependencies(&self, crate_id: CrateId) -> impl Iterator { - self.arena[&crate_id].dependencies.iter() - } - /// Extends this crate graph by adding a complete disjoint second crate /// graph. /// @@ -220,7 +207,7 @@ impl CrateGraph { return false; } - for dep in self.dependencies(from) { + for dep in &self.crate_data(&from).dependencies { let crate_id = dep.crate_id(); if crate_id == target { return true; @@ -242,13 +229,20 @@ impl CrateId { impl CrateData { fn new( - file_id: FileId, + root_file_id: FileId, edition: Edition, - declaration_name: Option, + display_name: Option, cfg_options: CfgOptions, env: Env, ) -> CrateData { - CrateData { file_id, edition, declaration_name, dependencies: Vec::new(), cfg_options, env } + CrateData { + root_file_id, + edition, + display_name, + dependencies: Vec::new(), + cfg_options, + env, + } } fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { @@ -382,8 +376,8 @@ mod tests { .add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2) .is_ok()); assert_eq!( - graph.dependencies(crate1).collect::>(), - vec![&Dependency { crate_id: crate2, name: "crate_name_with_dashes".into() }] + graph.crate_data(&crate1).dependencies, + vec![Dependency { crate_id: crate2, name: "crate_name_with_dashes".into() }] ); } } diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index dca5f27b2..9685d6982 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -55,7 +55,9 @@ pub struct CrateDependency { impl Crate { pub fn dependencies(self, db: &impl DefDatabase) -> Vec { db.crate_graph() - .dependencies(self.id) + .crate_data(&self.id) + .dependencies + .iter() .map(|dep| { let krate = Crate { id: dep.crate_id() }; let name = dep.as_name(); @@ -69,7 +71,9 @@ impl Crate { let crate_graph = db.crate_graph(); crate_graph .iter() - .filter(|&krate| crate_graph.dependencies(krate).any(|it| it.crate_id == self.id)) + .filter(|&krate| { + crate_graph.crate_data(&krate).dependencies.iter().any(|it| it.crate_id == self.id) + }) .map(|id| Crate { id }) .collect() } @@ -80,12 +84,11 @@ impl Crate { } pub fn root_file(self, db: &impl DefDatabase) -> FileId { - db.crate_graph().crate_root(self.id) + db.crate_graph().crate_data(&self.id).root_file_id } pub fn edition(self, db: &impl DefDatabase) -> Edition { - let crate_graph = db.crate_graph(); - crate_graph.edition(self.id) + db.crate_graph().crate_data(&self.id).edition } pub fn all(db: &impl DefDatabase) -> Vec { diff --git a/crates/ra_hir_def/src/find_path.rs b/crates/ra_hir_def/src/find_path.rs index 43b9b124a..217e19b01 100644 --- a/crates/ra_hir_def/src/find_path.rs +++ b/crates/ra_hir_def/src/find_path.rs @@ -176,7 +176,7 @@ fn find_importable_locations( // directly (only through reexports in direct dependencies). for krate in Some(from.krate) .into_iter() - .chain(crate_graph.dependencies(from.krate).map(|dep| dep.crate_id)) + .chain(crate_graph.crate_data(&from.krate).dependencies.iter().map(|dep| dep.crate_id)) { result.extend( importable_locations_in_crate(db, item, krate) diff --git a/crates/ra_hir_def/src/lang_item.rs b/crates/ra_hir_def/src/lang_item.rs index 5a336ea1f..79e8d8038 100644 --- a/crates/ra_hir_def/src/lang_item.rs +++ b/crates/ra_hir_def/src/lang_item.rs @@ -117,7 +117,9 @@ impl LangItems { return Some(*target); } db.crate_graph() - .dependencies(start_crate) + .crate_data(&start_crate) + .dependencies + .iter() .find_map(|dep| db.lang_item(dep.crate_id, item.clone())) } diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index 628c44c99..6af0f4a8e 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -179,8 +179,7 @@ impl CrateDefMap { pub(crate) fn crate_def_map_query(db: &impl DefDatabase, krate: CrateId) -> Arc { let _p = profile("crate_def_map_query"); let def_map = { - let crate_graph = db.crate_graph(); - let edition = crate_graph.edition(krate); + let edition = db.crate_graph().crate_data(&krate).edition; let mut modules: Arena = Arena::default(); let root = modules.alloc(ModuleData::default()); CrateDefMap { diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 51c65a5d7..e69f89b80 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -34,7 +34,7 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C let crate_graph = db.crate_graph(); // populate external prelude - for dep in crate_graph.dependencies(def_map.krate) { + for dep in &crate_graph.crate_data(&def_map.krate).dependencies { let dep_def_map = db.crate_def_map(dep.crate_id); log::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id); def_map.extern_prelude.insert( @@ -128,8 +128,7 @@ where DB: DefDatabase, { fn collect(&mut self) { - let crate_graph = self.db.crate_graph(); - let file_id = crate_graph.crate_root(self.def_map.krate); + let file_id = self.db.crate_graph().crate_data(&self.def_map.krate).root_file_id; let raw_items = self.db.raw_items(file_id.into()); let module_id = self.def_map.root; self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id }; @@ -955,7 +954,7 @@ mod tests { let krate = db.test_crate(); let def_map = { - let edition = db.crate_graph().edition(krate); + let edition = db.crate_graph().crate_data(&krate).edition; let mut modules: Arena = Arena::default(); let root = modules.alloc(ModuleData::default()); CrateDefMap { diff --git a/crates/ra_hir_ty/src/traits.rs b/crates/ra_hir_ty/src/traits.rs index 8de588790..6c653c4f5 100644 --- a/crates/ra_hir_ty/src/traits.rs +++ b/crates/ra_hir_ty/src/traits.rs @@ -47,7 +47,7 @@ pub(crate) fn impls_for_trait_query( // will only ever get called for a few crates near the root of the tree (the // ones the user is editing), so this may actually be a waste of memory. I'm // doing it like this mainly for simplicity for now. - for dep in db.crate_graph().dependencies(krate) { + for dep in &db.crate_graph().crate_data(&krate).dependencies { impls.extend(db.impls_for_trait(dep.crate_id, trait_).iter()); } let crate_impl_defs = db.impls_in_crate(krate); diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index f87054838..8b8af35fc 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs @@ -121,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.crate_graph().declaration_name(&module.krate().into()).cloned()) + once(db.crate_graph().crate_data(&module.krate().into()).display_name.clone()) .chain( module .path_to_root(db) @@ -130,7 +130,7 @@ fn determine_mod_path(db: &RootDatabase, def: &Definition) -> Option { .map(|it| it.name(db).map(|name| name.to_string())), ) .chain(once(definition_owner_name(db, def))) - .filter_map(std::convert::identity) + .flatten() .join("::") }); mod_path diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs index 56bc57d5c..903624381 100644 --- a/crates/ra_ide/src/lib.rs +++ b/crates/ra_ide/src/lib.rs @@ -421,12 +421,12 @@ impl Analysis { /// Returns the edition of the given crate. pub fn crate_edition(&self, crate_id: CrateId) -> Cancelable { - self.with_db(|db| db.crate_graph().edition(crate_id)) + self.with_db(|db| db.crate_graph().crate_data(&crate_id).edition) } /// Returns the root file of the given crate. pub fn crate_root(&self, crate_id: CrateId) -> Cancelable { - self.with_db(|db| db.crate_graph().crate_root(crate_id)) + self.with_db(|db| db.crate_graph().crate_data(&crate_id).root_file_id) } /// Returns the set of possible targets to run for the current file. -- cgit v1.2.3