diff options
Diffstat (limited to 'crates/ide_db/src/defs.rs')
-rw-r--r-- | crates/ide_db/src/defs.rs | 61 |
1 files changed, 57 insertions, 4 deletions
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs index d4a774261..bd2afc887 100644 --- a/crates/ide_db/src/defs.rs +++ b/crates/ide_db/src/defs.rs | |||
@@ -6,12 +6,12 @@ | |||
6 | // FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). | 6 | // FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). |
7 | 7 | ||
8 | use hir::{ | 8 | use hir::{ |
9 | db::HirDatabase, Crate, Field, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, | 9 | db::HirDatabase, Crate, Field, HasVisibility, Impl, LifetimeParam, Local, MacroDef, Module, |
10 | Name, PathResolution, Semantics, TypeParam, Visibility, | 10 | ModuleDef, Name, PathResolution, Semantics, TypeParam, Visibility, |
11 | }; | 11 | }; |
12 | use syntax::{ | 12 | use syntax::{ |
13 | ast::{self, AstNode}, | 13 | ast::{self, AstNode}, |
14 | match_ast, SyntaxNode, | 14 | match_ast, SyntaxKind, SyntaxNode, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | use crate::RootDatabase; | 17 | use crate::RootDatabase; |
@@ -22,9 +22,11 @@ pub enum Definition { | |||
22 | Macro(MacroDef), | 22 | Macro(MacroDef), |
23 | Field(Field), | 23 | Field(Field), |
24 | ModuleDef(ModuleDef), | 24 | ModuleDef(ModuleDef), |
25 | SelfType(ImplDef), | 25 | SelfType(Impl), |
26 | Local(Local), | 26 | Local(Local), |
27 | TypeParam(TypeParam), | 27 | TypeParam(TypeParam), |
28 | LifetimeParam(LifetimeParam), | ||
29 | // FIXME: Label | ||
28 | } | 30 | } |
29 | 31 | ||
30 | impl Definition { | 32 | impl Definition { |
@@ -36,6 +38,7 @@ impl Definition { | |||
36 | Definition::SelfType(it) => Some(it.module(db)), | 38 | Definition::SelfType(it) => Some(it.module(db)), |
37 | Definition::Local(it) => Some(it.module(db)), | 39 | Definition::Local(it) => Some(it.module(db)), |
38 | Definition::TypeParam(it) => Some(it.module(db)), | 40 | Definition::TypeParam(it) => Some(it.module(db)), |
41 | Definition::LifetimeParam(it) => Some(it.module(db)), | ||
39 | } | 42 | } |
40 | } | 43 | } |
41 | 44 | ||
@@ -47,6 +50,7 @@ impl Definition { | |||
47 | Definition::SelfType(_) => None, | 50 | Definition::SelfType(_) => None, |
48 | Definition::Local(_) => None, | 51 | Definition::Local(_) => None, |
49 | Definition::TypeParam(_) => None, | 52 | Definition::TypeParam(_) => None, |
53 | Definition::LifetimeParam(_) => None, | ||
50 | } | 54 | } |
51 | } | 55 | } |
52 | 56 | ||
@@ -72,6 +76,7 @@ impl Definition { | |||
72 | Definition::SelfType(_) => return None, | 76 | Definition::SelfType(_) => return None, |
73 | Definition::Local(it) => it.name(db)?, | 77 | Definition::Local(it) => it.name(db)?, |
74 | Definition::TypeParam(it) => it.name(db), | 78 | Definition::TypeParam(it) => it.name(db), |
79 | Definition::LifetimeParam(it) => it.name(db), | ||
75 | }; | 80 | }; |
76 | Some(name) | 81 | Some(name) |
77 | } | 82 | } |
@@ -229,6 +234,25 @@ impl NameClass { | |||
229 | } | 234 | } |
230 | } | 235 | } |
231 | } | 236 | } |
237 | |||
238 | pub fn classify_lifetime( | ||
239 | sema: &Semantics<RootDatabase>, | ||
240 | lifetime: &ast::Lifetime, | ||
241 | ) -> Option<NameClass> { | ||
242 | let _p = profile::span("classify_lifetime").detail(|| lifetime.to_string()); | ||
243 | let parent = lifetime.syntax().parent()?; | ||
244 | |||
245 | match_ast! { | ||
246 | match parent { | ||
247 | ast::LifetimeParam(it) => { | ||
248 | let def = sema.to_def(&it)?; | ||
249 | Some(NameClass::Definition(Definition::LifetimeParam(def))) | ||
250 | }, | ||
251 | ast::Label(_it) => None, | ||
252 | _ => None, | ||
253 | } | ||
254 | } | ||
255 | } | ||
232 | } | 256 | } |
233 | 257 | ||
234 | #[derive(Debug)] | 258 | #[derive(Debug)] |
@@ -338,6 +362,35 @@ impl NameRefClass { | |||
338 | let resolved = sema.resolve_extern_crate(&extern_crate)?; | 362 | let resolved = sema.resolve_extern_crate(&extern_crate)?; |
339 | Some(NameRefClass::ExternCrate(resolved)) | 363 | Some(NameRefClass::ExternCrate(resolved)) |
340 | } | 364 | } |
365 | |||
366 | pub fn classify_lifetime( | ||
367 | sema: &Semantics<RootDatabase>, | ||
368 | lifetime: &ast::Lifetime, | ||
369 | ) -> Option<NameRefClass> { | ||
370 | let _p = profile::span("classify_lifetime_ref").detail(|| lifetime.to_string()); | ||
371 | let parent = lifetime.syntax().parent()?; | ||
372 | match parent.kind() { | ||
373 | SyntaxKind::LIFETIME_ARG | ||
374 | | SyntaxKind::SELF_PARAM | ||
375 | | SyntaxKind::TYPE_BOUND | ||
376 | | SyntaxKind::WHERE_PRED | ||
377 | | SyntaxKind::REF_TYPE => sema | ||
378 | .resolve_lifetime_param(lifetime) | ||
379 | .map(Definition::LifetimeParam) | ||
380 | .map(NameRefClass::Definition), | ||
381 | // lifetime bounds, as in the 'b in 'a: 'b aren't wrapped in TypeBound nodes so we gotta check | ||
382 | // if our lifetime is in a LifetimeParam without being the constrained lifetime | ||
383 | _ if ast::LifetimeParam::cast(parent).and_then(|param| param.lifetime()).as_ref() | ||
384 | != Some(lifetime) => | ||
385 | { | ||
386 | sema.resolve_lifetime_param(lifetime) | ||
387 | .map(Definition::LifetimeParam) | ||
388 | .map(NameRefClass::Definition) | ||
389 | } | ||
390 | SyntaxKind::BREAK_EXPR | SyntaxKind::CONTINUE_EXPR => None, | ||
391 | _ => None, | ||
392 | } | ||
393 | } | ||
341 | } | 394 | } |
342 | 395 | ||
343 | impl From<PathResolution> for Definition { | 396 | impl From<PathResolution> for Definition { |