diff options
author | Aleksey Kladov <[email protected]> | 2018-11-27 13:55:56 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-11-27 15:25:35 +0000 |
commit | f4860870dae309f5287a287de0aa3a1a1b1de36b (patch) | |
tree | b487b5623db2a45f3c6cd3ae52e60b5fc90033a6 /crates/ra_analysis | |
parent | 68f66e0f446a2bd2385cfd236856f2a73bd58a3d (diff) |
scope-based resolve path
Diffstat (limited to 'crates/ra_analysis')
-rw-r--r-- | crates/ra_analysis/src/completion/reference_completion.rs | 16 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/mod.rs | 47 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/nameres.rs | 11 |
3 files changed, 53 insertions, 21 deletions
diff --git a/crates/ra_analysis/src/completion/reference_completion.rs b/crates/ra_analysis/src/completion/reference_completion.rs index 924d2440f..a0af59178 100644 --- a/crates/ra_analysis/src/completion/reference_completion.rs +++ b/crates/ra_analysis/src/completion/reference_completion.rs | |||
@@ -42,8 +42,7 @@ pub(super) fn completions( | |||
42 | let module_scope = module.scope(db)?; | 42 | let module_scope = module.scope(db)?; |
43 | acc.extend( | 43 | acc.extend( |
44 | module_scope | 44 | module_scope |
45 | .items | 45 | .entries() |
46 | .iter() | ||
47 | .filter(|(_name, res)| { | 46 | .filter(|(_name, res)| { |
48 | // Don't expose this item | 47 | // Don't expose this item |
49 | match res.import { | 48 | match res.import { |
@@ -162,14 +161,11 @@ fn complete_path( | |||
162 | Some(it) => it, | 161 | Some(it) => it, |
163 | }; | 162 | }; |
164 | let module_scope = target_module.scope(db)?; | 163 | let module_scope = target_module.scope(db)?; |
165 | let completions = module_scope | 164 | let completions = module_scope.entries().map(|(name, _res)| CompletionItem { |
166 | .items | 165 | label: name.to_string(), |
167 | .iter() | 166 | lookup: None, |
168 | .map(|(name, _res)| CompletionItem { | 167 | snippet: None, |
169 | label: name.to_string(), | 168 | }); |
170 | lookup: None, | ||
171 | snippet: None, | ||
172 | }); | ||
173 | acc.extend(completions); | 169 | acc.extend(completions); |
174 | Ok(()) | 170 | Ok(()) |
175 | } | 171 | } |
diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index 6890d8b09..51bc84bf1 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, | ||
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 | 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( |
@@ -133,25 +148,37 @@ impl ModuleDescriptor { | |||
133 | Ok(res) | 148 | Ok(res) |
134 | } | 149 | } |
135 | 150 | ||
136 | pub(crate) fn resolve_path(&self, db: &impl DescriptorDatabase, path: Path) -> Cancelable<Option<ModuleDescriptor>> { | 151 | pub(crate) fn resolve_path( |
137 | let res = match self.do_resolve_path(path) { | 152 | &self, |
138 | None => return Ok(None), | 153 | db: &impl DescriptorDatabase, |
139 | Some(it) => it, | 154 | path: Path, |
155 | ) -> Cancelable<Option<ModuleDescriptor>> { | ||
156 | macro_rules! ctry { | ||
157 | ($expr:expr) => { | ||
158 | match $expr { | ||
159 | None => return Ok(None), | ||
160 | Some(it) => it, | ||
161 | } | ||
162 | }; | ||
140 | }; | 163 | }; |
141 | Ok(Some(res)) | ||
142 | } | ||
143 | 164 | ||
144 | fn do_resolve_path(&self, path: Path) -> Option<ModuleDescriptor> { | ||
145 | let mut curr = match path.kind { | 165 | let mut curr = match path.kind { |
146 | PathKind::Crate => self.crate_root(), | 166 | PathKind::Crate => self.crate_root(), |
147 | PathKind::Self_ | PathKind::Plain => self.clone(), | 167 | PathKind::Self_ | PathKind::Plain => self.clone(), |
148 | PathKind::Super => self.parent()?, | 168 | PathKind::Super => ctry!(self.parent()), |
149 | }; | 169 | }; |
170 | |||
150 | let segments = path.segments; | 171 | let segments = path.segments; |
151 | for name in segments { | 172 | for name in segments { |
152 | curr = curr.child(&name)?; | 173 | let scope = curr.scope(db)?; |
174 | let def_id = ctry!(ctry!(scope.get(&name)).def_id); | ||
175 | curr = match db.id_maps().def_loc(def_id) { | ||
176 | DefLoc::Module { id, source_root } => ModuleDescriptor::new(db, source_root, id)?, | ||
177 | _ => return Ok(None), | ||
178 | }; | ||
153 | } | 179 | } |
154 | Some(curr) | 180 | |
181 | Ok(Some(curr)) | ||
155 | } | 182 | } |
156 | 183 | ||
157 | pub fn problems(&self, db: &impl DescriptorDatabase) -> Vec<(SyntaxNode, Problem)> { | 184 | 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 |