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_ide/src/display.rs | 14 +++-- crates/ra_ide/src/hover.rs | 119 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 104 insertions(+), 29 deletions(-) (limited to 'crates/ra_ide') 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()"], + ); + } } -- 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_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 + 4 files changed, 29 insertions(+), 33 deletions(-) (limited to 'crates/ra_ide') 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(), ); -- 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_ide/src/hover.rs | 4 ++-- crates/ra_ide/src/lib.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'crates/ra_ide') 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