aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/completion
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/completion
parent5a87a24f8288d905428db755c7ea806640b6ac1d (diff)
name res uses paths
Diffstat (limited to 'crates/ra_analysis/src/completion')
-rw-r--r--crates/ra_analysis/src/completion/reference_completion.rs64
1 files changed, 22 insertions, 42 deletions
diff --git a/crates/ra_analysis/src/completion/reference_completion.rs b/crates/ra_analysis/src/completion/reference_completion.rs
index 84383b547..a96570415 100644
--- a/crates/ra_analysis/src/completion/reference_completion.rs
+++ b/crates/ra_analysis/src/completion/reference_completion.rs
@@ -10,8 +10,11 @@ use ra_syntax::{
10use crate::{ 10use crate::{
11 db::RootDatabase, 11 db::RootDatabase,
12 completion::CompletionItem, 12 completion::CompletionItem,
13 descriptors::module::{ModuleDescriptor}, 13 descriptors::{
14 descriptors::function::FnScopes, 14 module::{ModuleDescriptor},
15 function::FnScopes,
16 Path, PathKind,
17 },
15 Cancelable 18 Cancelable
16}; 19};
17 20
@@ -55,7 +58,7 @@ pub(super) fn completions(
55 }), 58 }),
56 ); 59 );
57 } 60 }
58 NameRefKind::CratePath(path) => complete_path(acc, db, module, path)?, 61 NameRefKind::Path(path) => complete_path(acc, db, module, path)?,
59 NameRefKind::BareIdentInMod => { 62 NameRefKind::BareIdentInMod => {
60 let name_range = name_ref.syntax().range(); 63 let name_range = name_ref.syntax().range();
61 let top_node = name_ref 64 let top_node = name_ref
@@ -79,8 +82,8 @@ enum NameRefKind<'a> {
79 LocalRef { 82 LocalRef {
80 enclosing_fn: Option<ast::FnDef<'a>>, 83 enclosing_fn: Option<ast::FnDef<'a>>,
81 }, 84 },
82 /// NameRef is the last segment in crate:: path 85 /// NameRef is the last segment in some path
83 CratePath(Vec<ast::NameRef<'a>>), 86 Path(Path),
84 /// NameRef is bare identifier at the module's root. 87 /// NameRef is bare identifier at the module's root.
85 /// Used for keyword completion 88 /// Used for keyword completion
86 BareIdentInMod, 89 BareIdentInMod,
@@ -102,8 +105,10 @@ fn classify_name_ref(name_ref: ast::NameRef) -> Option<NameRefKind> {
102 let parent = name_ref.syntax().parent()?; 105 let parent = name_ref.syntax().parent()?;
103 if let Some(segment) = ast::PathSegment::cast(parent) { 106 if let Some(segment) = ast::PathSegment::cast(parent) {
104 let path = segment.parent_path(); 107 let path = segment.parent_path();
105 if let Some(crate_path) = crate_path(path) { 108 if let Some(path) = Path::from_ast(path) {
106 return Some(NameRefKind::CratePath(crate_path)); 109 if !path.is_ident() {
110 return Some(NameRefKind::Path(path));
111 }
107 } 112 }
108 if path.qualifier().is_none() { 113 if path.qualifier().is_none() {
109 let enclosing_fn = name_ref 114 let enclosing_fn = name_ref
@@ -117,32 +122,6 @@ fn classify_name_ref(name_ref: ast::NameRef) -> Option<NameRefKind> {
117 None 122 None
118} 123}
119 124
120fn crate_path(mut path: ast::Path) -> Option<Vec<ast::NameRef>> {
121 let mut res = Vec::new();
122 loop {
123 let segment = path.segment()?;
124 match segment.kind()? {
125 ast::PathSegmentKind::Name(name) => res.push(name),
126 ast::PathSegmentKind::CrateKw => break,
127 ast::PathSegmentKind::SelfKw | ast::PathSegmentKind::SuperKw => return None,
128 }
129 path = qualifier(path)?;
130 }
131 res.reverse();
132 return Some(res);
133
134 fn qualifier(path: ast::Path) -> Option<ast::Path> {
135 if let Some(q) = path.qualifier() {
136 return Some(q);
137 }
138 // TODO: this bottom up traversal is not too precise.
139 // Should we handle do a top-down analysiss, recording results?
140 let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?;
141 let use_tree = use_tree_list.parent_use_tree();
142 use_tree.path()
143 }
144}
145
146fn complete_fn(name_ref: ast::NameRef, scopes: &FnScopes, acc: &mut Vec<CompletionItem>) { 125fn complete_fn(name_ref: ast::NameRef, scopes: &FnScopes, acc: &mut Vec<CompletionItem>) {
147 let mut shadowed = FxHashSet::default(); 126 let mut shadowed = FxHashSet::default();
148 acc.extend( 127 acc.extend(
@@ -169,9 +148,9 @@ fn complete_path(
169 acc: &mut Vec<CompletionItem>, 148 acc: &mut Vec<CompletionItem>,
170 db: &RootDatabase, 149 db: &RootDatabase,
171 module: &ModuleDescriptor, 150 module: &ModuleDescriptor,
172 crate_path: Vec<ast::NameRef>, 151 path: Path,
173) -> Cancelable<()> { 152) -> Cancelable<()> {
174 let target_module = match find_target_module(module, crate_path) { 153 let target_module = match find_target_module(module, path) {
175 None => return Ok(()), 154 None => return Ok(()),
176 Some(it) => it, 155 Some(it) => it,
177 }; 156 };
@@ -188,14 +167,15 @@ fn complete_path(
188 Ok(()) 167 Ok(())
189} 168}
190 169
191fn find_target_module( 170fn find_target_module(module: &ModuleDescriptor, path: Path) -> Option<ModuleDescriptor> {
192 module: &ModuleDescriptor, 171 if path.kind != PathKind::Crate {
193 mut crate_path: Vec<ast::NameRef>, 172 return None;
194) -> Option<ModuleDescriptor> { 173 }
195 crate_path.pop(); 174 let mut segments = path.segments;
175 segments.pop();
196 let mut target_module = module.crate_root(); 176 let mut target_module = module.crate_root();
197 for name in crate_path { 177 for name in segments {
198 target_module = target_module.child(name.text().as_str())?; 178 target_module = target_module.child(&name)?;
199 } 179 }
200 Some(target_module) 180 Some(target_module)
201} 181}