diff options
-rw-r--r-- | crates/ra_ide_api/src/display/navigation_target.rs | 140 | ||||
-rw-r--r-- | crates/ra_ide_api/src/goto_definition.rs | 46 |
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}; | |||
2 | use ra_syntax::{ | 2 | use 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 | }; |
8 | use hir::{ModuleSource, FieldSource, ImplItem}; | 8 | use 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 | ||
317 | fn docs_inner(node: &SyntaxNode) -> Option<String> { | 388 | fn 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` |
340 | fn description_inner(node: &SyntaxNode) -> Option<String> { | 414 | fn 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 @@ | |||
1 | use ra_db::{FileId, SourceDatabase}; | 1 | use ra_db::{FileId, SourceDatabase}; |
2 | use ra_syntax::{ | 2 | use 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 | ||
115 | fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget> { | 115 | fn 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 | ||