diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_ide_api/src/hover.rs | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index 364bf9f74..729f435d3 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use ra_db::SourceDatabase; | 1 | use ra_db::SourceDatabase; |
2 | use ra_syntax::{ | 2 | use ra_syntax::{ |
3 | AstNode, SyntaxNode, TreeArc, ast, | 3 | AstNode, SyntaxNode, TreeArc, ast::{self, NameOwner, VisibilityOwner, TypeParamsOwner}, |
4 | algo::{find_covering_node, find_node_at_offset, find_leaf_at_offset, visit::{visitor, Visitor}}, | 4 | algo::{find_covering_node, find_node_at_offset, find_leaf_at_offset, visit::{visitor, Visitor}}, |
5 | }; | 5 | }; |
6 | 6 | ||
@@ -118,9 +118,49 @@ impl NavigationTarget { | |||
118 | // TODO: After type inference is done, add type information to improve the output | 118 | // TODO: After type inference is done, add type information to improve the output |
119 | let node = self.node(db)?; | 119 | let node = self.node(db)?; |
120 | 120 | ||
121 | // FIXME: This is copied from `structure.rs` and should probably | ||
122 | // be moved somewhere common | ||
123 | fn collapse_ws(node: &SyntaxNode, output: &mut String) { | ||
124 | let mut can_insert_ws = false; | ||
125 | for line in node.text().chunks().flat_map(|chunk| chunk.lines()) { | ||
126 | let line = line.trim(); | ||
127 | if line.is_empty() { | ||
128 | if can_insert_ws { | ||
129 | output.push_str(" "); | ||
130 | can_insert_ws = false; | ||
131 | } | ||
132 | } else { | ||
133 | output.push_str(line); | ||
134 | can_insert_ws = true; | ||
135 | } | ||
136 | } | ||
137 | } | ||
138 | |||
139 | fn visit_fn(node: &ast::FnDef) -> Option<String> { | ||
140 | let mut detail = | ||
141 | node.visibility().map(|v| format!("{} ", v.syntax().text())).unwrap_or_default(); | ||
142 | |||
143 | detail.push_str("fn "); | ||
144 | |||
145 | node.name()?.syntax().text().push_to(&mut detail); | ||
146 | |||
147 | if let Some(type_param_list) = node.type_param_list() { | ||
148 | collapse_ws(type_param_list.syntax(), &mut detail); | ||
149 | } | ||
150 | if let Some(param_list) = node.param_list() { | ||
151 | collapse_ws(param_list.syntax(), &mut detail); | ||
152 | } | ||
153 | if let Some(ret_type) = node.ret_type() { | ||
154 | detail.push_str(" "); | ||
155 | collapse_ws(ret_type.syntax(), &mut detail); | ||
156 | } | ||
157 | |||
158 | Some(detail) | ||
159 | } | ||
160 | |||
121 | fn visit_node<T>(node: &T, label: &str) -> Option<String> | 161 | fn visit_node<T>(node: &T, label: &str) -> Option<String> |
122 | where | 162 | where |
123 | T: ast::NameOwner + ast::VisibilityOwner, | 163 | T: NameOwner + VisibilityOwner, |
124 | { | 164 | { |
125 | let mut string = | 165 | let mut string = |
126 | node.visibility().map(|v| format!("{} ", v.syntax().text())).unwrap_or_default(); | 166 | node.visibility().map(|v| format!("{} ", v.syntax().text())).unwrap_or_default(); |
@@ -130,7 +170,7 @@ impl NavigationTarget { | |||
130 | } | 170 | } |
131 | 171 | ||
132 | visitor() | 172 | visitor() |
133 | .visit(|node: &ast::FnDef| visit_node(node, "fn ")) | 173 | .visit(visit_fn) |
134 | .visit(|node: &ast::StructDef| visit_node(node, "struct ")) | 174 | .visit(|node: &ast::StructDef| visit_node(node, "struct ")) |
135 | .visit(|node: &ast::EnumDef| visit_node(node, "enum ")) | 175 | .visit(|node: &ast::EnumDef| visit_node(node, "enum ")) |
136 | .visit(|node: &ast::TraitDef| visit_node(node, "trait ")) | 176 | .visit(|node: &ast::TraitDef| visit_node(node, "trait ")) |