aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2018-11-27 16:56:38 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2018-11-27 16:56:38 +0000
commit9f08341aa486ea59cb488635f19e960523568fb8 (patch)
tree160b6aecfabb2f7dac111763b35b6f52ba6ff25b /crates/ra_analysis
parent6bb06addf8d5100cd1125c40d3dfa5f7613b42c1 (diff)
parent192e2bbb0e5c772d43ec61d36de56a0f7062610e (diff)
Merge #246
246: Resolve path r=matklad a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_analysis')
-rw-r--r--crates/ra_analysis/src/completion/mod.rs5
-rw-r--r--crates/ra_analysis/src/completion/reference_completion.rs23
-rw-r--r--crates/ra_analysis/src/descriptors/mod.rs26
-rw-r--r--crates/ra_analysis/src/descriptors/module/mod.rs46
-rw-r--r--crates/ra_analysis/src/descriptors/module/nameres.rs11
-rw-r--r--crates/ra_analysis/src/imp.rs10
-rw-r--r--crates/ra_analysis/src/lib.rs9
7 files changed, 98 insertions, 32 deletions
diff --git a/crates/ra_analysis/src/completion/mod.rs b/crates/ra_analysis/src/completion/mod.rs
index c7717ab61..5ef278127 100644
--- a/crates/ra_analysis/src/completion/mod.rs
+++ b/crates/ra_analysis/src/completion/mod.rs
@@ -38,10 +38,7 @@ pub(crate) fn completions(
38 original_file.reparse(&edit) 38 original_file.reparse(&edit)
39 }; 39 };
40 40
41 let module = match ModuleDescriptor::guess_from_position(db, position)? { 41 let module = ctry!(ModuleDescriptor::guess_from_position(db, position)?);
42 None => return Ok(None),
43 Some(it) => it,
44 };
45 42
46 let mut res = Vec::new(); 43 let mut res = Vec::new();
47 let mut has_completions = false; 44 let mut has_completions = false;
diff --git a/crates/ra_analysis/src/completion/reference_completion.rs b/crates/ra_analysis/src/completion/reference_completion.rs
index 1faa70a18..858b52e76 100644
--- a/crates/ra_analysis/src/completion/reference_completion.rs
+++ b/crates/ra_analysis/src/completion/reference_completion.rs
@@ -13,6 +13,7 @@ use crate::{
13 descriptors::{ 13 descriptors::{
14 module::{ModuleDescriptor}, 14 module::{ModuleDescriptor},
15 function::FnScopes, 15 function::FnScopes,
16 Def,
16 Path, 17 Path,
17 }, 18 },
18 Cancelable 19 Cancelable
@@ -42,8 +43,7 @@ pub(super) fn completions(
42 let module_scope = module.scope(db)?; 43 let module_scope = module.scope(db)?;
43 acc.extend( 44 acc.extend(
44 module_scope 45 module_scope
45 .items 46 .entries()
46 .iter()
47 .filter(|(_name, res)| { 47 .filter(|(_name, res)| {
48 // Don't expose this item 48 // Don't expose this item
49 match res.import { 49 match res.import {
@@ -157,19 +157,20 @@ fn complete_path(
157 return Ok(()); 157 return Ok(());
158 } 158 }
159 path.segments.pop(); 159 path.segments.pop();
160 let target_module = match module.resolve_path(path) { 160 let def_id = match module.resolve_path(db, path)? {
161 None => return Ok(()), 161 None => return Ok(()),
162 Some(it) => it, 162 Some(it) => it,
163 }; 163 };
164 let target_module = match def_id.resolve(db)? {
165 Def::Module(it) => it,
166 Def::Item => return Ok(()),
167 };
164 let module_scope = target_module.scope(db)?; 168 let module_scope = target_module.scope(db)?;
165 let completions = module_scope 169 let completions = module_scope.entries().map(|(name, _res)| CompletionItem {
166 .items 170 label: name.to_string(),
167 .iter() 171 lookup: None,
168 .map(|(name, _res)| CompletionItem { 172 snippet: None,
169 label: name.to_string(), 173 });
170 lookup: None,
171 snippet: None,
172 });
173 acc.extend(completions); 174 acc.extend(completions);
174 Ok(()) 175 Ok(())
175} 176}
diff --git a/crates/ra_analysis/src/descriptors/mod.rs b/crates/ra_analysis/src/descriptors/mod.rs
index 98094d9ee..7a1bcf447 100644
--- a/crates/ra_analysis/src/descriptors/mod.rs
+++ b/crates/ra_analysis/src/descriptors/mod.rs
@@ -13,9 +13,12 @@ use crate::{
13 FileId, 13 FileId,
14 db::SyntaxDatabase, 14 db::SyntaxDatabase,
15 descriptors::function::{resolve_local_name, FnId, FnScopes}, 15 descriptors::function::{resolve_local_name, FnId, FnScopes},
16 descriptors::module::{ModuleId, ModuleTree, ModuleSource, nameres::{ItemMap, InputModuleItems, FileItems}}, 16 descriptors::module::{
17 ModuleId, ModuleTree, ModuleSource, ModuleDescriptor,
18 nameres::{ItemMap, InputModuleItems, FileItems}
19 },
17 input::SourceRootId, 20 input::SourceRootId,
18 loc2id::IdDatabase, 21 loc2id::{IdDatabase, DefId, DefLoc},
19 syntax_ptr::LocalSyntaxPtr, 22 syntax_ptr::LocalSyntaxPtr,
20 Cancelable, 23 Cancelable,
21}; 24};
@@ -67,6 +70,25 @@ salsa::query_group! {
67 } 70 }
68} 71}
69 72
73pub(crate) enum Def {
74 Module(ModuleDescriptor),
75 Item,
76}
77
78impl DefId {
79 pub(crate) fn resolve(self, db: &impl DescriptorDatabase) -> Cancelable<Def> {
80 let loc = db.id_maps().def_loc(self);
81 let res = match loc {
82 DefLoc::Module { id, source_root } => {
83 let descr = ModuleDescriptor::new(db, source_root, id)?;
84 Def::Module(descr)
85 }
86 DefLoc::Item { .. } => Def::Item,
87 };
88 Ok(res)
89 }
90}
91
70#[derive(Debug)] 92#[derive(Debug)]
71pub struct ReferenceDescriptor { 93pub struct ReferenceDescriptor {
72 pub range: TextRange, 94 pub range: TextRange,
diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs
index a6eaec178..78911d5d9 100644
--- a/crates/ra_analysis/src/descriptors/module/mod.rs
+++ b/crates/ra_analysis/src/descriptors/module/mod.rs
@@ -17,6 +17,7 @@ use crate::{
17 descriptors::{Path, PathKind, DescriptorDatabase}, 17 descriptors::{Path, PathKind, DescriptorDatabase},
18 input::SourceRootId, 18 input::SourceRootId,
19 arena::{Arena, Id}, 19 arena::{Arena, Id},
20 loc2id::{DefLoc, DefId},
20}; 21};
21 22
22pub(crate) use self::nameres::ModuleScope; 23pub(crate) use self::nameres::ModuleScope;
@@ -76,6 +77,20 @@ impl ModuleDescriptor {
76 Ok(res) 77 Ok(res)
77 } 78 }
78 79
80 pub(super) fn new(
81 db: &impl DescriptorDatabase,
82 source_root_id: SourceRootId,
83 module_id: ModuleId,
84 ) -> Cancelable<ModuleDescriptor> {
85 let module_tree = db._module_tree(source_root_id)?;
86 let res = ModuleDescriptor {
87 tree: module_tree,
88 source_root_id,
89 module_id,
90 };
91 Ok(res)
92 }
93
79 /// Returns `mod foo;` or `mod foo {}` node whihc declared this module. 94 /// Returns `mod foo;` or `mod foo {}` node whihc declared this module.
80 /// Returns `None` for the root module 95 /// Returns `None` for the root module
81 pub fn parent_link_source( 96 pub fn parent_link_source(
@@ -117,6 +132,14 @@ impl ModuleDescriptor {
117 Some(link.name(&self.tree)) 132 Some(link.name(&self.tree))
118 } 133 }
119 134
135 pub fn def_id(&self, db: &impl DescriptorDatabase) -> DefId {
136 let def_loc = DefLoc::Module {
137 id: self.module_id,
138 source_root: self.source_root_id,
139 };
140 db.id_maps().def_id(def_loc)
141 }
142
120 /// Finds a child module with the specified name. 143 /// Finds a child module with the specified name.
121 pub fn child(&self, name: &str) -> Option<ModuleDescriptor> { 144 pub fn child(&self, name: &str) -> Option<ModuleDescriptor> {
122 let child_id = self.module_id.child(&self.tree, name)?; 145 let child_id = self.module_id.child(&self.tree, name)?;
@@ -133,17 +156,28 @@ impl ModuleDescriptor {
133 Ok(res) 156 Ok(res)
134 } 157 }
135 158
136 pub(crate) fn resolve_path(&self, path: Path) -> Option<ModuleDescriptor> { 159 pub(crate) fn resolve_path(
160 &self,
161 db: &impl DescriptorDatabase,
162 path: Path,
163 ) -> Cancelable<Option<DefId>> {
137 let mut curr = match path.kind { 164 let mut curr = match path.kind {
138 PathKind::Crate => self.crate_root(), 165 PathKind::Crate => self.crate_root(),
139 PathKind::Self_ | PathKind::Plain => self.clone(), 166 PathKind::Self_ | PathKind::Plain => self.clone(),
140 PathKind::Super => self.parent()?, 167 PathKind::Super => ctry!(self.parent()),
141 }; 168 }
169 .def_id(db);
170
142 let segments = path.segments; 171 let segments = path.segments;
143 for name in segments { 172 for name in segments.iter() {
144 curr = curr.child(&name)?; 173 let module = match db.id_maps().def_loc(curr) {
174 DefLoc::Module { id, source_root } => ModuleDescriptor::new(db, source_root, id)?,
175 _ => return Ok(None),
176 };
177 let scope = module.scope(db)?;
178 curr = ctry!(ctry!(scope.get(&name)).def_id);
145 } 179 }
146 Some(curr) 180 Ok(Some(curr))
147 } 181 }
148 182
149 pub fn problems(&self, db: &impl DescriptorDatabase) -> Vec<(SyntaxNode, Problem)> { 183 pub fn problems(&self, db: &impl DescriptorDatabase) -> Vec<(SyntaxNode, Problem)> {
diff --git a/crates/ra_analysis/src/descriptors/module/nameres.rs b/crates/ra_analysis/src/descriptors/module/nameres.rs
index d347a69b0..d2964f67f 100644
--- a/crates/ra_analysis/src/descriptors/module/nameres.rs
+++ b/crates/ra_analysis/src/descriptors/module/nameres.rs
@@ -103,7 +103,16 @@ pub(crate) struct ItemMap {
103 103
104#[derive(Debug, Default, PartialEq, Eq, Clone)] 104#[derive(Debug, Default, PartialEq, Eq, Clone)]
105pub(crate) struct ModuleScope { 105pub(crate) struct ModuleScope {
106 pub(crate) items: FxHashMap<SmolStr, Resolution>, 106 items: FxHashMap<SmolStr, Resolution>,
107}
108
109impl ModuleScope {
110 pub(crate) fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a SmolStr, &Resolution)> + 'a {
111 self.items.iter()
112 }
113 pub(crate) fn get(&self, name: &SmolStr) -> Option<&Resolution> {
114 self.items.get(name)
115 }
107} 116}
108 117
109/// A set of items and imports declared inside a module, without relation to 118/// A set of items and imports declared inside a module, without relation to
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index ad6b52371..8a41b3152 100644
--- a/crates/ra_analysis/src/imp.rs
+++ b/crates/ra_analysis/src/imp.rs
@@ -450,14 +450,8 @@ impl AnalysisImpl {
450 let syntax = file.syntax(); 450 let syntax = file.syntax();
451 451
452 // Find the calling expression and it's NameRef 452 // Find the calling expression and it's NameRef
453 let calling_node = match FnCallNode::with_node(syntax, position.offset) { 453 let calling_node = ctry!(FnCallNode::with_node(syntax, position.offset));
454 Some(node) => node, 454 let name_ref = ctry!(calling_node.name_ref());
455 None => return Ok(None),
456 };
457 let name_ref = match calling_node.name_ref() {
458 Some(name) => name,
459 None => return Ok(None),
460 };
461 455
462 // Resolve the function's NameRef (NOTE: this isn't entirely accurate). 456 // Resolve the function's NameRef (NOTE: this isn't entirely accurate).
463 let file_symbols = self.index_resolve(name_ref)?; 457 let file_symbols = self.index_resolve(name_ref)?;
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs
index cedbd1fc8..0fbfd8a40 100644
--- a/crates/ra_analysis/src/lib.rs
+++ b/crates/ra_analysis/src/lib.rs
@@ -9,6 +9,15 @@ extern crate relative_path;
9extern crate rustc_hash; 9extern crate rustc_hash;
10extern crate salsa; 10extern crate salsa;
11 11
12macro_rules! ctry {
13 ($expr:expr) => {
14 match $expr {
15 None => return Ok(None),
16 Some(it) => it,
17 }
18 };
19}
20
12mod arena; 21mod arena;
13mod db; 22mod db;
14mod loc2id; 23mod loc2id;