aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/display
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/display')
-rw-r--r--crates/ide/src/display/navigation_target.rs132
1 files changed, 94 insertions, 38 deletions
diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs
index 48acb8c93..ac6346b2b 100644
--- a/crates/ide/src/display/navigation_target.rs
+++ b/crates/ide/src/display/navigation_target.rs
@@ -2,19 +2,43 @@
2 2
3use either::Either; 3use either::Either;
4use hir::{AssocItem, Documentation, FieldSource, HasAttrs, HasSource, InFile, ModuleSource}; 4use hir::{AssocItem, Documentation, FieldSource, HasAttrs, HasSource, InFile, ModuleSource};
5use ide_db::base_db::{FileId, SourceDatabase}; 5use ide_db::{
6 base_db::{FileId, SourceDatabase},
7 symbol_index::FileSymbolKind,
8};
6use ide_db::{defs::Definition, RootDatabase}; 9use ide_db::{defs::Definition, RootDatabase};
7use syntax::{ 10use syntax::{
8 ast::{self, NameOwner}, 11 ast::{self, NameOwner},
9 match_ast, AstNode, SmolStr, 12 match_ast, AstNode, SmolStr, TextRange,
10 SyntaxKind::{self, IDENT_PAT, LIFETIME_PARAM, TYPE_PARAM},
11 TextRange,
12}; 13};
13 14
14use crate::FileSymbol; 15use crate::FileSymbol;
15 16
16use super::short_label::ShortLabel; 17use super::short_label::ShortLabel;
17 18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20pub enum SymbolKind {
21 Module,
22 Impl,
23 Field,
24 TypeParam,
25 LifetimeParam,
26 SelfParam,
27 Local,
28 Function,
29 Const,
30 Static,
31 Struct,
32 Enum,
33 Variant,
34 Union,
35 TypeAlias,
36 Trait,
37 Macro,
38 // Do we actually need this?
39 DocTest,
40}
41
18/// `NavigationTarget` represents and element in the editor's UI which you can 42/// `NavigationTarget` represents and element in the editor's UI which you can
19/// click on to navigate to a particular piece of code. 43/// click on to navigate to a particular piece of code.
20/// 44///
@@ -40,7 +64,7 @@ pub struct NavigationTarget {
40 /// Clients should place the cursor on this range when navigating to this target. 64 /// Clients should place the cursor on this range when navigating to this target.
41 pub focus_range: Option<TextRange>, 65 pub focus_range: Option<TextRange>,
42 pub name: SmolStr, 66 pub name: SmolStr,
43 pub kind: SyntaxKind, 67 pub kind: SymbolKind,
44 pub container_name: Option<SmolStr>, 68 pub container_name: Option<SmolStr>,
45 pub description: Option<String>, 69 pub description: Option<String>,
46 pub docs: Option<Documentation>, 70 pub docs: Option<Documentation>,
@@ -69,7 +93,7 @@ impl NavigationTarget {
69 name, 93 name,
70 None, 94 None,
71 frange.range, 95 frange.range,
72 src.value.syntax().kind(), 96 SymbolKind::Module,
73 ); 97 );
74 res.docs = module.attrs(db).docs(); 98 res.docs = module.attrs(db).docs();
75 res.description = src.value.short_label(); 99 res.description = src.value.short_label();
@@ -101,6 +125,7 @@ impl NavigationTarget {
101 pub(crate) fn from_named( 125 pub(crate) fn from_named(
102 db: &RootDatabase, 126 db: &RootDatabase,
103 node: InFile<&dyn ast::NameOwner>, 127 node: InFile<&dyn ast::NameOwner>,
128 kind: SymbolKind,
104 ) -> NavigationTarget { 129 ) -> NavigationTarget {
105 let name = 130 let name =
106 node.value.name().map(|it| it.text().clone()).unwrap_or_else(|| SmolStr::new("_")); 131 node.value.name().map(|it| it.text().clone()).unwrap_or_else(|| SmolStr::new("_"));
@@ -108,13 +133,7 @@ impl NavigationTarget {
108 node.value.name().map(|it| node.with_value(it.syntax()).original_file_range(db).range); 133 node.value.name().map(|it| node.with_value(it.syntax()).original_file_range(db).range);
109 let frange = node.map(|it| it.syntax()).original_file_range(db); 134 let frange = node.map(|it| it.syntax()).original_file_range(db);
110 135
111 NavigationTarget::from_syntax( 136 NavigationTarget::from_syntax(frange.file_id, name, focus_range, frange.range, kind)
112 frange.file_id,
113 name,
114 focus_range,
115 frange.range,
116 node.value.syntax().kind(),
117 )
118 } 137 }
119 138
120 fn from_syntax( 139 fn from_syntax(
@@ -122,7 +141,7 @@ impl NavigationTarget {
122 name: SmolStr, 141 name: SmolStr,
123 focus_range: Option<TextRange>, 142 focus_range: Option<TextRange>,
124 full_range: TextRange, 143 full_range: TextRange,
125 kind: SyntaxKind, 144 kind: SymbolKind,
126 ) -> NavigationTarget { 145 ) -> NavigationTarget {
127 NavigationTarget { 146 NavigationTarget {
128 file_id, 147 file_id,
@@ -142,7 +161,17 @@ impl ToNav for FileSymbol {
142 NavigationTarget { 161 NavigationTarget {
143 file_id: self.file_id, 162 file_id: self.file_id,
144 name: self.name.clone(), 163 name: self.name.clone(),
145 kind: self.kind, 164 kind: match self.kind {
165 FileSymbolKind::Function => SymbolKind::Function,
166 FileSymbolKind::Struct => SymbolKind::Struct,
167 FileSymbolKind::Enum => SymbolKind::Enum,
168 FileSymbolKind::Trait => SymbolKind::Trait,
169 FileSymbolKind::Module => SymbolKind::Module,
170 FileSymbolKind::TypeAlias => SymbolKind::TypeAlias,
171 FileSymbolKind::Const => SymbolKind::Const,
172 FileSymbolKind::Static => SymbolKind::Static,
173 FileSymbolKind::Macro => SymbolKind::Macro,
174 },
146 full_range: self.range, 175 full_range: self.range,
147 focus_range: self.name_range, 176 focus_range: self.name_range,
148 container_name: self.container_name.clone(), 177 container_name: self.container_name.clone(),
@@ -191,16 +220,36 @@ impl TryToNav for hir::ModuleDef {
191 } 220 }
192} 221}
193 222
194pub(crate) trait ToNavFromAst {} 223pub(crate) trait ToNavFromAst {
195impl ToNavFromAst for hir::Function {} 224 const KIND: SymbolKind;
196impl ToNavFromAst for hir::Const {} 225}
197impl ToNavFromAst for hir::Static {} 226impl ToNavFromAst for hir::Function {
198impl ToNavFromAst for hir::Struct {} 227 const KIND: SymbolKind = SymbolKind::Function;
199impl ToNavFromAst for hir::Enum {} 228}
200impl ToNavFromAst for hir::EnumVariant {} 229impl ToNavFromAst for hir::Const {
201impl ToNavFromAst for hir::Union {} 230 const KIND: SymbolKind = SymbolKind::Const;
202impl ToNavFromAst for hir::TypeAlias {} 231}
203impl ToNavFromAst for hir::Trait {} 232impl ToNavFromAst for hir::Static {
233 const KIND: SymbolKind = SymbolKind::Static;
234}
235impl ToNavFromAst for hir::Struct {
236 const KIND: SymbolKind = SymbolKind::Struct;
237}
238impl ToNavFromAst for hir::Enum {
239 const KIND: SymbolKind = SymbolKind::Enum;
240}
241impl ToNavFromAst for hir::EnumVariant {
242 const KIND: SymbolKind = SymbolKind::Variant;
243}
244impl ToNavFromAst for hir::Union {
245 const KIND: SymbolKind = SymbolKind::Union;
246}
247impl ToNavFromAst for hir::TypeAlias {
248 const KIND: SymbolKind = SymbolKind::TypeAlias;
249}
250impl ToNavFromAst for hir::Trait {
251 const KIND: SymbolKind = SymbolKind::Trait;
252}
204 253
205impl<D> ToNav for D 254impl<D> ToNav for D
206where 255where
@@ -209,8 +258,11 @@ where
209{ 258{
210 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { 259 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
211 let src = self.source(db); 260 let src = self.source(db);
212 let mut res = 261 let mut res = NavigationTarget::from_named(
213 NavigationTarget::from_named(db, src.as_ref().map(|it| it as &dyn ast::NameOwner)); 262 db,
263 src.as_ref().map(|it| it as &dyn ast::NameOwner),
264 D::KIND,
265 );
214 res.docs = self.docs(db); 266 res.docs = self.docs(db);
215 res.description = src.value.short_label(); 267 res.description = src.value.short_label();
216 res 268 res
@@ -228,7 +280,7 @@ impl ToNav for hir::Module {
228 } 280 }
229 }; 281 };
230 let frange = src.with_value(syntax).original_file_range(db); 282 let frange = src.with_value(syntax).original_file_range(db);
231 NavigationTarget::from_syntax(frange.file_id, name, focus, frange.range, syntax.kind()) 283 NavigationTarget::from_syntax(frange.file_id, name, focus, frange.range, SymbolKind::Module)
232 } 284 }
233} 285}
234 286
@@ -252,7 +304,7 @@ impl ToNav for hir::Impl {
252 "impl".into(), 304 "impl".into(),
253 focus_range, 305 focus_range,
254 frange.range, 306 frange.range,
255 src.value.syntax().kind(), 307 SymbolKind::Impl,
256 ) 308 )
257 } 309 }
258} 310}
@@ -263,7 +315,8 @@ impl ToNav for hir::Field {
263 315
264 match &src.value { 316 match &src.value {
265 FieldSource::Named(it) => { 317 FieldSource::Named(it) => {
266 let mut res = NavigationTarget::from_named(db, src.with_value(it)); 318 let mut res =
319 NavigationTarget::from_named(db, src.with_value(it), SymbolKind::Field);
267 res.docs = self.docs(db); 320 res.docs = self.docs(db);
268 res.description = it.short_label(); 321 res.description = it.short_label();
269 res 322 res
@@ -275,7 +328,7 @@ impl ToNav for hir::Field {
275 "".into(), 328 "".into(),
276 None, 329 None,
277 frange.range, 330 frange.range,
278 it.syntax().kind(), 331 SymbolKind::Field,
279 ) 332 )
280 } 333 }
281 } 334 }
@@ -286,8 +339,11 @@ impl ToNav for hir::MacroDef {
286 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { 339 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
287 let src = self.source(db); 340 let src = self.source(db);
288 log::debug!("nav target {:#?}", src.value.syntax()); 341 log::debug!("nav target {:#?}", src.value.syntax());
289 let mut res = 342 let mut res = NavigationTarget::from_named(
290 NavigationTarget::from_named(db, src.as_ref().map(|it| it as &dyn ast::NameOwner)); 343 db,
344 src.as_ref().map(|it| it as &dyn ast::NameOwner),
345 SymbolKind::Macro,
346 );
291 res.docs = self.docs(db); 347 res.docs = self.docs(db);
292 res 348 res
293 } 349 }
@@ -330,7 +386,7 @@ impl ToNav for hir::Local {
330 NavigationTarget { 386 NavigationTarget {
331 file_id: full_range.file_id, 387 file_id: full_range.file_id,
332 name, 388 name,
333 kind: IDENT_PAT, 389 kind: SymbolKind::Local,
334 full_range: full_range.range, 390 full_range: full_range.range,
335 focus_range: None, 391 focus_range: None,
336 container_name: None, 392 container_name: None,
@@ -354,7 +410,7 @@ impl ToNav for hir::TypeParam {
354 NavigationTarget { 410 NavigationTarget {
355 file_id: src.file_id.original_file(db), 411 file_id: src.file_id.original_file(db),
356 name: self.name(db).to_string().into(), 412 name: self.name(db).to_string().into(),
357 kind: TYPE_PARAM, 413 kind: SymbolKind::TypeParam,
358 full_range, 414 full_range,
359 focus_range, 415 focus_range,
360 container_name: None, 416 container_name: None,
@@ -371,7 +427,7 @@ impl ToNav for hir::LifetimeParam {
371 NavigationTarget { 427 NavigationTarget {
372 file_id: src.file_id.original_file(db), 428 file_id: src.file_id.original_file(db),
373 name: self.name(db).to_string().into(), 429 name: self.name(db).to_string().into(),
374 kind: LIFETIME_PARAM, 430 kind: SymbolKind::LifetimeParam,
375 full_range, 431 full_range,
376 focus_range: Some(full_range), 432 focus_range: Some(full_range),
377 container_name: None, 433 container_name: None,
@@ -432,7 +488,7 @@ fn foo() { enum FooInner { } }
432 5..13, 488 5..13,
433 ), 489 ),
434 name: "FooInner", 490 name: "FooInner",
435 kind: ENUM, 491 kind: Enum,
436 container_name: None, 492 container_name: None,
437 description: Some( 493 description: Some(
438 "enum FooInner", 494 "enum FooInner",
@@ -448,7 +504,7 @@ fn foo() { enum FooInner { } }
448 34..42, 504 34..42,
449 ), 505 ),
450 name: "FooInner", 506 name: "FooInner",
451 kind: ENUM, 507 kind: Enum,
452 container_name: Some( 508 container_name: Some(
453 "foo", 509 "foo",
454 ), 510 ),