aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/syntax_tree.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/syntax_tree.rs')
-rw-r--r--crates/ra_ide_api/src/syntax_tree.rs33
1 files changed, 19 insertions, 14 deletions
diff --git a/crates/ra_ide_api/src/syntax_tree.rs b/crates/ra_ide_api/src/syntax_tree.rs
index 276f8a8c8..a4e4c3dbe 100644
--- a/crates/ra_ide_api/src/syntax_tree.rs
+++ b/crates/ra_ide_api/src/syntax_tree.rs
@@ -1,8 +1,9 @@
1use ra_db::SourceDatabase; 1use ra_db::SourceDatabase;
2use crate::db::RootDatabase; 2use crate::db::RootDatabase;
3use ra_syntax::{ 3use ra_syntax::{
4 SourceFile, SyntaxNode, TextRange, AstNode, 4 SourceFile, TextRange, AstNode, SyntaxToken, SyntaxElement,
5 algo::{self, visit::{visitor, Visitor}}, ast::{self, AstToken} 5 algo,
6 SyntaxKind::{STRING, RAW_STRING},
6}; 7};
7 8
8pub use ra_db::FileId; 9pub use ra_db::FileId;
@@ -14,11 +15,15 @@ pub(crate) fn syntax_tree(
14) -> String { 15) -> String {
15 if let Some(text_range) = text_range { 16 if let Some(text_range) = text_range {
16 let file = db.parse(file_id); 17 let file = db.parse(file_id);
17 let node = algo::find_covering_node(file.syntax(), text_range); 18 let node = match algo::find_covering_element(file.syntax(), text_range) {
18 19 SyntaxElement::Node(node) => node,
19 if let Some(tree) = syntax_tree_for_string(node, text_range) { 20 SyntaxElement::Token(token) => {
20 return tree; 21 if let Some(tree) = syntax_tree_for_string(token, text_range) {
21 } 22 return tree;
23 }
24 token.parent()
25 }
26 };
22 27
23 node.debug_dump() 28 node.debug_dump()
24 } else { 29 } else {
@@ -28,19 +33,19 @@ pub(crate) fn syntax_tree(
28 33
29/// Attempts parsing the selected contents of a string literal 34/// Attempts parsing the selected contents of a string literal
30/// as rust syntax and returns its syntax tree 35/// as rust syntax and returns its syntax tree
31fn syntax_tree_for_string(node: &SyntaxNode, text_range: TextRange) -> Option<String> { 36fn syntax_tree_for_string(token: SyntaxToken, text_range: TextRange) -> Option<String> {
32 // When the range is inside a string 37 // When the range is inside a string
33 // we'll attempt parsing it as rust syntax 38 // we'll attempt parsing it as rust syntax
34 // to provide the syntax tree of the contents of the string 39 // to provide the syntax tree of the contents of the string
35 visitor() 40 match token.kind() {
36 .visit(|node: &ast::String| syntax_tree_for_token(node, text_range)) 41 STRING | RAW_STRING => syntax_tree_for_token(token, text_range),
37 .visit(|node: &ast::RawString| syntax_tree_for_token(node, text_range)) 42 _ => None,
38 .accept(node)? 43 }
39} 44}
40 45
41fn syntax_tree_for_token<T: AstToken>(node: &T, text_range: TextRange) -> Option<String> { 46fn syntax_tree_for_token(node: SyntaxToken, text_range: TextRange) -> Option<String> {
42 // Range of the full node 47 // Range of the full node
43 let node_range = node.syntax().range(); 48 let node_range = node.range();
44 let text = node.text().to_string(); 49 let text = node.text().to_string();
45 50
46 // We start at some point inside the node 51 // We start at some point inside the node