diff options
Diffstat (limited to 'crates/ra_analysis/src/descriptors')
-rw-r--r-- | crates/ra_analysis/src/descriptors/mod.rs | 2 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/nameres.rs | 4 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/path.rs | 51 |
3 files changed, 52 insertions, 5 deletions
diff --git a/crates/ra_analysis/src/descriptors/mod.rs b/crates/ra_analysis/src/descriptors/mod.rs index e6225479d..97750ea64 100644 --- a/crates/ra_analysis/src/descriptors/mod.rs +++ b/crates/ra_analysis/src/descriptors/mod.rs | |||
@@ -5,7 +5,7 @@ mod path; | |||
5 | use std::sync::Arc; | 5 | use std::sync::Arc; |
6 | 6 | ||
7 | use ra_syntax::{ | 7 | use ra_syntax::{ |
8 | ast::{self, FnDefNode}, | 8 | ast::{self, FnDefNode, AstNode}, |
9 | TextRange, | 9 | TextRange, |
10 | }; | 10 | }; |
11 | 11 | ||
diff --git a/crates/ra_analysis/src/descriptors/module/nameres.rs b/crates/ra_analysis/src/descriptors/module/nameres.rs index bf671470c..4c555421d 100644 --- a/crates/ra_analysis/src/descriptors/module/nameres.rs +++ b/crates/ra_analysis/src/descriptors/module/nameres.rs | |||
@@ -23,7 +23,7 @@ use rustc_hash::FxHashMap; | |||
23 | 23 | ||
24 | use ra_syntax::{ | 24 | use ra_syntax::{ |
25 | SmolStr, SyntaxKind::{self, *}, | 25 | SmolStr, SyntaxKind::{self, *}, |
26 | ast::{self, AstNode, ModuleItemOwner} | 26 | ast::{self, ModuleItemOwner} |
27 | }; | 27 | }; |
28 | 28 | ||
29 | use crate::{ | 29 | use crate::{ |
@@ -309,7 +309,7 @@ where | |||
309 | 309 | ||
310 | let mut curr = match import.path.kind { | 310 | let mut curr = match import.path.kind { |
311 | // TODO: handle extern crates | 311 | // TODO: handle extern crates |
312 | PathKind::Abs => return, | 312 | PathKind::Plain => return, |
313 | PathKind::Self_ => module_id, | 313 | PathKind::Self_ => module_id, |
314 | PathKind::Super => { | 314 | PathKind::Super => { |
315 | match module_id.parent(&self.module_tree) { | 315 | match module_id.parent(&self.module_tree) { |
diff --git a/crates/ra_analysis/src/descriptors/path.rs b/crates/ra_analysis/src/descriptors/path.rs index 4ed561b51..99fca18b1 100644 --- a/crates/ra_analysis/src/descriptors/path.rs +++ b/crates/ra_analysis/src/descriptors/path.rs | |||
@@ -10,13 +10,14 @@ pub(crate) struct Path { | |||
10 | 10 | ||
11 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 11 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
12 | pub(crate) enum PathKind { | 12 | pub(crate) enum PathKind { |
13 | Abs, | 13 | Plain, |
14 | Self_, | 14 | Self_, |
15 | Super, | 15 | Super, |
16 | Crate, | 16 | Crate, |
17 | } | 17 | } |
18 | 18 | ||
19 | impl Path { | 19 | impl Path { |
20 | /// Calls `cb` with all paths, represented by this use item. | ||
20 | pub(crate) fn expand_use_item( | 21 | pub(crate) fn expand_use_item( |
21 | item: ast::UseItem, | 22 | item: ast::UseItem, |
22 | mut cb: impl FnMut(Path, Option<LocalSyntaxPtr>), | 23 | mut cb: impl FnMut(Path, Option<LocalSyntaxPtr>), |
@@ -25,6 +26,52 @@ impl Path { | |||
25 | expand_use_tree(None, tree, &mut cb); | 26 | expand_use_tree(None, tree, &mut cb); |
26 | } | 27 | } |
27 | } | 28 | } |
29 | |||
30 | /// Converts an `ast::Path` to `Path`. Works with use trees. | ||
31 | pub(crate) fn from_ast(mut path: ast::Path) -> Option<Path> { | ||
32 | let mut kind = PathKind::Plain; | ||
33 | let mut segments = Vec::new(); | ||
34 | loop { | ||
35 | let segment = path.segment()?; | ||
36 | match segment.kind()? { | ||
37 | ast::PathSegmentKind::Name(name) => segments.push(name.text()), | ||
38 | ast::PathSegmentKind::CrateKw => { | ||
39 | kind = PathKind::Crate; | ||
40 | break; | ||
41 | } | ||
42 | ast::PathSegmentKind::SelfKw => { | ||
43 | kind = PathKind::Self_; | ||
44 | break; | ||
45 | } | ||
46 | ast::PathSegmentKind::SuperKw => { | ||
47 | kind = PathKind::Super; | ||
48 | break; | ||
49 | } | ||
50 | } | ||
51 | path = match qualifier(path) { | ||
52 | Some(it) => it, | ||
53 | None => break, | ||
54 | }; | ||
55 | } | ||
56 | segments.reverse(); | ||
57 | return Some(Path { kind, segments }); | ||
58 | |||
59 | fn qualifier(path: ast::Path) -> Option<ast::Path> { | ||
60 | if let Some(q) = path.qualifier() { | ||
61 | return Some(q); | ||
62 | } | ||
63 | // TODO: this bottom up traversal is not too precise. | ||
64 | // Should we handle do a top-down analysiss, recording results? | ||
65 | let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?; | ||
66 | let use_tree = use_tree_list.parent_use_tree(); | ||
67 | use_tree.path() | ||
68 | } | ||
69 | } | ||
70 | |||
71 | /// `true` is this path is a single identifier, like `foo` | ||
72 | pub(crate) fn is_ident(&self) -> bool { | ||
73 | self.kind == PathKind::Plain && self.segments.len() == 1 | ||
74 | } | ||
28 | } | 75 | } |
29 | 76 | ||
30 | fn expand_use_tree( | 77 | fn expand_use_tree( |
@@ -68,7 +115,7 @@ fn convert_path(prefix: Option<Path>, path: ast::Path) -> Option<Path> { | |||
68 | let res = match segment.kind()? { | 115 | let res = match segment.kind()? { |
69 | ast::PathSegmentKind::Name(name) => { | 116 | ast::PathSegmentKind::Name(name) => { |
70 | let mut res = prefix.unwrap_or_else(|| Path { | 117 | let mut res = prefix.unwrap_or_else(|| Path { |
71 | kind: PathKind::Abs, | 118 | kind: PathKind::Plain, |
72 | segments: Vec::with_capacity(1), | 119 | segments: Vec::with_capacity(1), |
73 | }); | 120 | }); |
74 | res.segments.push(name.text()); | 121 | res.segments.push(name.text()); |