aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/descriptors
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-11-21 14:51:02 +0000
committerAleksey Kladov <[email protected]>2018-11-21 14:51:02 +0000
commit11f19b784923ac701bc6fc39a6aea712f0091bf7 (patch)
tree6a5b5ba2543bc52d10501d41a8514bae68b78c36 /crates/ra_analysis/src/descriptors
parent5a87a24f8288d905428db755c7ea806640b6ac1d (diff)
name res uses paths
Diffstat (limited to 'crates/ra_analysis/src/descriptors')
-rw-r--r--crates/ra_analysis/src/descriptors/mod.rs2
-rw-r--r--crates/ra_analysis/src/descriptors/module/nameres.rs4
-rw-r--r--crates/ra_analysis/src/descriptors/path.rs51
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;
5use std::sync::Arc; 5use std::sync::Arc;
6 6
7use ra_syntax::{ 7use 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
24use ra_syntax::{ 24use ra_syntax::{
25 SmolStr, SyntaxKind::{self, *}, 25 SmolStr, SyntaxKind::{self, *},
26 ast::{self, AstNode, ModuleItemOwner} 26 ast::{self, ModuleItemOwner}
27}; 27};
28 28
29use crate::{ 29use 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)]
12pub(crate) enum PathKind { 12pub(crate) enum PathKind {
13 Abs, 13 Plain,
14 Self_, 14 Self_,
15 Super, 15 Super,
16 Crate, 16 Crate,
17} 17}
18 18
19impl Path { 19impl 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
30fn expand_use_tree( 77fn 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());