aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/hover.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-07-19 10:56:47 +0100
committerAleksey Kladov <[email protected]>2019-07-19 11:16:25 +0100
commitf1abc7bdc63fedd5a699b4c495bb23f1b6d254f9 (patch)
tree9518c43f5ddeaa38426efddc17be19af5381f003 /crates/ra_ide_api/src/hover.rs
parent0343c4a815a0e82d5e55e76a01d21b0f7a00ff5b (diff)
migrate ra_ide_api to the new rowan
Diffstat (limited to 'crates/ra_ide_api/src/hover.rs')
-rw-r--r--crates/ra_ide_api/src/hover.rs51
1 files changed, 25 insertions, 26 deletions
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs
index 253d21f48..e503bf6a9 100644
--- a/crates/ra_ide_api/src/hover.rs
+++ b/crates/ra_ide_api/src/hover.rs
@@ -6,7 +6,7 @@ use ra_syntax::{
6 visit::{visitor, Visitor}, 6 visit::{visitor, Visitor},
7 }, 7 },
8 ast::{self, DocCommentsOwner}, 8 ast::{self, DocCommentsOwner},
9 AstNode, TreeArc, 9 AstNode,
10}; 10};
11 11
12use crate::{ 12use crate::{
@@ -104,7 +104,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
104 104
105 let mut no_fallback = false; 105 let mut no_fallback = false;
106 106
107 match classify_name_ref(db, &analyzer, name_ref) { 107 match classify_name_ref(db, &analyzer, &name_ref) {
108 Some(Method(it)) => res.extend(from_def_source(db, it)), 108 Some(Method(it)) => res.extend(from_def_source(db, it)),
109 Some(Macro(it)) => { 109 Some(Macro(it)) => {
110 let src = it.source(db); 110 let src = it.source(db);
@@ -163,7 +163,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
163 163
164 if res.is_empty() && !no_fallback { 164 if res.is_empty() && !no_fallback {
165 // Fallback index based approach: 165 // Fallback index based approach:
166 let symbols = crate::symbol_index::index_resolve(db, name_ref); 166 let symbols = crate::symbol_index::index_resolve(db, &name_ref);
167 for sym in symbols { 167 for sym in symbols {
168 let docs = docs_from_symbol(db, &sym); 168 let docs = docs_from_symbol(db, &sym);
169 let desc = description_from_symbol(db, &sym); 169 let desc = description_from_symbol(db, &sym);
@@ -177,34 +177,32 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
177 } else if let Some(name) = find_node_at_offset::<ast::Name>(file.syntax(), position.offset) { 177 } else if let Some(name) = find_node_at_offset::<ast::Name>(file.syntax(), position.offset) {
178 if let Some(parent) = name.syntax().parent() { 178 if let Some(parent) = name.syntax().parent() {
179 let text = visitor() 179 let text = visitor()
180 .visit(|node: &ast::StructDef| { 180 .visit(|node: ast::StructDef| {
181 hover_text(node.doc_comment_text(), node.short_label()) 181 hover_text(node.doc_comment_text(), node.short_label())
182 }) 182 })
183 .visit(|node: &ast::EnumDef| { 183 .visit(|node: ast::EnumDef| hover_text(node.doc_comment_text(), node.short_label()))
184 .visit(|node: ast::EnumVariant| {
184 hover_text(node.doc_comment_text(), node.short_label()) 185 hover_text(node.doc_comment_text(), node.short_label())
185 }) 186 })
186 .visit(|node: &ast::EnumVariant| { 187 .visit(|node: ast::FnDef| hover_text(node.doc_comment_text(), node.short_label()))
188 .visit(|node: ast::TypeAliasDef| {
187 hover_text(node.doc_comment_text(), node.short_label()) 189 hover_text(node.doc_comment_text(), node.short_label())
188 }) 190 })
189 .visit(|node: &ast::FnDef| hover_text(node.doc_comment_text(), node.short_label())) 191 .visit(|node: ast::ConstDef| {
190 .visit(|node: &ast::TypeAliasDef| {
191 hover_text(node.doc_comment_text(), node.short_label()) 192 hover_text(node.doc_comment_text(), node.short_label())
192 }) 193 })
193 .visit(|node: &ast::ConstDef| { 194 .visit(|node: ast::StaticDef| {
194 hover_text(node.doc_comment_text(), node.short_label()) 195 hover_text(node.doc_comment_text(), node.short_label())
195 }) 196 })
196 .visit(|node: &ast::StaticDef| { 197 .visit(|node: ast::TraitDef| {
197 hover_text(node.doc_comment_text(), node.short_label()) 198 hover_text(node.doc_comment_text(), node.short_label())
198 }) 199 })
199 .visit(|node: &ast::TraitDef| { 200 .visit(|node: ast::NamedFieldDef| {
200 hover_text(node.doc_comment_text(), node.short_label()) 201 hover_text(node.doc_comment_text(), node.short_label())
201 }) 202 })
202 .visit(|node: &ast::NamedFieldDef| { 203 .visit(|node: ast::Module| hover_text(node.doc_comment_text(), node.short_label()))
203 hover_text(node.doc_comment_text(), node.short_label()) 204 .visit(|node: ast::MacroCall| hover_text(node.doc_comment_text(), None))
204 }) 205 .accept(&parent);
205 .visit(|node: &ast::Module| hover_text(node.doc_comment_text(), node.short_label()))
206 .visit(|node: &ast::MacroCall| hover_text(node.doc_comment_text(), None))
207 .accept(parent);
208 206
209 if let Some(text) = text { 207 if let Some(text) = text {
210 res.extend(text); 208 res.extend(text);
@@ -217,8 +215,9 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
217 } 215 }
218 216
219 if range.is_none() { 217 if range.is_none() {
220 let node = ancestors_at_offset(file.syntax(), position.offset) 218 let node = ancestors_at_offset(file.syntax(), position.offset).find(|n| {
221 .find(|n| ast::Expr::cast(*n).is_some() || ast::Pat::cast(*n).is_some())?; 219 ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some()
220 })?;
222 let frange = FileRange { file_id: position.file_id, range: node.range() }; 221 let frange = FileRange { file_id: position.file_id, range: node.range() };
223 res.extend(type_of(db, frange).map(rust_code_markup)); 222 res.extend(type_of(db, frange).map(rust_code_markup));
224 range = Some(node.range()); 223 range = Some(node.range());
@@ -233,7 +232,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
233 232
234 fn from_def_source<A, D>(db: &RootDatabase, def: D) -> Option<String> 233 fn from_def_source<A, D>(db: &RootDatabase, def: D) -> Option<String>
235 where 234 where
236 D: HasSource<Ast = TreeArc<A>>, 235 D: HasSource<Ast = A>,
237 A: ast::DocCommentsOwner + ast::NameOwner + ShortLabel, 236 A: ast::DocCommentsOwner + ast::NameOwner + ShortLabel,
238 { 237 {
239 let src = def.source(db); 238 let src = def.source(db);
@@ -243,17 +242,17 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
243 242
244pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> { 243pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> {
245 let parse = db.parse(frange.file_id); 244 let parse = db.parse(frange.file_id);
246 let syntax = parse.tree().syntax(); 245 let leaf_node = find_covering_element(parse.tree().syntax(), frange.range);
247 let leaf_node = find_covering_element(syntax, frange.range);
248 // if we picked identifier, expand to pattern/expression 246 // if we picked identifier, expand to pattern/expression
249 let node = leaf_node 247 let node = leaf_node
250 .ancestors() 248 .ancestors()
251 .take_while(|it| it.range() == leaf_node.range()) 249 .take_while(|it| it.range() == leaf_node.range())
252 .find(|&it| ast::Expr::cast(it).is_some() || ast::Pat::cast(it).is_some())?; 250 .find(|it| ast::Expr::cast(it.clone()).is_some() || ast::Pat::cast(it.clone()).is_some())?;
253 let analyzer = hir::SourceAnalyzer::new(db, frange.file_id, node, None); 251 let analyzer = hir::SourceAnalyzer::new(db, frange.file_id, &node, None);
254 let ty = if let Some(ty) = ast::Expr::cast(node).and_then(|e| analyzer.type_of(db, e)) { 252 let ty = if let Some(ty) = ast::Expr::cast(node.clone()).and_then(|e| analyzer.type_of(db, &e))
253 {
255 ty 254 ty
256 } else if let Some(ty) = ast::Pat::cast(node).and_then(|p| analyzer.type_of_pat(db, p)) { 255 } else if let Some(ty) = ast::Pat::cast(node).and_then(|p| analyzer.type_of_pat(db, &p)) {
257 ty 256 ty
258 } else { 257 } else {
259 return None; 258 return None;