aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/imp.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_analysis/src/imp.rs')
-rw-r--r--crates/ra_analysis/src/imp.rs124
1 files changed, 105 insertions, 19 deletions
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index ff13247de..5f67c95f6 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, LocalEdit, Severity}; 9use ra_editor::{self, find_node_at_offset, LocalEdit, Severity};
10use ra_syntax::{ 10use ra_syntax::{
11 algo::find_covering_node, 11 algo::{find_covering_node, visit::{visitor, Visitor}},
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 SyntaxNodeRef, TextRange, TextUnit, 15 SyntaxNode, SyntaxNodeRef, TextRange, TextUnit,
16}; 16};
17 17
18use crate::{ 18use crate::{
@@ -116,12 +116,12 @@ impl db::RootDatabase {
116 }; 116 };
117 let decl = decl.borrowed(); 117 let decl = decl.borrowed();
118 let decl_name = decl.name().unwrap(); 118 let decl_name = decl.name().unwrap();
119 let symbol = FileSymbol { 119 Ok(vec![NavigationTarget {
120 file_id,
120 name: decl_name.text(), 121 name: decl_name.text(),
121 node_range: decl_name.syntax().range(), 122 range: decl_name.syntax().range(),
122 kind: MODULE, 123 kind: MODULE,
123 }; 124 }])
124 Ok(vec![NavigationTarget { file_id, symbol }])
125 } 125 }
126 /// Returns `Vec` for the same reason as `parent_module` 126 /// Returns `Vec` for the same reason as `parent_module`
127 pub(crate) fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { 127 pub(crate) fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> {
@@ -153,14 +153,12 @@ impl db::RootDatabase {
153 let scope = fn_descr.scopes(self); 153 let scope = fn_descr.scopes(self);
154 // First try to resolve the symbol locally 154 // First try to resolve the symbol locally
155 if let Some(entry) = scope.resolve_local_name(name_ref) { 155 if let Some(entry) = scope.resolve_local_name(name_ref) {
156 rr.add_resolution( 156 rr.resolves_to.push(NavigationTarget {
157 position.file_id, 157 file_id: position.file_id,
158 FileSymbol { 158 name: entry.name().to_string().into(),
159 name: entry.name().to_string().into(), 159 range: entry.ptr().range(),
160 node_range: entry.ptr().range(), 160 kind: NAME,
161 kind: NAME, 161 });
162 },
163 );
164 return Ok(Some(rr)); 162 return Ok(Some(rr));
165 }; 163 };
166 } 164 }
@@ -182,12 +180,13 @@ impl db::RootDatabase {
182 Some(name) => name.to_string().into(), 180 Some(name) => name.to_string().into(),
183 None => "".into(), 181 None => "".into(),
184 }; 182 };
185 let symbol = FileSymbol { 183 let symbol = NavigationTarget {
184 file_id,
186 name, 185 name,
187 node_range: TextRange::offset_len(0.into(), 0.into()), 186 range: TextRange::offset_len(0.into(), 0.into()),
188 kind: MODULE, 187 kind: MODULE,
189 }; 188 };
190 rr.add_resolution(file_id, symbol); 189 rr.resolves_to.push(symbol);
191 return Ok(Some(rr)); 190 return Ok(Some(rr));
192 } 191 }
193 } 192 }
@@ -253,8 +252,7 @@ impl db::RootDatabase {
253 } 252 }
254 } 253 }
255 pub(crate) fn doc_text_for(&self, nav: NavigationTarget) -> Cancelable<Option<String>> { 254 pub(crate) fn doc_text_for(&self, nav: NavigationTarget) -> Cancelable<Option<String>> {
256 let file = self.source_file(nav.file_id); 255 let result = match (nav.description(self), nav.docs(self)) {
257 let result = match (nav.symbol.description(&file), nav.symbol.docs(&file)) {
258 (Some(desc), Some(docs)) => { 256 (Some(desc), Some(docs)) => {
259 Some("```rust\n".to_string() + &*desc + "\n```\n\n" + &*docs) 257 Some("```rust\n".to_string() + &*desc + "\n```\n\n" + &*docs)
260 } 258 }
@@ -511,3 +509,91 @@ impl<'a> FnCallNode<'a> {
511 } 509 }
512 } 510 }
513} 511}
512
513impl NavigationTarget {
514 fn node(&self, db: &db::RootDatabase) -> Option<SyntaxNode> {
515 let source_file = db.source_file(self.file_id);
516 let source_file = source_file.syntax();
517 let node = source_file
518 .descendants()
519 .find(|node| node.kind() == self.kind && node.range() == self.range)?
520 .owned();
521 Some(node)
522 }
523
524 fn docs(&self, db: &db::RootDatabase) -> Option<String> {
525 let node = self.node(db)?;
526 let node = node.borrowed();
527 fn doc_comments<'a, N: ast::DocCommentsOwner<'a>>(node: N) -> Option<String> {
528 let comments = node.doc_comment_text();
529 if comments.is_empty() {
530 None
531 } else {
532 Some(comments)
533 }
534 }
535
536 visitor()
537 .visit(doc_comments::<ast::FnDef>)
538 .visit(doc_comments::<ast::StructDef>)
539 .visit(doc_comments::<ast::EnumDef>)
540 .visit(doc_comments::<ast::TraitDef>)
541 .visit(doc_comments::<ast::Module>)
542 .visit(doc_comments::<ast::TypeDef>)
543 .visit(doc_comments::<ast::ConstDef>)
544 .visit(doc_comments::<ast::StaticDef>)
545 .accept(node)?
546 }
547
548 /// Get a description of this node.
549 ///
550 /// e.g. `struct Name`, `enum Name`, `fn Name`
551 fn description(&self, db: &db::RootDatabase) -> Option<String> {
552 // TODO: After type inference is done, add type information to improve the output
553 let node = self.node(db)?;
554 let node = node.borrowed();
555 // TODO: Refactor to be have less repetition
556 visitor()
557 .visit(|node: ast::FnDef| {
558 let mut string = "fn ".to_string();
559 node.name()?.syntax().text().push_to(&mut string);
560 Some(string)
561 })
562 .visit(|node: ast::StructDef| {
563 let mut string = "struct ".to_string();
564 node.name()?.syntax().text().push_to(&mut string);
565 Some(string)
566 })
567 .visit(|node: ast::EnumDef| {
568 let mut string = "enum ".to_string();
569 node.name()?.syntax().text().push_to(&mut string);
570 Some(string)
571 })
572 .visit(|node: ast::TraitDef| {
573 let mut string = "trait ".to_string();
574 node.name()?.syntax().text().push_to(&mut string);
575 Some(string)
576 })
577 .visit(|node: ast::Module| {
578 let mut string = "mod ".to_string();
579 node.name()?.syntax().text().push_to(&mut string);
580 Some(string)
581 })
582 .visit(|node: ast::TypeDef| {
583 let mut string = "type ".to_string();
584 node.name()?.syntax().text().push_to(&mut string);
585 Some(string)
586 })
587 .visit(|node: ast::ConstDef| {
588 let mut string = "const ".to_string();
589 node.name()?.syntax().text().push_to(&mut string);
590 Some(string)
591 })
592 .visit(|node: ast::StaticDef| {
593 let mut string = "static ".to_string();
594 node.name()?.syntax().text().push_to(&mut string);
595 Some(string)
596 })
597 .accept(node)?
598 }
599}