diff options
author | Aleksey Kladov <[email protected]> | 2019-01-05 14:22:41 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-01-05 14:24:17 +0000 |
commit | 3ad0037f907778d20ce6cfd9bf676a467b5734ad (patch) | |
tree | dd5b7a2f8e134c0452f88f8543cc16528cc1dc9e /crates/ra_analysis/src/hover.rs | |
parent | 2560a9e8076d0b83f606af3029ea1a0c7bc48514 (diff) |
move hover implementation to ra_analysis
Diffstat (limited to 'crates/ra_analysis/src/hover.rs')
-rw-r--r-- | crates/ra_analysis/src/hover.rs | 57 |
1 files changed, 57 insertions, 0 deletions
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 @@ | |||
1 | use ra_db::{Cancelable, SyntaxDatabase}; | ||
2 | use ra_syntax::{ast, AstNode}; | ||
3 | |||
4 | use crate::{db::RootDatabase, RangeInfo, FilePosition, FileRange}; | ||
5 | |||
6 | pub(crate) fn hover( | ||
7 | db: &RootDatabase, | ||
8 | position: FilePosition, | ||
9 | ) -> Cancelable<Option<RangeInfo<String>>> { | ||
10 | let mut res = Vec::new(); | ||
11 | let range = if let Some(rr) = db.approximately_resolve_symbol(position)? { | ||
12 | for nav in rr.resolves_to { | ||
13 | res.extend(db.doc_text_for(nav)?) | ||
14 | } | ||
15 | rr.reference_range | ||
16 | } else { | ||
17 | let file = db.source_file(position.file_id); | ||
18 | let expr: ast::Expr = ctry!(ra_editor::find_node_at_offset( | ||
19 | file.syntax(), | ||
20 | position.offset | ||
21 | )); | ||
22 | let frange = FileRange { | ||
23 | file_id: position.file_id, | ||
24 | range: expr.syntax().range(), | ||
25 | }; | ||
26 | res.extend(db.type_of(frange)?); | ||
27 | expr.syntax().range() | ||
28 | }; | ||
29 | if res.is_empty() { | ||
30 | return Ok(None); | ||
31 | } | ||
32 | let res = RangeInfo::new(range, res.join("\n\n---\n")); | ||
33 | Ok(Some(res)) | ||
34 | } | ||
35 | |||
36 | #[cfg(test)] | ||
37 | mod tests { | ||
38 | use ra_syntax::TextRange; | ||
39 | |||
40 | use crate::mock_analysis::single_file_with_position; | ||
41 | |||
42 | #[test] | ||
43 | fn hover_shows_type_of_an_expression() { | ||
44 | let (analysis, position) = single_file_with_position( | ||
45 | " | ||
46 | pub fn foo() -> u32 { 1 } | ||
47 | |||
48 | fn main() { | ||
49 | let foo_test = foo()<|>; | ||
50 | } | ||
51 | ", | ||
52 | ); | ||
53 | let hover = analysis.hover(position).unwrap().unwrap(); | ||
54 | assert_eq!(hover.range, TextRange::from_to(95.into(), 100.into())); | ||
55 | assert_eq!(hover.info, "u32"); | ||
56 | } | ||
57 | } | ||