aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_db/src/defs.rs
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2020-12-16 20:35:15 +0000
committerLukas Wirth <[email protected]>2020-12-16 21:21:01 +0000
commit55faa2daa3fc8bd213038a012b1c5e9ad5fd3736 (patch)
tree2d84a7fa9fe93aa7a6bdd4d0f9cda87e6bb4a5da /crates/ide_db/src/defs.rs
parent067067a6c11bb5afda98f5af14bfdec4744e7812 (diff)
Lifetime reference search
Diffstat (limited to 'crates/ide_db/src/defs.rs')
-rw-r--r--crates/ide_db/src/defs.rs59
1 files changed, 56 insertions, 3 deletions
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs
index d4a774261..f2d1e4c39 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
8use hir::{ 8use hir::{
9 db::HirDatabase, Crate, Field, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, 9 db::HirDatabase, Crate, Field, HasVisibility, ImplDef, LifetimeParam, Local, MacroDef, Module,
10 Name, PathResolution, Semantics, TypeParam, Visibility, 10 ModuleDef, Name, PathResolution, Semantics, TypeParam, Visibility,
11}; 11};
12use syntax::{ 12use syntax::{
13 ast::{self, AstNode}, 13 ast::{self, AstNode},
14 match_ast, SyntaxNode, 14 match_ast, SyntaxKind, SyntaxNode,
15}; 15};
16 16
17use crate::RootDatabase; 17use crate::RootDatabase;
@@ -25,6 +25,8 @@ pub enum Definition {
25 SelfType(ImplDef), 25 SelfType(ImplDef),
26 Local(Local), 26 Local(Local),
27 TypeParam(TypeParam), 27 TypeParam(TypeParam),
28 LifetimeParam(LifetimeParam),
29 // FIXME: Label
28} 30}
29 31
30impl Definition { 32impl 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
343impl From<PathResolution> for Definition { 396impl From<PathResolution> for Definition {