From 3ad0037f907778d20ce6cfd9bf676a467b5734ad Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 5 Jan 2019 17:22:41 +0300 Subject: move hover implementation to ra_analysis --- crates/ra_analysis/src/hover.rs | 57 +++++++++++++++++++++++++++++++++++++++++ crates/ra_analysis/src/imp.rs | 26 ------------------- crates/ra_analysis/src/lib.rs | 17 ++++++++++++ 3 files changed, 74 insertions(+), 26 deletions(-) create mode 100644 crates/ra_analysis/src/hover.rs (limited to 'crates/ra_analysis/src') diff --git a/crates/ra_analysis/src/hover.rs b/crates/ra_analysis/src/hover.rs new file mode 100644 index 000000000..c3825f6ea --- /dev/null +++ b/crates/ra_analysis/src/hover.rs @@ -0,0 +1,57 @@ +use ra_db::{Cancelable, SyntaxDatabase}; +use ra_syntax::{ast, AstNode}; + +use crate::{db::RootDatabase, RangeInfo, FilePosition, FileRange}; + +pub(crate) fn hover( + db: &RootDatabase, + position: FilePosition, +) -> Cancelable>> { + let mut res = Vec::new(); + let range = if let Some(rr) = db.approximately_resolve_symbol(position)? { + for nav in rr.resolves_to { + res.extend(db.doc_text_for(nav)?) + } + rr.reference_range + } else { + let file = db.source_file(position.file_id); + let expr: ast::Expr = ctry!(ra_editor::find_node_at_offset( + file.syntax(), + position.offset + )); + let frange = FileRange { + file_id: position.file_id, + range: expr.syntax().range(), + }; + res.extend(db.type_of(frange)?); + expr.syntax().range() + }; + if res.is_empty() { + return Ok(None); + } + let res = RangeInfo::new(range, res.join("\n\n---\n")); + Ok(Some(res)) +} + +#[cfg(test)] +mod tests { + use ra_syntax::TextRange; + + use crate::mock_analysis::single_file_with_position; + + #[test] + fn hover_shows_type_of_an_expression() { + let (analysis, position) = single_file_with_position( + " + pub fn foo() -> u32 { 1 } + + fn main() { + let foo_test = foo()<|>; + } + ", + ); + let hover = analysis.hover(position).unwrap().unwrap(); + assert_eq!(hover.range, TextRange::from_to(95.into(), 100.into())); + assert_eq!(hover.info, "u32"); + } +} diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 10248013c..eae73c2c4 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -269,32 +269,6 @@ impl db::RootDatabase { Ok(result) } - pub(crate) fn hover(&self, position: FilePosition) -> Cancelable> { - let mut res = Vec::new(); - let range = if let Some(rr) = self.approximately_resolve_symbol(position)? { - for nav in rr.resolves_to { - res.extend(self.doc_text_for(nav)?) - } - rr.reference_range - } else { - let file = self.source_file(position.file_id); - let expr: ast::Expr = ctry!(ra_editor::find_node_at_offset( - file.syntax(), - position.offset - )); - let frange = FileRange { - file_id: position.file_id, - range: expr.syntax().range(), - }; - res.extend(self.type_of(frange)?); - expr.syntax().range() - }; - if res.is_empty() { - return Ok(None); - } - Ok(Some((range, res.join("\n\n---\n")))) - } - pub(crate) fn diagnostics(&self, file_id: FileId) -> Cancelable> { let syntax = self.source_file(file_id); diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 1e26a2889..1904ff884 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -21,6 +21,7 @@ mod runnables; mod extend_selection; mod syntax_highlighting; +mod hover; use std::{fmt, sync::Arc}; @@ -260,6 +261,18 @@ impl NavigationTarget { } } +#[derive(Debug)] +pub struct RangeInfo { + pub range: TextRange, + pub info: T, +} + +impl RangeInfo { + fn new(range: TextRange, info: T) -> RangeInfo { + RangeInfo { range, info } + } +} + /// Result of "goto def" query. #[derive(Debug)] pub struct ReferenceResolution { @@ -394,6 +407,10 @@ impl Analysis { pub fn doc_text_for(&self, nav: NavigationTarget) -> Cancelable> { self.db.doc_text_for(nav) } + /// Returns a short text descrbing element at position. + pub fn hover(&self, position: FilePosition) -> Cancelable>> { + hover::hover(&*self.db, position) + } /// Returns a `mod name;` declaration which created the current module. pub fn parent_module(&self, position: FilePosition) -> Cancelable> { self.db.parent_module(position) -- cgit v1.2.3