aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_analysis/src/hover.rs111
-rw-r--r--crates/ra_analysis/src/imp.rs104
-rw-r--r--crates/ra_analysis/src/lib.rs4
3 files changed, 110 insertions, 109 deletions
diff --git a/crates/ra_analysis/src/hover.rs b/crates/ra_analysis/src/hover.rs
index c3825f6ea..c99d87da6 100644
--- a/crates/ra_analysis/src/hover.rs
+++ b/crates/ra_analysis/src/hover.rs
@@ -1,7 +1,11 @@
1use ra_db::{Cancelable, SyntaxDatabase}; 1use ra_db::{Cancelable, SyntaxDatabase};
2use ra_syntax::{ast, AstNode}; 2use ra_syntax::{
3 AstNode, SyntaxNode,
4 ast::{self, NameOwner},
5 algo::visit::{visitor, Visitor},
6};
3 7
4use crate::{db::RootDatabase, RangeInfo, FilePosition, FileRange}; 8use crate::{db::RootDatabase, RangeInfo, FilePosition, FileRange, NavigationTarget};
5 9
6pub(crate) fn hover( 10pub(crate) fn hover(
7 db: &RootDatabase, 11 db: &RootDatabase,
@@ -10,7 +14,7 @@ pub(crate) fn hover(
10 let mut res = Vec::new(); 14 let mut res = Vec::new();
11 let range = if let Some(rr) = db.approximately_resolve_symbol(position)? { 15 let range = if let Some(rr) = db.approximately_resolve_symbol(position)? {
12 for nav in rr.resolves_to { 16 for nav in rr.resolves_to {
13 res.extend(db.doc_text_for(nav)?) 17 res.extend(doc_text_for(db, nav)?)
14 } 18 }
15 rr.reference_range 19 rr.reference_range
16 } else { 20 } else {
@@ -33,6 +37,107 @@ pub(crate) fn hover(
33 Ok(Some(res)) 37 Ok(Some(res))
34} 38}
35 39
40// FIXME: this should not really use navigation target. Rather, approximatelly
41// resovled symbol should return a `DefId`.
42fn doc_text_for(db: &RootDatabase, nav: NavigationTarget) -> Cancelable<Option<String>> {
43 let result = match (nav.description(db), nav.docs(db)) {
44 (Some(desc), Some(docs)) => Some("```rust\n".to_string() + &*desc + "\n```\n\n" + &*docs),
45 (Some(desc), None) => Some("```rust\n".to_string() + &*desc + "\n```"),
46 (None, Some(docs)) => Some(docs),
47 _ => None,
48 };
49
50 Ok(result)
51}
52
53impl NavigationTarget {
54 fn node(&self, db: &RootDatabase) -> Option<SyntaxNode> {
55 let source_file = db.source_file(self.file_id);
56 let source_file = source_file.syntax();
57 let node = source_file
58 .descendants()
59 .find(|node| node.kind() == self.kind && node.range() == self.range)?
60 .owned();
61 Some(node)
62 }
63
64 fn docs(&self, db: &RootDatabase) -> Option<String> {
65 let node = self.node(db)?;
66 let node = node.borrowed();
67 fn doc_comments<'a, N: ast::DocCommentsOwner<'a>>(node: N) -> Option<String> {
68 let comments = node.doc_comment_text();
69 if comments.is_empty() {
70 None
71 } else {
72 Some(comments)
73 }
74 }
75
76 visitor()
77 .visit(doc_comments::<ast::FnDef>)
78 .visit(doc_comments::<ast::StructDef>)
79 .visit(doc_comments::<ast::EnumDef>)
80 .visit(doc_comments::<ast::TraitDef>)
81 .visit(doc_comments::<ast::Module>)
82 .visit(doc_comments::<ast::TypeDef>)
83 .visit(doc_comments::<ast::ConstDef>)
84 .visit(doc_comments::<ast::StaticDef>)
85 .accept(node)?
86 }
87
88 /// Get a description of this node.
89 ///
90 /// e.g. `struct Name`, `enum Name`, `fn Name`
91 fn description(&self, db: &RootDatabase) -> Option<String> {
92 // TODO: After type inference is done, add type information to improve the output
93 let node = self.node(db)?;
94 let node = node.borrowed();
95 // TODO: Refactor to be have less repetition
96 visitor()
97 .visit(|node: ast::FnDef| {
98 let mut string = "fn ".to_string();
99 node.name()?.syntax().text().push_to(&mut string);
100 Some(string)
101 })
102 .visit(|node: ast::StructDef| {
103 let mut string = "struct ".to_string();
104 node.name()?.syntax().text().push_to(&mut string);
105 Some(string)
106 })
107 .visit(|node: ast::EnumDef| {
108 let mut string = "enum ".to_string();
109 node.name()?.syntax().text().push_to(&mut string);
110 Some(string)
111 })
112 .visit(|node: ast::TraitDef| {
113 let mut string = "trait ".to_string();
114 node.name()?.syntax().text().push_to(&mut string);
115 Some(string)
116 })
117 .visit(|node: ast::Module| {
118 let mut string = "mod ".to_string();
119 node.name()?.syntax().text().push_to(&mut string);
120 Some(string)
121 })
122 .visit(|node: ast::TypeDef| {
123 let mut string = "type ".to_string();
124 node.name()?.syntax().text().push_to(&mut string);
125 Some(string)
126 })
127 .visit(|node: ast::ConstDef| {
128 let mut string = "const ".to_string();
129 node.name()?.syntax().text().push_to(&mut string);
130 Some(string)
131 })
132 .visit(|node: ast::StaticDef| {
133 let mut string = "static ".to_string();
134 node.name()?.syntax().text().push_to(&mut string);
135 Some(string)
136 })
137 .accept(node)?
138 }
139}
140
36#[cfg(test)] 141#[cfg(test)]
37mod tests { 142mod tests {
38 use ra_syntax::TextRange; 143 use ra_syntax::TextRange;
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index eae73c2c4..1e9129c4f 100644
--- a/crates/ra_analysis/src/imp.rs
+++ b/crates/ra_analysis/src/imp.rs
@@ -8,11 +8,11 @@ use hir::{
8use ra_db::{FilesDatabase, SourceRoot, SourceRootId, SyntaxDatabase}; 8use ra_db::{FilesDatabase, SourceRoot, SourceRootId, SyntaxDatabase};
9use ra_editor::{self, find_node_at_offset, assists, LocalEdit, Severity}; 9use ra_editor::{self, find_node_at_offset, assists, LocalEdit, Severity};
10use ra_syntax::{ 10use ra_syntax::{
11 algo::{find_covering_node, visit::{visitor, Visitor}}, 11 algo::find_covering_node,
12 ast::{self, ArgListOwner, Expr, FnDef, NameOwner}, 12 ast::{self, ArgListOwner, Expr, FnDef, NameOwner},
13 AstNode, SourceFileNode, 13 AstNode, SourceFileNode,
14 SyntaxKind::*, 14 SyntaxKind::*,
15 SyntaxNode, SyntaxNodeRef, TextRange, TextUnit, 15 SyntaxNodeRef, TextRange, TextUnit,
16}; 16};
17 17
18use crate::{ 18use crate::{
@@ -256,18 +256,6 @@ impl db::RootDatabase {
256 Ok(Some((binding, descr))) 256 Ok(Some((binding, descr)))
257 } 257 }
258 } 258 }
259 pub(crate) fn doc_text_for(&self, nav: NavigationTarget) -> Cancelable<Option<String>> {
260 let result = match (nav.description(self), nav.docs(self)) {
261 (Some(desc), Some(docs)) => {
262 Some("```rust\n".to_string() + &*desc + "\n```\n\n" + &*docs)
263 }
264 (Some(desc), None) => Some("```rust\n".to_string() + &*desc + "\n```"),
265 (None, Some(docs)) => Some(docs),
266 _ => None,
267 };
268
269 Ok(result)
270 }
271 259
272 pub(crate) fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> { 260 pub(crate) fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> {
273 let syntax = self.source_file(file_id); 261 let syntax = self.source_file(file_id);
@@ -506,91 +494,3 @@ impl<'a> FnCallNode<'a> {
506 } 494 }
507 } 495 }
508} 496}
509
510impl NavigationTarget {
511 fn node(&self, db: &db::RootDatabase) -> Option<SyntaxNode> {
512 let source_file = db.source_file(self.file_id);
513 let source_file = source_file.syntax();
514 let node = source_file
515 .descendants()
516 .find(|node| node.kind() == self.kind && node.range() == self.range)?
517 .owned();
518 Some(node)
519 }
520
521 fn docs(&self, db: &db::RootDatabase) -> Option<String> {
522 let node = self.node(db)?;
523 let node = node.borrowed();
524 fn doc_comments<'a, N: ast::DocCommentsOwner<'a>>(node: N) -> Option<String> {
525 let comments = node.doc_comment_text();
526 if comments.is_empty() {
527 None
528 } else {
529 Some(comments)
530 }
531 }
532
533 visitor()
534 .visit(doc_comments::<ast::FnDef>)
535 .visit(doc_comments::<ast::StructDef>)
536 .visit(doc_comments::<ast::EnumDef>)
537 .visit(doc_comments::<ast::TraitDef>)
538 .visit(doc_comments::<ast::Module>)
539 .visit(doc_comments::<ast::TypeDef>)
540 .visit(doc_comments::<ast::ConstDef>)
541 .visit(doc_comments::<ast::StaticDef>)
542 .accept(node)?
543 }
544
545 /// Get a description of this node.
546 ///
547 /// e.g. `struct Name`, `enum Name`, `fn Name`
548 fn description(&self, db: &db::RootDatabase) -> Option<String> {
549 // TODO: After type inference is done, add type information to improve the output
550 let node = self.node(db)?;
551 let node = node.borrowed();
552 // TODO: Refactor to be have less repetition
553 visitor()
554 .visit(|node: ast::FnDef| {
555 let mut string = "fn ".to_string();
556 node.name()?.syntax().text().push_to(&mut string);
557 Some(string)
558 })
559 .visit(|node: ast::StructDef| {
560 let mut string = "struct ".to_string();
561 node.name()?.syntax().text().push_to(&mut string);
562 Some(string)
563 })
564 .visit(|node: ast::EnumDef| {
565 let mut string = "enum ".to_string();
566 node.name()?.syntax().text().push_to(&mut string);
567 Some(string)
568 })
569 .visit(|node: ast::TraitDef| {
570 let mut string = "trait ".to_string();
571 node.name()?.syntax().text().push_to(&mut string);
572 Some(string)
573 })
574 .visit(|node: ast::Module| {
575 let mut string = "mod ".to_string();
576 node.name()?.syntax().text().push_to(&mut string);
577 Some(string)
578 })
579 .visit(|node: ast::TypeDef| {
580 let mut string = "type ".to_string();
581 node.name()?.syntax().text().push_to(&mut string);
582 Some(string)
583 })
584 .visit(|node: ast::ConstDef| {
585 let mut string = "const ".to_string();
586 node.name()?.syntax().text().push_to(&mut string);
587 Some(string)
588 })
589 .visit(|node: ast::StaticDef| {
590 let mut string = "static ".to_string();
591 node.name()?.syntax().text().push_to(&mut string);
592 Some(string)
593 })
594 .accept(node)?
595 }
596}
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs
index 1904ff884..0e32a15f8 100644
--- a/crates/ra_analysis/src/lib.rs
+++ b/crates/ra_analysis/src/lib.rs
@@ -403,10 +403,6 @@ impl Analysis {
403 pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> { 403 pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> {
404 self.db.find_all_refs(position) 404 self.db.find_all_refs(position)
405 } 405 }
406 /// Returns documentation string for a given target.
407 pub fn doc_text_for(&self, nav: NavigationTarget) -> Cancelable<Option<String>> {
408 self.db.doc_text_for(nav)
409 }
410 /// Returns a short text descrbing element at position. 406 /// Returns a short text descrbing element at position.
411 pub fn hover(&self, position: FilePosition) -> Cancelable<Option<RangeInfo<String>>> { 407 pub fn hover(&self, position: FilePosition) -> Cancelable<Option<RangeInfo<String>>> {
412 hover::hover(&*self.db, position) 408 hover::hover(&*self.db, position)