diff options
Diffstat (limited to 'crates/ra_ide_api/src/display')
-rw-r--r-- | crates/ra_ide_api/src/display/navigation_target.rs | 99 |
1 files changed, 44 insertions, 55 deletions
diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs index f7ad08515..b30ef8e05 100644 --- a/crates/ra_ide_api/src/display/navigation_target.rs +++ b/crates/ra_ide_api/src/display/navigation_target.rs | |||
@@ -1,16 +1,17 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::{AssocItem, Either, FieldSource, HasSource, ModuleSource}; | 3 | use hir::{AssocItem, Either, FieldSource, HasSource, ModuleSource, Source}; |
4 | use ra_db::{FileId, SourceDatabase}; | 4 | use ra_db::{FileId, SourceDatabase}; |
5 | use ra_syntax::{ | 5 | use ra_syntax::{ |
6 | ast::{self, DocCommentsOwner, NameOwner}, | 6 | ast::{self, DocCommentsOwner, NameOwner}, |
7 | match_ast, AstNode, SmolStr, | 7 | match_ast, AstNode, SmolStr, |
8 | SyntaxKind::{self, BIND_PAT}, | 8 | SyntaxKind::{self, BIND_PAT}, |
9 | SyntaxNode, TextRange, | 9 | TextRange, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | use crate::{db::RootDatabase, expand::original_range, FileSymbol}; | ||
13 | |||
12 | use super::short_label::ShortLabel; | 14 | use super::short_label::ShortLabel; |
13 | use crate::{db::RootDatabase, FileSymbol}; | ||
14 | 15 | ||
15 | /// `NavigationTarget` represents and element in the editor's UI which you can | 16 | /// `NavigationTarget` represents and element in the editor's UI which you can |
16 | /// click on to navigate to a particular piece of code. | 17 | /// click on to navigate to a particular piece of code. |
@@ -79,13 +80,13 @@ impl NavigationTarget { | |||
79 | pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget { | 80 | pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget { |
80 | let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); | 81 | let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); |
81 | if let Some(src) = module.declaration_source(db) { | 82 | if let Some(src) = module.declaration_source(db) { |
82 | let (file_id, text_range) = find_range_from_node(db, src.file_id, src.ast.syntax()); | 83 | let frange = original_range(db, src.as_ref().map(|it| it.syntax())); |
83 | return NavigationTarget::from_syntax( | 84 | return NavigationTarget::from_syntax( |
84 | file_id, | 85 | frange.file_id, |
85 | name, | 86 | name, |
86 | None, | 87 | None, |
87 | text_range, | 88 | frange.range, |
88 | src.ast.syntax(), | 89 | src.ast.syntax().kind(), |
89 | src.ast.doc_comment_text(), | 90 | src.ast.doc_comment_text(), |
90 | src.ast.short_label(), | 91 | src.ast.short_label(), |
91 | ); | 92 | ); |
@@ -140,22 +141,22 @@ impl NavigationTarget { | |||
140 | /// Allows `NavigationTarget` to be created from a `NameOwner` | 141 | /// Allows `NavigationTarget` to be created from a `NameOwner` |
141 | pub(crate) fn from_named( | 142 | pub(crate) fn from_named( |
142 | db: &RootDatabase, | 143 | db: &RootDatabase, |
143 | file_id: hir::HirFileId, | 144 | node: Source<&dyn ast::NameOwner>, |
144 | node: &impl ast::NameOwner, | ||
145 | docs: Option<String>, | 145 | docs: Option<String>, |
146 | description: Option<String>, | 146 | description: Option<String>, |
147 | ) -> NavigationTarget { | 147 | ) -> NavigationTarget { |
148 | //FIXME: use `_` instead of empty string | 148 | //FIXME: use `_` instead of empty string |
149 | let name = node.name().map(|it| it.text().clone()).unwrap_or_default(); | 149 | let name = node.ast.name().map(|it| it.text().clone()).unwrap_or_default(); |
150 | let focus_range = node.name().map(|it| find_range_from_node(db, file_id, it.syntax()).1); | 150 | let focus_range = |
151 | let (file_id, full_range) = find_range_from_node(db, file_id, node.syntax()); | 151 | node.ast.name().map(|it| original_range(db, node.with_ast(it.syntax())).range); |
152 | let frange = original_range(db, node.map(|it| it.syntax())); | ||
152 | 153 | ||
153 | NavigationTarget::from_syntax( | 154 | NavigationTarget::from_syntax( |
154 | file_id, | 155 | frange.file_id, |
155 | name, | 156 | name, |
156 | focus_range, | 157 | focus_range, |
157 | full_range, | 158 | frange.range, |
158 | node.syntax(), | 159 | node.ast.syntax().kind(), |
159 | docs, | 160 | docs, |
160 | description, | 161 | description, |
161 | ) | 162 | ) |
@@ -166,14 +167,14 @@ impl NavigationTarget { | |||
166 | name: SmolStr, | 167 | name: SmolStr, |
167 | focus_range: Option<TextRange>, | 168 | focus_range: Option<TextRange>, |
168 | full_range: TextRange, | 169 | full_range: TextRange, |
169 | node: &SyntaxNode, | 170 | kind: SyntaxKind, |
170 | docs: Option<String>, | 171 | docs: Option<String>, |
171 | description: Option<String>, | 172 | description: Option<String>, |
172 | ) -> NavigationTarget { | 173 | ) -> NavigationTarget { |
173 | NavigationTarget { | 174 | NavigationTarget { |
174 | file_id, | 175 | file_id, |
175 | name, | 176 | name, |
176 | kind: node.kind(), | 177 | kind, |
177 | full_range, | 178 | full_range, |
178 | focus_range, | 179 | focus_range, |
179 | container_name: None, | 180 | container_name: None, |
@@ -218,8 +219,7 @@ where | |||
218 | let src = self.source(db); | 219 | let src = self.source(db); |
219 | NavigationTarget::from_named( | 220 | NavigationTarget::from_named( |
220 | db, | 221 | db, |
221 | src.file_id, | 222 | src.as_ref().map(|it| it as &dyn ast::NameOwner), |
222 | &src.ast, | ||
223 | src.ast.doc_comment_text(), | 223 | src.ast.doc_comment_text(), |
224 | src.ast.short_label(), | 224 | src.ast.short_label(), |
225 | ) | 225 | ) |
@@ -230,29 +230,29 @@ impl ToNav for hir::Module { | |||
230 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 230 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
231 | let src = self.definition_source(db); | 231 | let src = self.definition_source(db); |
232 | let name = self.name(db).map(|it| it.to_string().into()).unwrap_or_default(); | 232 | let name = self.name(db).map(|it| it.to_string().into()).unwrap_or_default(); |
233 | match src.ast { | 233 | match &src.ast { |
234 | ModuleSource::SourceFile(node) => { | 234 | ModuleSource::SourceFile(node) => { |
235 | let (file_id, text_range) = find_range_from_node(db, src.file_id, node.syntax()); | 235 | let frange = original_range(db, src.with_ast(node.syntax())); |
236 | 236 | ||
237 | NavigationTarget::from_syntax( | 237 | NavigationTarget::from_syntax( |
238 | file_id, | 238 | frange.file_id, |
239 | name, | 239 | name, |
240 | None, | 240 | None, |
241 | text_range, | 241 | frange.range, |
242 | node.syntax(), | 242 | node.syntax().kind(), |
243 | None, | 243 | None, |
244 | None, | 244 | None, |
245 | ) | 245 | ) |
246 | } | 246 | } |
247 | ModuleSource::Module(node) => { | 247 | ModuleSource::Module(node) => { |
248 | let (file_id, text_range) = find_range_from_node(db, src.file_id, node.syntax()); | 248 | let frange = original_range(db, src.with_ast(node.syntax())); |
249 | 249 | ||
250 | NavigationTarget::from_syntax( | 250 | NavigationTarget::from_syntax( |
251 | file_id, | 251 | frange.file_id, |
252 | name, | 252 | name, |
253 | None, | 253 | None, |
254 | text_range, | 254 | frange.range, |
255 | node.syntax(), | 255 | node.syntax().kind(), |
256 | node.doc_comment_text(), | 256 | node.doc_comment_text(), |
257 | node.short_label(), | 257 | node.short_label(), |
258 | ) | 258 | ) |
@@ -264,14 +264,14 @@ impl ToNav for hir::Module { | |||
264 | impl ToNav for hir::ImplBlock { | 264 | impl ToNav for hir::ImplBlock { |
265 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 265 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
266 | let src = self.source(db); | 266 | let src = self.source(db); |
267 | let (file_id, text_range) = find_range_from_node(db, src.file_id, src.ast.syntax()); | 267 | let frange = original_range(db, src.as_ref().map(|it| it.syntax())); |
268 | 268 | ||
269 | NavigationTarget::from_syntax( | 269 | NavigationTarget::from_syntax( |
270 | file_id, | 270 | frange.file_id, |
271 | "impl".into(), | 271 | "impl".into(), |
272 | None, | 272 | None, |
273 | text_range, | 273 | frange.range, |
274 | src.ast.syntax(), | 274 | src.ast.syntax().kind(), |
275 | None, | 275 | None, |
276 | None, | 276 | None, |
277 | ) | 277 | ) |
@@ -282,22 +282,21 @@ impl ToNav for hir::StructField { | |||
282 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 282 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
283 | let src = self.source(db); | 283 | let src = self.source(db); |
284 | 284 | ||
285 | match src.ast { | 285 | match &src.ast { |
286 | FieldSource::Named(it) => NavigationTarget::from_named( | 286 | FieldSource::Named(it) => NavigationTarget::from_named( |
287 | db, | 287 | db, |
288 | src.file_id, | 288 | src.with_ast(it), |
289 | &it, | ||
290 | it.doc_comment_text(), | 289 | it.doc_comment_text(), |
291 | it.short_label(), | 290 | it.short_label(), |
292 | ), | 291 | ), |
293 | FieldSource::Pos(it) => { | 292 | FieldSource::Pos(it) => { |
294 | let (file_id, text_range) = find_range_from_node(db, src.file_id, it.syntax()); | 293 | let frange = original_range(db, src.with_ast(it.syntax())); |
295 | NavigationTarget::from_syntax( | 294 | NavigationTarget::from_syntax( |
296 | file_id, | 295 | frange.file_id, |
297 | "".into(), | 296 | "".into(), |
298 | None, | 297 | None, |
299 | text_range, | 298 | frange.range, |
300 | it.syntax(), | 299 | it.syntax().kind(), |
301 | None, | 300 | None, |
302 | None, | 301 | None, |
303 | ) | 302 | ) |
@@ -310,7 +309,12 @@ impl ToNav for hir::MacroDef { | |||
310 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 309 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
311 | let src = self.source(db); | 310 | let src = self.source(db); |
312 | log::debug!("nav target {:#?}", src.ast.syntax()); | 311 | log::debug!("nav target {:#?}", src.ast.syntax()); |
313 | NavigationTarget::from_named(db, src.file_id, &src.ast, src.ast.doc_comment_text(), None) | 312 | NavigationTarget::from_named( |
313 | db, | ||
314 | src.as_ref().map(|it| it as &dyn ast::NameOwner), | ||
315 | src.ast.doc_comment_text(), | ||
316 | None, | ||
317 | ) | ||
314 | } | 318 | } |
315 | } | 319 | } |
316 | 320 | ||
@@ -360,21 +364,6 @@ impl ToNav for hir::Local { | |||
360 | } | 364 | } |
361 | } | 365 | } |
362 | 366 | ||
363 | fn find_range_from_node( | ||
364 | db: &RootDatabase, | ||
365 | src: hir::HirFileId, | ||
366 | node: &SyntaxNode, | ||
367 | ) -> (FileId, TextRange) { | ||
368 | let text_range = node.text_range(); | ||
369 | let (file_id, text_range) = src | ||
370 | .expansion_info(db) | ||
371 | .and_then(|expansion_info| expansion_info.find_range(text_range)) | ||
372 | .unwrap_or((src, text_range)); | ||
373 | |||
374 | // FIXME: handle recursive macro generated macro | ||
375 | (file_id.original_file(db), text_range) | ||
376 | } | ||
377 | |||
378 | pub(crate) fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> { | 367 | pub(crate) fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> { |
379 | let parse = db.parse(symbol.file_id); | 368 | let parse = db.parse(symbol.file_id); |
380 | let node = symbol.ptr.to_node(parse.tree().syntax()); | 369 | let node = symbol.ptr.to_node(parse.tree().syntax()); |