aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_ide_api/src/display/navigation_target.rs140
-rw-r--r--crates/ra_ide_api/src/goto_definition.rs46
2 files changed, 141 insertions, 45 deletions
diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs
index f8a7bd3ad..b2a925e2a 100644
--- a/crates/ra_ide_api/src/display/navigation_target.rs
+++ b/crates/ra_ide_api/src/display/navigation_target.rs
@@ -2,7 +2,7 @@ use ra_db::{FileId, SourceDatabase};
2use ra_syntax::{ 2use ra_syntax::{
3 SyntaxNode, AstNode, SmolStr, TextRange, AstPtr, 3 SyntaxNode, AstNode, SmolStr, TextRange, AstPtr,
4 SyntaxKind::{self, NAME}, 4 SyntaxKind::{self, NAME},
5 ast::{self, NameOwner, VisibilityOwner, TypeAscriptionOwner}, 5 ast::{self, NameOwner, VisibilityOwner, TypeAscriptionOwner, DocCommentsOwner},
6 algo::visit::{visitor, Visitor}, 6 algo::visit::{visitor, Visitor},
7}; 7};
8use hir::{ModuleSource, FieldSource, ImplItem}; 8use hir::{ModuleSource, FieldSource, ImplItem};
@@ -63,7 +63,7 @@ impl NavigationTarget {
63 } 63 }
64 64
65 pub(crate) fn from_bind_pat(file_id: FileId, pat: &ast::BindPat) -> NavigationTarget { 65 pub(crate) fn from_bind_pat(file_id: FileId, pat: &ast::BindPat) -> NavigationTarget {
66 NavigationTarget::from_named(file_id, pat) 66 NavigationTarget::from_named(file_id, pat, None)
67 } 67 }
68 68
69 pub(crate) fn from_symbol(db: &RootDatabase, symbol: FileSymbol) -> NavigationTarget { 69 pub(crate) fn from_symbol(db: &RootDatabase, symbol: FileSymbol) -> NavigationTarget {
@@ -78,7 +78,7 @@ impl NavigationTarget {
78 focus_range: symbol.name_range, 78 focus_range: symbol.name_range,
79 container_name: symbol.container_name.clone(), 79 container_name: symbol.container_name.clone(),
80 description: description_inner(&node), 80 description: description_inner(&node),
81 docs: docs_inner(&node), 81 docs: docs_from_symbol(db, &symbol),
82 } 82 }
83 } 83 }
84 84
@@ -102,7 +102,7 @@ impl NavigationTarget {
102 kind: NAME, 102 kind: NAME,
103 container_name: None, 103 container_name: None,
104 description: description_inner(&node), 104 description: description_inner(&node),
105 docs: docs_inner(&node), 105 docs: None, //< No documentation for Pattern
106 } 106 }
107 } 107 }
108 108
@@ -113,7 +113,8 @@ impl NavigationTarget {
113 ) -> NavigationTarget { 113 ) -> NavigationTarget {
114 let (name, full_range) = ("self".into(), par.syntax_node_ptr().range()); 114 let (name, full_range) = ("self".into(), par.syntax_node_ptr().range());
115 let file = db.parse(file_id).tree; 115 let file = db.parse(file_id).tree;
116 let node = par.to_node(file.syntax()).syntax().to_owned(); 116 let ast = par.to_node(file.syntax());
117 let node = ast.syntax().to_owned();
117 118
118 NavigationTarget { 119 NavigationTarget {
119 file_id, 120 file_id,
@@ -123,7 +124,7 @@ impl NavigationTarget {
123 kind: NAME, 124 kind: NAME,
124 container_name: None, 125 container_name: None,
125 description: description_inner(&node), 126 description: description_inner(&node),
126 docs: docs_inner(&node), 127 docs: None, //< No document node for SelfParam
127 } 128 }
128 } 129 }
129 130
@@ -133,11 +134,15 @@ impl NavigationTarget {
133 let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); 134 let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default();
134 match source { 135 match source {
135 ModuleSource::SourceFile(node) => { 136 ModuleSource::SourceFile(node) => {
136 NavigationTarget::from_syntax(file_id, name, None, node.syntax()) 137 NavigationTarget::from_syntax(file_id, name, None, node.syntax(), None)
137 }
138 ModuleSource::Module(node) => {
139 NavigationTarget::from_syntax(file_id, name, None, node.syntax())
140 } 138 }
139 ModuleSource::Module(node) => NavigationTarget::from_syntax(
140 file_id,
141 name,
142 None,
143 node.syntax(),
144 node.doc_comment_text(),
145 ),
141 } 146 }
142 } 147 }
143 148
@@ -145,23 +150,31 @@ impl NavigationTarget {
145 let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); 150 let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default();
146 if let Some((file_id, source)) = module.declaration_source(db) { 151 if let Some((file_id, source)) = module.declaration_source(db) {
147 let file_id = file_id.as_original_file(); 152 let file_id = file_id.as_original_file();
148 return NavigationTarget::from_syntax(file_id, name, None, source.syntax()); 153 return NavigationTarget::from_syntax(
154 file_id,
155 name,
156 None,
157 source.syntax(),
158 source.doc_comment_text(),
159 );
149 } 160 }
150 NavigationTarget::from_module(db, module) 161 NavigationTarget::from_module(db, module)
151 } 162 }
152 163
153 pub(crate) fn from_function(db: &RootDatabase, func: hir::Function) -> NavigationTarget { 164 pub(crate) fn from_function(db: &RootDatabase, func: hir::Function) -> NavigationTarget {
154 let (file_id, fn_def) = func.source(db); 165 let (file_id, fn_def) = func.source(db);
155 NavigationTarget::from_named(file_id.original_file(db), &*fn_def) 166 NavigationTarget::from_named(file_id.original_file(db), &*fn_def, fn_def.doc_comment_text())
156 } 167 }
157 168
158 pub(crate) fn from_field(db: &RootDatabase, field: hir::StructField) -> NavigationTarget { 169 pub(crate) fn from_field(db: &RootDatabase, field: hir::StructField) -> NavigationTarget {
159 let (file_id, field) = field.source(db); 170 let (file_id, field) = field.source(db);
160 let file_id = file_id.original_file(db); 171 let file_id = file_id.original_file(db);
161 match field { 172 match field {
162 FieldSource::Named(it) => NavigationTarget::from_named(file_id, &*it), 173 FieldSource::Named(it) => {
174 NavigationTarget::from_named(file_id, &*it, it.doc_comment_text())
175 }
163 FieldSource::Pos(it) => { 176 FieldSource::Pos(it) => {
164 NavigationTarget::from_syntax(file_id, "".into(), None, it.syntax()) 177 NavigationTarget::from_syntax(file_id, "".into(), None, it.syntax(), None)
165 } 178 }
166 } 179 }
167 } 180 }
@@ -170,15 +183,27 @@ impl NavigationTarget {
170 match adt_def { 183 match adt_def {
171 hir::AdtDef::Struct(s) => { 184 hir::AdtDef::Struct(s) => {
172 let (file_id, node) = s.source(db); 185 let (file_id, node) = s.source(db);
173 NavigationTarget::from_named(file_id.original_file(db), &*node) 186 NavigationTarget::from_named(
187 file_id.original_file(db),
188 &*node,
189 node.doc_comment_text(),
190 )
174 } 191 }
175 hir::AdtDef::Union(s) => { 192 hir::AdtDef::Union(s) => {
176 let (file_id, node) = s.source(db); 193 let (file_id, node) = s.source(db);
177 NavigationTarget::from_named(file_id.original_file(db), &*node) 194 NavigationTarget::from_named(
195 file_id.original_file(db),
196 &*node,
197 node.doc_comment_text(),
198 )
178 } 199 }
179 hir::AdtDef::Enum(s) => { 200 hir::AdtDef::Enum(s) => {
180 let (file_id, node) = s.source(db); 201 let (file_id, node) = s.source(db);
181 NavigationTarget::from_named(file_id.original_file(db), &*node) 202 NavigationTarget::from_named(
203 file_id.original_file(db),
204 &*node,
205 node.doc_comment_text(),
206 )
182 } 207 }
183 } 208 }
184 } 209 }
@@ -192,35 +217,67 @@ impl NavigationTarget {
192 hir::ModuleDef::Function(func) => NavigationTarget::from_function(db, func), 217 hir::ModuleDef::Function(func) => NavigationTarget::from_function(db, func),
193 hir::ModuleDef::Struct(s) => { 218 hir::ModuleDef::Struct(s) => {
194 let (file_id, node) = s.source(db); 219 let (file_id, node) = s.source(db);
195 NavigationTarget::from_named(file_id.original_file(db), &*node) 220 NavigationTarget::from_named(
221 file_id.original_file(db),
222 &*node,
223 node.doc_comment_text(),
224 )
196 } 225 }
197 hir::ModuleDef::Union(s) => { 226 hir::ModuleDef::Union(s) => {
198 let (file_id, node) = s.source(db); 227 let (file_id, node) = s.source(db);
199 NavigationTarget::from_named(file_id.original_file(db), &*node) 228 NavigationTarget::from_named(
229 file_id.original_file(db),
230 &*node,
231 node.doc_comment_text(),
232 )
200 } 233 }
201 hir::ModuleDef::Const(s) => { 234 hir::ModuleDef::Const(s) => {
202 let (file_id, node) = s.source(db); 235 let (file_id, node) = s.source(db);
203 NavigationTarget::from_named(file_id.original_file(db), &*node) 236 NavigationTarget::from_named(
237 file_id.original_file(db),
238 &*node,
239 node.doc_comment_text(),
240 )
204 } 241 }
205 hir::ModuleDef::Static(s) => { 242 hir::ModuleDef::Static(s) => {
206 let (file_id, node) = s.source(db); 243 let (file_id, node) = s.source(db);
207 NavigationTarget::from_named(file_id.original_file(db), &*node) 244 NavigationTarget::from_named(
245 file_id.original_file(db),
246 &*node,
247 node.doc_comment_text(),
248 )
208 } 249 }
209 hir::ModuleDef::Enum(e) => { 250 hir::ModuleDef::Enum(e) => {
210 let (file_id, node) = e.source(db); 251 let (file_id, node) = e.source(db);
211 NavigationTarget::from_named(file_id.original_file(db), &*node) 252 NavigationTarget::from_named(
253 file_id.original_file(db),
254 &*node,
255 node.doc_comment_text(),
256 )
212 } 257 }
213 hir::ModuleDef::EnumVariant(var) => { 258 hir::ModuleDef::EnumVariant(var) => {
214 let (file_id, node) = var.source(db); 259 let (file_id, node) = var.source(db);
215 NavigationTarget::from_named(file_id.original_file(db), &*node) 260 NavigationTarget::from_named(
261 file_id.original_file(db),
262 &*node,
263 node.doc_comment_text(),
264 )
216 } 265 }
217 hir::ModuleDef::Trait(e) => { 266 hir::ModuleDef::Trait(e) => {
218 let (file_id, node) = e.source(db); 267 let (file_id, node) = e.source(db);
219 NavigationTarget::from_named(file_id.original_file(db), &*node) 268 NavigationTarget::from_named(
269 file_id.original_file(db),
270 &*node,
271 node.doc_comment_text(),
272 )
220 } 273 }
221 hir::ModuleDef::TypeAlias(e) => { 274 hir::ModuleDef::TypeAlias(e) => {
222 let (file_id, node) = e.source(db); 275 let (file_id, node) = e.source(db);
223 NavigationTarget::from_named(file_id.original_file(db), &*node) 276 NavigationTarget::from_named(
277 file_id.original_file(db),
278 &*node,
279 node.doc_comment_text(),
280 )
224 } 281 }
225 hir::ModuleDef::BuiltinType(..) => { 282 hir::ModuleDef::BuiltinType(..) => {
226 return None; 283 return None;
@@ -239,6 +296,7 @@ impl NavigationTarget {
239 "impl".into(), 296 "impl".into(),
240 None, 297 None,
241 node.syntax(), 298 node.syntax(),
299 None,
242 ) 300 )
243 } 301 }
244 302
@@ -247,11 +305,19 @@ impl NavigationTarget {
247 ImplItem::Method(f) => NavigationTarget::from_function(db, f), 305 ImplItem::Method(f) => NavigationTarget::from_function(db, f),
248 ImplItem::Const(c) => { 306 ImplItem::Const(c) => {
249 let (file_id, node) = c.source(db); 307 let (file_id, node) = c.source(db);
250 NavigationTarget::from_named(file_id.original_file(db), &*node) 308 NavigationTarget::from_named(
309 file_id.original_file(db),
310 &*node,
311 node.doc_comment_text(),
312 )
251 } 313 }
252 ImplItem::TypeAlias(a) => { 314 ImplItem::TypeAlias(a) => {
253 let (file_id, node) = a.source(db); 315 let (file_id, node) = a.source(db);
254 NavigationTarget::from_named(file_id.original_file(db), &*node) 316 NavigationTarget::from_named(
317 file_id.original_file(db),
318 &*node,
319 node.doc_comment_text(),
320 )
255 } 321 }
256 } 322 }
257 } 323 }
@@ -259,7 +325,7 @@ impl NavigationTarget {
259 pub(crate) fn from_macro_def(db: &RootDatabase, macro_call: hir::MacroDef) -> NavigationTarget { 325 pub(crate) fn from_macro_def(db: &RootDatabase, macro_call: hir::MacroDef) -> NavigationTarget {
260 let (file_id, node) = macro_call.source(db); 326 let (file_id, node) = macro_call.source(db);
261 log::debug!("nav target {}", node.syntax().debug_dump()); 327 log::debug!("nav target {}", node.syntax().debug_dump());
262 NavigationTarget::from_named(file_id.original_file(db), &*node) 328 NavigationTarget::from_named(file_id.original_file(db), &*node, node.doc_comment_text())
263 } 329 }
264 330
265 #[cfg(test)] 331 #[cfg(test)]
@@ -287,11 +353,15 @@ impl NavigationTarget {
287 } 353 }
288 354
289 /// Allows `NavigationTarget` to be created from a `NameOwner` 355 /// Allows `NavigationTarget` to be created from a `NameOwner`
290 pub(crate) fn from_named(file_id: FileId, node: &impl ast::NameOwner) -> NavigationTarget { 356 pub(crate) fn from_named(
357 file_id: FileId,
358 node: &impl ast::NameOwner,
359 docs: Option<String>,
360 ) -> NavigationTarget {
291 //FIXME: use `_` instead of empty string 361 //FIXME: use `_` instead of empty string
292 let name = node.name().map(|it| it.text().clone()).unwrap_or_default(); 362 let name = node.name().map(|it| it.text().clone()).unwrap_or_default();
293 let focus_range = node.name().map(|it| it.syntax().range()); 363 let focus_range = node.name().map(|it| it.syntax().range());
294 NavigationTarget::from_syntax(file_id, name, focus_range, node.syntax()) 364 NavigationTarget::from_syntax(file_id, name, focus_range, node.syntax(), docs)
295 } 365 }
296 366
297 fn from_syntax( 367 fn from_syntax(
@@ -299,6 +369,7 @@ impl NavigationTarget {
299 name: SmolStr, 369 name: SmolStr,
300 focus_range: Option<TextRange>, 370 focus_range: Option<TextRange>,
301 node: &SyntaxNode, 371 node: &SyntaxNode,
372 docs: Option<String>,
302 ) -> NavigationTarget { 373 ) -> NavigationTarget {
303 NavigationTarget { 374 NavigationTarget {
304 file_id, 375 file_id,
@@ -309,12 +380,15 @@ impl NavigationTarget {
309 // ptr: Some(LocalSyntaxPtr::new(node)), 380 // ptr: Some(LocalSyntaxPtr::new(node)),
310 container_name: None, 381 container_name: None,
311 description: description_inner(node), 382 description: description_inner(node),
312 docs: docs_inner(node), 383 docs,
313 } 384 }
314 } 385 }
315} 386}
316 387
317fn docs_inner(node: &SyntaxNode) -> Option<String> { 388fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> {
389 let file = db.parse(symbol.file_id).tree;
390 let node = symbol.ptr.to_node(file.syntax()).to_owned();
391
318 fn doc_comments<N: ast::DocCommentsOwner>(node: &N) -> Option<String> { 392 fn doc_comments<N: ast::DocCommentsOwner>(node: &N) -> Option<String> {
319 node.doc_comment_text() 393 node.doc_comment_text()
320 } 394 }
@@ -334,7 +408,7 @@ fn docs_inner(node: &SyntaxNode) -> Option<String> {
334 .accept(&node)? 408 .accept(&node)?
335} 409}
336 410
337/// Get a description of this node. 411/// Get a description of a node.
338/// 412///
339/// e.g. `struct Name`, `enum Name`, `fn Name` 413/// e.g. `struct Name`, `enum Name`, `fn Name`
340fn description_inner(node: &SyntaxNode) -> Option<String> { 414fn description_inner(node: &SyntaxNode) -> Option<String> {
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs
index 31b6679ae..fbd881bfe 100644
--- a/crates/ra_ide_api/src/goto_definition.rs
+++ b/crates/ra_ide_api/src/goto_definition.rs
@@ -1,6 +1,6 @@
1use ra_db::{FileId, SourceDatabase}; 1use ra_db::{FileId, SourceDatabase};
2use ra_syntax::{ 2use ra_syntax::{
3 AstNode, ast, 3 AstNode, ast::{self, DocCommentsOwner},
4 algo::{ 4 algo::{
5 find_node_at_offset, 5 find_node_at_offset,
6 visit::{visitor, Visitor}, 6 visit::{visitor, Visitor},
@@ -114,17 +114,39 @@ pub(crate) fn name_definition(
114 114
115fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget> { 115fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget> {
116 visitor() 116 visitor()
117 .visit(|node: &ast::StructDef| NavigationTarget::from_named(file_id, node)) 117 .visit(|node: &ast::StructDef| {
118 .visit(|node: &ast::EnumDef| NavigationTarget::from_named(file_id, node)) 118 NavigationTarget::from_named(file_id, node, node.doc_comment_text())
119 .visit(|node: &ast::EnumVariant| NavigationTarget::from_named(file_id, node)) 119 })
120 .visit(|node: &ast::FnDef| NavigationTarget::from_named(file_id, node)) 120 .visit(|node: &ast::EnumDef| {
121 .visit(|node: &ast::TypeAliasDef| NavigationTarget::from_named(file_id, node)) 121 NavigationTarget::from_named(file_id, node, node.doc_comment_text())
122 .visit(|node: &ast::ConstDef| NavigationTarget::from_named(file_id, node)) 122 })
123 .visit(|node: &ast::StaticDef| NavigationTarget::from_named(file_id, node)) 123 .visit(|node: &ast::EnumVariant| {
124 .visit(|node: &ast::TraitDef| NavigationTarget::from_named(file_id, node)) 124 NavigationTarget::from_named(file_id, node, node.doc_comment_text())
125 .visit(|node: &ast::NamedFieldDef| NavigationTarget::from_named(file_id, node)) 125 })
126 .visit(|node: &ast::Module| NavigationTarget::from_named(file_id, node)) 126 .visit(|node: &ast::FnDef| {
127 .visit(|node: &ast::MacroCall| NavigationTarget::from_named(file_id, node)) 127 NavigationTarget::from_named(file_id, node, node.doc_comment_text())
128 })
129 .visit(|node: &ast::TypeAliasDef| {
130 NavigationTarget::from_named(file_id, node, node.doc_comment_text())
131 })
132 .visit(|node: &ast::ConstDef| {
133 NavigationTarget::from_named(file_id, node, node.doc_comment_text())
134 })
135 .visit(|node: &ast::StaticDef| {
136 NavigationTarget::from_named(file_id, node, node.doc_comment_text())
137 })
138 .visit(|node: &ast::TraitDef| {
139 NavigationTarget::from_named(file_id, node, node.doc_comment_text())
140 })
141 .visit(|node: &ast::NamedFieldDef| {
142 NavigationTarget::from_named(file_id, node, node.doc_comment_text())
143 })
144 .visit(|node: &ast::Module| {
145 NavigationTarget::from_named(file_id, node, node.doc_comment_text())
146 })
147 .visit(|node: &ast::MacroCall| {
148 NavigationTarget::from_named(file_id, node, node.doc_comment_text())
149 })
128 .accept(node) 150 .accept(node)
129} 151}
130 152