aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-01-05 14:22:41 +0000
committerAleksey Kladov <[email protected]>2019-01-05 14:24:17 +0000
commit3ad0037f907778d20ce6cfd9bf676a467b5734ad (patch)
treedd5b7a2f8e134c0452f88f8543cc16528cc1dc9e /crates/ra_analysis
parent2560a9e8076d0b83f606af3029ea1a0c7bc48514 (diff)
move hover implementation to ra_analysis
Diffstat (limited to 'crates/ra_analysis')
-rw-r--r--crates/ra_analysis/src/hover.rs57
-rw-r--r--crates/ra_analysis/src/imp.rs26
-rw-r--r--crates/ra_analysis/src/lib.rs17
3 files changed, 74 insertions, 26 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 @@
1use ra_db::{Cancelable, SyntaxDatabase};
2use ra_syntax::{ast, AstNode};
3
4use crate::{db::RootDatabase, RangeInfo, FilePosition, FileRange};
5
6pub(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)]
37mod 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}
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 {
269 Ok(result) 269 Ok(result)
270 } 270 }
271 271
272 pub(crate) fn hover(&self, position: FilePosition) -> Cancelable<Option<(TextRange, String)>> {
273 let mut res = Vec::new();
274 let range = if let Some(rr) = self.approximately_resolve_symbol(position)? {
275 for nav in rr.resolves_to {
276 res.extend(self.doc_text_for(nav)?)
277 }
278 rr.reference_range
279 } else {
280 let file = self.source_file(position.file_id);
281 let expr: ast::Expr = ctry!(ra_editor::find_node_at_offset(
282 file.syntax(),
283 position.offset
284 ));
285 let frange = FileRange {
286 file_id: position.file_id,
287 range: expr.syntax().range(),
288 };
289 res.extend(self.type_of(frange)?);
290 expr.syntax().range()
291 };
292 if res.is_empty() {
293 return Ok(None);
294 }
295 Ok(Some((range, res.join("\n\n---\n"))))
296 }
297
298 pub(crate) fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> { 272 pub(crate) fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> {
299 let syntax = self.source_file(file_id); 273 let syntax = self.source_file(file_id);
300 274
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;
21 21
22mod extend_selection; 22mod extend_selection;
23mod syntax_highlighting; 23mod syntax_highlighting;
24mod hover;
24 25
25use std::{fmt, sync::Arc}; 26use std::{fmt, sync::Arc};
26 27
@@ -260,6 +261,18 @@ impl NavigationTarget {
260 } 261 }
261} 262}
262 263
264#[derive(Debug)]
265pub struct RangeInfo<T> {
266 pub range: TextRange,
267 pub info: T,
268}
269
270impl<T> RangeInfo<T> {
271 fn new(range: TextRange, info: T) -> RangeInfo<T> {
272 RangeInfo { range, info }
273 }
274}
275
263/// Result of "goto def" query. 276/// Result of "goto def" query.
264#[derive(Debug)] 277#[derive(Debug)]
265pub struct ReferenceResolution { 278pub struct ReferenceResolution {
@@ -394,6 +407,10 @@ impl Analysis {
394 pub fn doc_text_for(&self, nav: NavigationTarget) -> Cancelable<Option<String>> { 407 pub fn doc_text_for(&self, nav: NavigationTarget) -> Cancelable<Option<String>> {
395 self.db.doc_text_for(nav) 408 self.db.doc_text_for(nav)
396 } 409 }
410 /// Returns a short text descrbing element at position.
411 pub fn hover(&self, position: FilePosition) -> Cancelable<Option<RangeInfo<String>>> {
412 hover::hover(&*self.db, position)
413 }
397 /// Returns a `mod name;` declaration which created the current module. 414 /// Returns a `mod name;` declaration which created the current module.
398 pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> { 415 pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> {
399 self.db.parent_module(position) 416 self.db.parent_module(position)