diff options
Diffstat (limited to 'crates/ra_ide/src/display/navigation_target.rs')
-rw-r--r-- | crates/ra_ide/src/display/navigation_target.rs | 134 |
1 files changed, 66 insertions, 68 deletions
diff --git a/crates/ra_ide/src/display/navigation_target.rs b/crates/ra_ide/src/display/navigation_target.rs index 5da28edd2..8bf2428ed 100644 --- a/crates/ra_ide/src/display/navigation_target.rs +++ b/crates/ra_ide/src/display/navigation_target.rs | |||
@@ -11,7 +11,7 @@ use ra_syntax::{ | |||
11 | TextRange, | 11 | TextRange, |
12 | }; | 12 | }; |
13 | 13 | ||
14 | use crate::{FileRange, FileSymbol}; | 14 | use crate::FileSymbol; |
15 | 15 | ||
16 | use super::short_label::ShortLabel; | 16 | use super::short_label::ShortLabel; |
17 | 17 | ||
@@ -47,6 +47,19 @@ impl NavigationTarget { | |||
47 | pub fn range(&self) -> TextRange { | 47 | pub fn range(&self) -> TextRange { |
48 | self.focus_range.unwrap_or(self.full_range) | 48 | self.focus_range.unwrap_or(self.full_range) |
49 | } | 49 | } |
50 | /// A "most interesting" range withing the `full_range`. | ||
51 | /// | ||
52 | /// Typically, `full_range` is the whole syntax node, | ||
53 | /// including doc comments, and `focus_range` is the range of the identifier. | ||
54 | pub fn focus_range(&self) -> Option<TextRange> { | ||
55 | self.focus_range | ||
56 | } | ||
57 | pub fn full_range(&self) -> TextRange { | ||
58 | self.full_range | ||
59 | } | ||
60 | pub fn file_id(&self) -> FileId { | ||
61 | self.file_id | ||
62 | } | ||
50 | 63 | ||
51 | pub fn name(&self) -> &SmolStr { | 64 | pub fn name(&self) -> &SmolStr { |
52 | &self.name | 65 | &self.name |
@@ -60,18 +73,6 @@ impl NavigationTarget { | |||
60 | self.kind | 73 | self.kind |
61 | } | 74 | } |
62 | 75 | ||
63 | pub fn file_id(&self) -> FileId { | ||
64 | self.file_id | ||
65 | } | ||
66 | |||
67 | pub fn file_range(&self) -> FileRange { | ||
68 | FileRange { file_id: self.file_id, range: self.full_range } | ||
69 | } | ||
70 | |||
71 | pub fn full_range(&self) -> TextRange { | ||
72 | self.full_range | ||
73 | } | ||
74 | |||
75 | pub fn docs(&self) -> Option<&str> { | 76 | pub fn docs(&self) -> Option<&str> { |
76 | self.docs.as_deref() | 77 | self.docs.as_deref() |
77 | } | 78 | } |
@@ -80,27 +81,20 @@ impl NavigationTarget { | |||
80 | self.description.as_deref() | 81 | self.description.as_deref() |
81 | } | 82 | } |
82 | 83 | ||
83 | /// A "most interesting" range withing the `full_range`. | ||
84 | /// | ||
85 | /// Typically, `full_range` is the whole syntax node, | ||
86 | /// including doc comments, and `focus_range` is the range of the identifier. | ||
87 | pub fn focus_range(&self) -> Option<TextRange> { | ||
88 | self.focus_range | ||
89 | } | ||
90 | |||
91 | pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget { | 84 | pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget { |
92 | let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); | 85 | let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); |
93 | if let Some(src) = module.declaration_source(db) { | 86 | if let Some(src) = module.declaration_source(db) { |
94 | let frange = original_range(db, src.as_ref().map(|it| it.syntax())); | 87 | let frange = original_range(db, src.as_ref().map(|it| it.syntax())); |
95 | return NavigationTarget::from_syntax( | 88 | let mut res = NavigationTarget::from_syntax( |
96 | frange.file_id, | 89 | frange.file_id, |
97 | name, | 90 | name, |
98 | None, | 91 | None, |
99 | frange.range, | 92 | frange.range, |
100 | src.value.syntax().kind(), | 93 | src.value.syntax().kind(), |
101 | src.value.doc_comment_text(), | ||
102 | src.value.short_label(), | ||
103 | ); | 94 | ); |
95 | res.docs = src.value.doc_comment_text(); | ||
96 | res.description = src.value.short_label(); | ||
97 | return res; | ||
104 | } | 98 | } |
105 | module.to_nav(db) | 99 | module.to_nav(db) |
106 | } | 100 | } |
@@ -130,14 +124,12 @@ impl NavigationTarget { | |||
130 | } | 124 | } |
131 | 125 | ||
132 | /// Allows `NavigationTarget` to be created from a `NameOwner` | 126 | /// Allows `NavigationTarget` to be created from a `NameOwner` |
133 | fn from_named( | 127 | pub(crate) fn from_named( |
134 | db: &RootDatabase, | 128 | db: &RootDatabase, |
135 | node: InFile<&dyn ast::NameOwner>, | 129 | node: InFile<&dyn ast::NameOwner>, |
136 | docs: Option<String>, | ||
137 | description: Option<String>, | ||
138 | ) -> NavigationTarget { | 130 | ) -> NavigationTarget { |
139 | //FIXME: use `_` instead of empty string | 131 | let name = |
140 | let name = node.value.name().map(|it| it.text().clone()).unwrap_or_default(); | 132 | node.value.name().map(|it| it.text().clone()).unwrap_or_else(|| SmolStr::new("_")); |
141 | let focus_range = | 133 | let focus_range = |
142 | node.value.name().map(|it| original_range(db, node.with_value(it.syntax())).range); | 134 | node.value.name().map(|it| original_range(db, node.with_value(it.syntax())).range); |
143 | let frange = original_range(db, node.map(|it| it.syntax())); | 135 | let frange = original_range(db, node.map(|it| it.syntax())); |
@@ -148,8 +140,25 @@ impl NavigationTarget { | |||
148 | focus_range, | 140 | focus_range, |
149 | frange.range, | 141 | frange.range, |
150 | node.value.syntax().kind(), | 142 | node.value.syntax().kind(), |
151 | docs, | 143 | ) |
152 | description, | 144 | } |
145 | |||
146 | /// Allows `NavigationTarget` to be created from a `DocCommentsOwner` and a `NameOwner` | ||
147 | pub(crate) fn from_doc_commented( | ||
148 | db: &RootDatabase, | ||
149 | named: InFile<&dyn ast::NameOwner>, | ||
150 | node: InFile<&dyn ast::DocCommentsOwner>, | ||
151 | ) -> NavigationTarget { | ||
152 | let name = | ||
153 | named.value.name().map(|it| it.text().clone()).unwrap_or_else(|| SmolStr::new("_")); | ||
154 | let frange = original_range(db, node.map(|it| it.syntax())); | ||
155 | |||
156 | NavigationTarget::from_syntax( | ||
157 | frange.file_id, | ||
158 | name, | ||
159 | None, | ||
160 | frange.range, | ||
161 | node.value.syntax().kind(), | ||
153 | ) | 162 | ) |
154 | } | 163 | } |
155 | 164 | ||
@@ -159,8 +168,6 @@ impl NavigationTarget { | |||
159 | focus_range: Option<TextRange>, | 168 | focus_range: Option<TextRange>, |
160 | full_range: TextRange, | 169 | full_range: TextRange, |
161 | kind: SyntaxKind, | 170 | kind: SyntaxKind, |
162 | docs: Option<String>, | ||
163 | description: Option<String>, | ||
164 | ) -> NavigationTarget { | 171 | ) -> NavigationTarget { |
165 | NavigationTarget { | 172 | NavigationTarget { |
166 | file_id, | 173 | file_id, |
@@ -169,8 +176,8 @@ impl NavigationTarget { | |||
169 | full_range, | 176 | full_range, |
170 | focus_range, | 177 | focus_range, |
171 | container_name: None, | 178 | container_name: None, |
172 | description, | 179 | description: None, |
173 | docs, | 180 | docs: None, |
174 | } | 181 | } |
175 | } | 182 | } |
176 | } | 183 | } |
@@ -238,12 +245,11 @@ where | |||
238 | { | 245 | { |
239 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 246 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
240 | let src = self.source(db); | 247 | let src = self.source(db); |
241 | NavigationTarget::from_named( | 248 | let mut res = |
242 | db, | 249 | NavigationTarget::from_named(db, src.as_ref().map(|it| it as &dyn ast::NameOwner)); |
243 | src.as_ref().map(|it| it as &dyn ast::NameOwner), | 250 | res.docs = src.value.doc_comment_text(); |
244 | src.value.doc_comment_text(), | 251 | res.description = src.value.short_label(); |
245 | src.value.short_label(), | 252 | res |
246 | ) | ||
247 | } | 253 | } |
248 | } | 254 | } |
249 | 255 | ||
@@ -258,35 +264,31 @@ impl ToNav for hir::Module { | |||
258 | } | 264 | } |
259 | }; | 265 | }; |
260 | let frange = original_range(db, src.with_value(syntax)); | 266 | let frange = original_range(db, src.with_value(syntax)); |
261 | NavigationTarget::from_syntax( | 267 | NavigationTarget::from_syntax(frange.file_id, name, focus, frange.range, syntax.kind()) |
262 | frange.file_id, | ||
263 | name, | ||
264 | focus, | ||
265 | frange.range, | ||
266 | syntax.kind(), | ||
267 | None, | ||
268 | None, | ||
269 | ) | ||
270 | } | 268 | } |
271 | } | 269 | } |
272 | 270 | ||
273 | impl ToNav for hir::ImplDef { | 271 | impl ToNav for hir::ImplDef { |
274 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 272 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
275 | let src = self.source(db); | 273 | let src = self.source(db); |
276 | let frange = if let Some(item) = self.is_builtin_derive(db) { | 274 | let derive_attr = self.is_builtin_derive(db); |
275 | let frange = if let Some(item) = &derive_attr { | ||
277 | original_range(db, item.syntax()) | 276 | original_range(db, item.syntax()) |
278 | } else { | 277 | } else { |
279 | original_range(db, src.as_ref().map(|it| it.syntax())) | 278 | original_range(db, src.as_ref().map(|it| it.syntax())) |
280 | }; | 279 | }; |
280 | let focus_range = if derive_attr.is_some() { | ||
281 | None | ||
282 | } else { | ||
283 | src.value.target_type().map(|ty| original_range(db, src.with_value(ty.syntax())).range) | ||
284 | }; | ||
281 | 285 | ||
282 | NavigationTarget::from_syntax( | 286 | NavigationTarget::from_syntax( |
283 | frange.file_id, | 287 | frange.file_id, |
284 | "impl".into(), | 288 | "impl".into(), |
285 | None, | 289 | focus_range, |
286 | frange.range, | 290 | frange.range, |
287 | src.value.syntax().kind(), | 291 | src.value.syntax().kind(), |
288 | None, | ||
289 | None, | ||
290 | ) | 292 | ) |
291 | } | 293 | } |
292 | } | 294 | } |
@@ -296,12 +298,12 @@ impl ToNav for hir::Field { | |||
296 | let src = self.source(db); | 298 | let src = self.source(db); |
297 | 299 | ||
298 | match &src.value { | 300 | match &src.value { |
299 | FieldSource::Named(it) => NavigationTarget::from_named( | 301 | FieldSource::Named(it) => { |
300 | db, | 302 | let mut res = NavigationTarget::from_named(db, src.with_value(it)); |
301 | src.with_value(it), | 303 | res.docs = it.doc_comment_text(); |
302 | it.doc_comment_text(), | 304 | res.description = it.short_label(); |
303 | it.short_label(), | 305 | res |
304 | ), | 306 | } |
305 | FieldSource::Pos(it) => { | 307 | FieldSource::Pos(it) => { |
306 | let frange = original_range(db, src.with_value(it.syntax())); | 308 | let frange = original_range(db, src.with_value(it.syntax())); |
307 | NavigationTarget::from_syntax( | 309 | NavigationTarget::from_syntax( |
@@ -310,8 +312,6 @@ impl ToNav for hir::Field { | |||
310 | None, | 312 | None, |
311 | frange.range, | 313 | frange.range, |
312 | it.syntax().kind(), | 314 | it.syntax().kind(), |
313 | None, | ||
314 | None, | ||
315 | ) | 315 | ) |
316 | } | 316 | } |
317 | } | 317 | } |
@@ -322,12 +322,10 @@ impl ToNav for hir::MacroDef { | |||
322 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 322 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
323 | let src = self.source(db); | 323 | let src = self.source(db); |
324 | log::debug!("nav target {:#?}", src.value.syntax()); | 324 | log::debug!("nav target {:#?}", src.value.syntax()); |
325 | NavigationTarget::from_named( | 325 | let mut res = |
326 | db, | 326 | NavigationTarget::from_named(db, src.as_ref().map(|it| it as &dyn ast::NameOwner)); |
327 | src.as_ref().map(|it| it as &dyn ast::NameOwner), | 327 | res.docs = src.value.doc_comment_text(); |
328 | src.value.doc_comment_text(), | 328 | res |
329 | None, | ||
330 | ) | ||
331 | } | 329 | } |
332 | } | 330 | } |
333 | 331 | ||