diff options
Diffstat (limited to 'crates/libanalysis/src/imp.rs')
-rw-r--r-- | crates/libanalysis/src/imp.rs | 124 |
1 files changed, 55 insertions, 69 deletions
diff --git a/crates/libanalysis/src/imp.rs b/crates/libanalysis/src/imp.rs index 3e65ee14a..8734813f4 100644 --- a/crates/libanalysis/src/imp.rs +++ b/crates/libanalysis/src/imp.rs | |||
@@ -18,8 +18,8 @@ use libsyntax2::{ | |||
18 | use { | 18 | use { |
19 | FileId, FileResolver, Query, Diagnostic, SourceChange, SourceFileEdit, Position, FileSystemEdit, | 19 | FileId, FileResolver, Query, Diagnostic, SourceChange, SourceFileEdit, Position, FileSystemEdit, |
20 | JobToken, CrateGraph, CrateId, | 20 | JobToken, CrateGraph, CrateId, |
21 | module_map::{ModuleMap, Problem}, | ||
22 | roots::{SourceRoot, ReadonlySourceRoot, WritableSourceRoot}, | 21 | roots::{SourceRoot, ReadonlySourceRoot, WritableSourceRoot}, |
22 | descriptors::{ModuleTreeDescriptor, Problem}, | ||
23 | }; | 23 | }; |
24 | 24 | ||
25 | 25 | ||
@@ -148,25 +148,24 @@ impl AnalysisImpl { | |||
148 | } | 148 | } |
149 | pub fn parent_module(&self, file_id: FileId) -> Vec<(FileId, FileSymbol)> { | 149 | pub fn parent_module(&self, file_id: FileId) -> Vec<(FileId, FileSymbol)> { |
150 | let root = self.root(file_id); | 150 | let root = self.root(file_id); |
151 | let module_map = root.module_map(); | 151 | let module_tree = root.module_tree(); |
152 | let id = module_map.file2module(file_id); | 152 | module_tree.parent_modules(file_id) |
153 | module_map | 153 | .iter() |
154 | .parent_modules(id, &|file_id| root.syntax(file_id)) | 154 | .map(|link| { |
155 | .into_iter() | 155 | let file_id = link.owner(&module_tree); |
156 | .map(|(id, name, node)| { | 156 | let syntax = root.syntax(file_id); |
157 | let id = module_map.module2file(id); | 157 | let decl = link.bind_source(&module_tree, syntax.ast()); |
158 | let sym = FileSymbol { | 158 | let sym = FileSymbol { |
159 | name, | 159 | name: link.name(&module_tree), |
160 | node_range: node.range(), | 160 | node_range: decl.syntax().range(), |
161 | kind: MODULE, | 161 | kind: MODULE, |
162 | }; | 162 | }; |
163 | (id, sym) | 163 | (file_id, sym) |
164 | }) | 164 | }) |
165 | .collect() | 165 | .collect() |
166 | } | 166 | } |
167 | |||
168 | pub fn crate_for(&self, file_id: FileId) -> Vec<CrateId> { | 167 | pub fn crate_for(&self, file_id: FileId) -> Vec<CrateId> { |
169 | let module_map = self.root(file_id).module_map(); | 168 | let module_tree = self.root(file_id).module_tree(); |
170 | let crate_graph = &self.data.crate_graph; | 169 | let crate_graph = &self.data.crate_graph; |
171 | let mut res = Vec::new(); | 170 | let mut res = Vec::new(); |
172 | let mut work = VecDeque::new(); | 171 | let mut work = VecDeque::new(); |
@@ -177,11 +176,10 @@ impl AnalysisImpl { | |||
177 | res.push(crate_id); | 176 | res.push(crate_id); |
178 | continue; | 177 | continue; |
179 | } | 178 | } |
180 | let mid = module_map.file2module(id); | 179 | let parents = module_tree |
181 | let parents = module_map | 180 | .parent_modules(id) |
182 | .parent_module_ids(mid, &|file_id| self.file_syntax(file_id)) | ||
183 | .into_iter() | 181 | .into_iter() |
184 | .map(|id| module_map.module2file(id)) | 182 | .map(|link| link.owner(&module_tree)) |
185 | .filter(|&id| visited.insert(id)); | 183 | .filter(|&id| visited.insert(id)); |
186 | work.extend(parents); | 184 | work.extend(parents); |
187 | } | 185 | } |
@@ -197,7 +195,7 @@ impl AnalysisImpl { | |||
197 | token: &JobToken, | 195 | token: &JobToken, |
198 | ) -> Vec<(FileId, FileSymbol)> { | 196 | ) -> Vec<(FileId, FileSymbol)> { |
199 | let root = self.root(file_id); | 197 | let root = self.root(file_id); |
200 | let module_map = root.module_map(); | 198 | let module_tree = root.module_tree(); |
201 | let file = root.syntax(file_id); | 199 | let file = root.syntax(file_id); |
202 | let syntax = file.syntax(); | 200 | let syntax = file.syntax(); |
203 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) { | 201 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) { |
@@ -206,7 +204,7 @@ impl AnalysisImpl { | |||
206 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, offset) { | 204 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, offset) { |
207 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { | 205 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { |
208 | if module.has_semi() { | 206 | if module.has_semi() { |
209 | let file_ids = self.resolve_module(module_map, file_id, module); | 207 | let file_ids = self.resolve_module(&*module_tree, file_id, module); |
210 | 208 | ||
211 | let res = file_ids.into_iter().map(|id| { | 209 | let res = file_ids.into_iter().map(|id| { |
212 | let name = module.name() | 210 | let name = module.name() |
@@ -229,7 +227,7 @@ impl AnalysisImpl { | |||
229 | 227 | ||
230 | pub fn diagnostics(&self, file_id: FileId) -> Vec<Diagnostic> { | 228 | pub fn diagnostics(&self, file_id: FileId) -> Vec<Diagnostic> { |
231 | let root = self.root(file_id); | 229 | let root = self.root(file_id); |
232 | let module_map = root.module_map(); | 230 | let module_tree = root.module_tree(); |
233 | let syntax = root.syntax(file_id); | 231 | let syntax = root.syntax(file_id); |
234 | 232 | ||
235 | let mut res = libeditor::diagnostics(&syntax) | 233 | let mut res = libeditor::diagnostics(&syntax) |
@@ -237,47 +235,43 @@ impl AnalysisImpl { | |||
237 | .map(|d| Diagnostic { range: d.range, message: d.msg, fix: None }) | 235 | .map(|d| Diagnostic { range: d.range, message: d.msg, fix: None }) |
238 | .collect::<Vec<_>>(); | 236 | .collect::<Vec<_>>(); |
239 | 237 | ||
240 | module_map.problems( | 238 | for (name_node, problem) in module_tree.problems(file_id, syntax.ast()) { |
241 | file_id, | 239 | let diag = match problem { |
242 | &|file_id| self.file_syntax(file_id), | 240 | Problem::UnresolvedModule { candidate } => { |
243 | |name_node, problem| { | 241 | let create_file = FileSystemEdit::CreateFile { |
244 | let diag = match problem { | 242 | anchor: file_id, |
245 | Problem::UnresolvedModule { candidate } => { | 243 | path: candidate.clone(), |
246 | let create_file = FileSystemEdit::CreateFile { | 244 | }; |
247 | anchor: file_id, | 245 | let fix = SourceChange { |
248 | path: candidate.clone(), | 246 | label: "create module".to_string(), |
249 | }; | 247 | source_file_edits: Vec::new(), |
250 | let fix = SourceChange { | 248 | file_system_edits: vec![create_file], |
251 | label: "create module".to_string(), | 249 | cursor_position: None, |
252 | source_file_edits: Vec::new(), | 250 | }; |
253 | file_system_edits: vec![create_file], | 251 | Diagnostic { |
254 | cursor_position: None, | 252 | range: name_node.syntax().range(), |
255 | }; | 253 | message: "unresolved module".to_string(), |
256 | Diagnostic { | 254 | fix: Some(fix), |
257 | range: name_node.syntax().range(), | ||
258 | message: "unresolved module".to_string(), | ||
259 | fix: Some(fix), | ||
260 | } | ||
261 | } | 255 | } |
262 | Problem::NotDirOwner { move_to, candidate } => { | 256 | } |
263 | let move_file = FileSystemEdit::MoveFile { file: file_id, path: move_to.clone() }; | 257 | Problem::NotDirOwner { move_to, candidate } => { |
264 | let create_file = FileSystemEdit::CreateFile { anchor: file_id, path: move_to.join(candidate) }; | 258 | let move_file = FileSystemEdit::MoveFile { file: file_id, path: move_to.clone() }; |
265 | let fix = SourceChange { | 259 | let create_file = FileSystemEdit::CreateFile { anchor: file_id, path: move_to.join(candidate) }; |
266 | label: "move file and create module".to_string(), | 260 | let fix = SourceChange { |
267 | source_file_edits: Vec::new(), | 261 | label: "move file and create module".to_string(), |
268 | file_system_edits: vec![move_file, create_file], | 262 | source_file_edits: Vec::new(), |
269 | cursor_position: None, | 263 | file_system_edits: vec![move_file, create_file], |
270 | }; | 264 | cursor_position: None, |
271 | Diagnostic { | 265 | }; |
272 | range: name_node.syntax().range(), | 266 | Diagnostic { |
273 | message: "can't declare module at this location".to_string(), | 267 | range: name_node.syntax().range(), |
274 | fix: Some(fix), | 268 | message: "can't declare module at this location".to_string(), |
275 | } | 269 | fix: Some(fix), |
276 | } | 270 | } |
277 | }; | 271 | } |
278 | res.push(diag) | 272 | }; |
279 | } | 273 | res.push(diag) |
280 | ); | 274 | } |
281 | res | 275 | res |
282 | } | 276 | } |
283 | 277 | ||
@@ -307,20 +301,12 @@ impl AnalysisImpl { | |||
307 | self.world_symbols(query, token) | 301 | self.world_symbols(query, token) |
308 | } | 302 | } |
309 | 303 | ||
310 | fn resolve_module(&self, module_map: &ModuleMap, file_id: FileId, module: ast::Module) -> Vec<FileId> { | 304 | fn resolve_module(&self, module_tree: &ModuleTreeDescriptor, file_id: FileId, module: ast::Module) -> Vec<FileId> { |
311 | let name = match module.name() { | 305 | let name = match module.name() { |
312 | Some(name) => name.text(), | 306 | Some(name) => name.text(), |
313 | None => return Vec::new(), | 307 | None => return Vec::new(), |
314 | }; | 308 | }; |
315 | let id = module_map.file2module(file_id); | 309 | module_tree.child_module_by_name(file_id, name.as_str()) |
316 | module_map | ||
317 | .child_module_by_name( | ||
318 | id, name.as_str(), | ||
319 | &|file_id| self.file_syntax(file_id), | ||
320 | ) | ||
321 | .into_iter() | ||
322 | .map(|id| module_map.module2file(id)) | ||
323 | .collect() | ||
324 | } | 310 | } |
325 | 311 | ||
326 | fn reindex(&self) { | 312 | fn reindex(&self) { |