mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Use classify_name_ref in hover
This commit is contained in:
parent
cbafae6fa8
commit
34322ea9a3
@ -13,6 +13,7 @@ pub use structure::{StructureNode, file_structure};
|
||||
pub use function_signature::FunctionSignature;
|
||||
|
||||
pub(crate) use short_label::ShortLabel;
|
||||
pub(crate) use navigation_target::{docs_from_symbol, description_from_symbol};
|
||||
|
||||
pub(crate) fn function_label(node: &ast::FnDef) -> String {
|
||||
FunctionSignature::from(node).to_string()
|
||||
|
@ -413,7 +413,7 @@ impl NavigationTarget {
|
||||
}
|
||||
}
|
||||
|
||||
fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> {
|
||||
pub(crate) fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> {
|
||||
let file = db.parse(symbol.file_id).tree;
|
||||
let node = symbol.ptr.to_node(file.syntax()).to_owned();
|
||||
|
||||
@ -439,7 +439,7 @@ fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> {
|
||||
/// Get a description of a symbol.
|
||||
///
|
||||
/// e.g. `struct Name`, `enum Name`, `fn Name`
|
||||
fn description_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> {
|
||||
pub(crate) fn description_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> {
|
||||
let file = db.parse(symbol.file_id).tree;
|
||||
let node = symbol.ptr.to_node(file.syntax()).to_owned();
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use ra_db::SourceDatabase;
|
||||
use ra_syntax::{
|
||||
AstNode, ast,
|
||||
AstNode, ast::{self, DocCommentsOwner},
|
||||
algo::{find_covering_element, find_node_at_offset, ancestors_at_offset},
|
||||
};
|
||||
use hir::HirDisplay;
|
||||
@ -8,7 +8,8 @@ use hir::HirDisplay;
|
||||
use crate::{
|
||||
db::RootDatabase,
|
||||
RangeInfo, FilePosition, FileRange,
|
||||
display::{rust_code_markup, doc_text_for},
|
||||
display::{rust_code_markup, doc_text_for, rust_code_markup_with_doc, ShortLabel, docs_from_symbol, description_from_symbol},
|
||||
name_ref_kind::{NameRefKind::*, classify_name_ref},
|
||||
};
|
||||
|
||||
/// Contains the results when hovering over an item
|
||||
@ -77,25 +78,140 @@ impl HoverResult {
|
||||
}
|
||||
}
|
||||
|
||||
fn hover_text(docs: Option<String>, desc: Option<String>) -> Option<String> {
|
||||
match (desc, docs) {
|
||||
(Some(desc), docs) => Some(rust_code_markup_with_doc(desc, docs)),
|
||||
(None, Some(docs)) => Some(docs.to_string()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo<HoverResult>> {
|
||||
let file = db.parse(position.file_id).tree;
|
||||
let mut res = HoverResult::new();
|
||||
|
||||
let mut range = None;
|
||||
if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(file.syntax(), position.offset) {
|
||||
use crate::goto_definition::{ReferenceResult::*, reference_definition};
|
||||
let ref_result = reference_definition(db, position.file_id, name_ref);
|
||||
match ref_result {
|
||||
Exact(nav) => res.extend(doc_text_for(nav)),
|
||||
Approximate(navs) => {
|
||||
// We are no longer exact
|
||||
res.exact = false;
|
||||
let analyzer = hir::SourceAnalyzer::new(db, position.file_id, name_ref.syntax(), None);
|
||||
|
||||
for nav in navs {
|
||||
res.extend(doc_text_for(nav))
|
||||
match classify_name_ref(db, &analyzer, name_ref) {
|
||||
Some(Method(it)) => {
|
||||
let it = it.source(db).1;
|
||||
res.extend(hover_text(it.doc_comment_text(), it.short_label()));
|
||||
}
|
||||
Some(Macro(it)) => {
|
||||
let it = it.source(db).1;
|
||||
res.extend(hover_text(it.doc_comment_text(), None));
|
||||
}
|
||||
Some(FieldAccess(it)) => {
|
||||
let it = it.source(db).1;
|
||||
if let hir::FieldSource::Named(it) = it {
|
||||
res.extend(hover_text(it.doc_comment_text(), it.short_label()));
|
||||
}
|
||||
}
|
||||
Some(AssocItem(it)) => match it {
|
||||
hir::ImplItem::Method(it) => {
|
||||
let it = it.source(db).1;
|
||||
res.extend(hover_text(it.doc_comment_text(), it.short_label()))
|
||||
}
|
||||
hir::ImplItem::Const(it) => {
|
||||
let it = it.source(db).1;
|
||||
res.extend(hover_text(it.doc_comment_text(), it.short_label()))
|
||||
}
|
||||
hir::ImplItem::TypeAlias(it) => {
|
||||
let it = it.source(db).1;
|
||||
res.extend(hover_text(it.doc_comment_text(), it.short_label()))
|
||||
}
|
||||
},
|
||||
Some(Def(it)) => {
|
||||
match it {
|
||||
hir::ModuleDef::Module(it) => {
|
||||
let it = it.definition_source(db).1;
|
||||
if let hir::ModuleSource::Module(it) = it {
|
||||
res.extend(hover_text(it.doc_comment_text(), it.short_label()))
|
||||
}
|
||||
}
|
||||
hir::ModuleDef::Function(it) => {
|
||||
let it = it.source(db).1;
|
||||
res.extend(hover_text(it.doc_comment_text(), it.short_label()))
|
||||
}
|
||||
hir::ModuleDef::Struct(it) => {
|
||||
let it = it.source(db).1;
|
||||
res.extend(hover_text(it.doc_comment_text(), it.short_label()))
|
||||
}
|
||||
hir::ModuleDef::Union(it) => {
|
||||
let it = it.source(db).1;
|
||||
res.extend(hover_text(it.doc_comment_text(), it.short_label()))
|
||||
}
|
||||
hir::ModuleDef::Enum(it) => {
|
||||
let it = it.source(db).1;
|
||||
res.extend(hover_text(it.doc_comment_text(), it.short_label()))
|
||||
}
|
||||
hir::ModuleDef::EnumVariant(it) => {
|
||||
let it = it.source(db).1;
|
||||
res.extend(hover_text(it.doc_comment_text(), it.short_label()))
|
||||
}
|
||||
hir::ModuleDef::Const(it) => {
|
||||
let it = it.source(db).1;
|
||||
res.extend(hover_text(it.doc_comment_text(), it.short_label()))
|
||||
}
|
||||
hir::ModuleDef::Static(it) => {
|
||||
let it = it.source(db).1;
|
||||
res.extend(hover_text(it.doc_comment_text(), it.short_label()))
|
||||
}
|
||||
hir::ModuleDef::Trait(it) => {
|
||||
let it = it.source(db).1;
|
||||
res.extend(hover_text(it.doc_comment_text(), it.short_label()))
|
||||
}
|
||||
hir::ModuleDef::TypeAlias(it) => {
|
||||
let it = it.source(db).1;
|
||||
res.extend(hover_text(it.doc_comment_text(), it.short_label()))
|
||||
}
|
||||
hir::ModuleDef::BuiltinType(_) => {
|
||||
// FIXME: hover for builtin Type ?
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(SelfType(ty)) => {
|
||||
if let Some((adt_def, _)) = ty.as_adt() {
|
||||
match adt_def {
|
||||
hir::AdtDef::Struct(it) => {
|
||||
let it = it.source(db).1;
|
||||
res.extend(hover_text(it.doc_comment_text(), it.short_label()))
|
||||
}
|
||||
hir::AdtDef::Union(it) => {
|
||||
let it = it.source(db).1;
|
||||
res.extend(hover_text(it.doc_comment_text(), it.short_label()))
|
||||
}
|
||||
hir::AdtDef::Enum(it) => {
|
||||
let it = it.source(db).1;
|
||||
res.extend(hover_text(it.doc_comment_text(), it.short_label()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(Pat(_)) => {
|
||||
res.extend(None);
|
||||
}
|
||||
Some(SelfParam(_)) => {
|
||||
res.extend(None);
|
||||
}
|
||||
Some(GenericParam(_)) => {
|
||||
// FIXME: Hover for generic param
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
if res.is_empty() {
|
||||
// Fallback index based approach:
|
||||
let symbols = crate::symbol_index::index_resolve(db, name_ref);
|
||||
for sym in symbols {
|
||||
let docs = docs_from_symbol(db, &sym);
|
||||
let desc = description_from_symbol(db, &sym);
|
||||
res.extend(hover_text(docs, desc));
|
||||
}
|
||||
}
|
||||
|
||||
if !res.is_empty() {
|
||||
range = Some(name_ref.syntax().range())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user