diff options
-rw-r--r-- | crates/ra_analysis/src/completion/mod.rs | 5 | ||||
-rw-r--r-- | crates/ra_analysis/src/completion/reference_completion.rs | 23 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/mod.rs | 26 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/mod.rs | 46 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/nameres.rs | 11 | ||||
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 10 | ||||
-rw-r--r-- | crates/ra_analysis/src/lib.rs | 9 |
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 | ||
73 | pub(crate) enum Def { | ||
74 | Module(ModuleDescriptor), | ||
75 | Item, | ||
76 | } | ||
77 | |||
78 | impl 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)] |
71 | pub struct ReferenceDescriptor { | 93 | pub 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 | ||
22 | pub(crate) use self::nameres::ModuleScope; | 23 | pub(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)] |
105 | pub(crate) struct ModuleScope { | 105 | pub(crate) struct ModuleScope { |
106 | pub(crate) items: FxHashMap<SmolStr, Resolution>, | 106 | items: FxHashMap<SmolStr, Resolution>, |
107 | } | ||
108 | |||
109 | impl 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; | |||
9 | extern crate rustc_hash; | 9 | extern crate rustc_hash; |
10 | extern crate salsa; | 10 | extern crate salsa; |
11 | 11 | ||
12 | macro_rules! ctry { | ||
13 | ($expr:expr) => { | ||
14 | match $expr { | ||
15 | None => return Ok(None), | ||
16 | Some(it) => it, | ||
17 | } | ||
18 | }; | ||
19 | } | ||
20 | |||
12 | mod arena; | 21 | mod arena; |
13 | mod db; | 22 | mod db; |
14 | mod loc2id; | 23 | mod loc2id; |