diff options
author | Lukas Wirth <[email protected]> | 2021-01-12 14:51:02 +0000 |
---|---|---|
committer | Lukas Wirth <[email protected]> | 2021-01-12 14:51:02 +0000 |
commit | 2c1777a2e264e58fccd5ace94b238c8a497ddbda (patch) | |
tree | e7d47c95c6bcdeecd5f321f4ca969d04ca90dff7 /crates/ide_db | |
parent | fbdb32adfc49e0d69b7fd8e44135bea59382d2cb (diff) |
Ensure uniqueness of file ids in reference search via hashmap
Diffstat (limited to 'crates/ide_db')
-rw-r--r-- | crates/ide_db/src/search.rs | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs index b8359a9b4..89a313e9b 100644 --- a/crates/ide_db/src/search.rs +++ b/crates/ide_db/src/search.rs | |||
@@ -8,7 +8,6 @@ use std::{convert::TryInto, mem}; | |||
8 | 8 | ||
9 | use base_db::{FileId, FileRange, SourceDatabaseExt}; | 9 | use base_db::{FileId, FileRange, SourceDatabaseExt}; |
10 | use hir::{DefWithBody, HasSource, Module, ModuleSource, Semantics, Visibility}; | 10 | use hir::{DefWithBody, HasSource, Module, ModuleSource, Semantics, Visibility}; |
11 | use itertools::Itertools; | ||
12 | use once_cell::unsync::Lazy; | 11 | use once_cell::unsync::Lazy; |
13 | use rustc_hash::FxHashMap; | 12 | use rustc_hash::FxHashMap; |
14 | use syntax::{ast, match_ast, AstNode, TextRange, TextSize}; | 13 | use syntax::{ast, match_ast, AstNode, TextRange, TextSize}; |
@@ -19,17 +18,37 @@ use crate::{ | |||
19 | RootDatabase, | 18 | RootDatabase, |
20 | }; | 19 | }; |
21 | 20 | ||
22 | #[derive(Debug, Clone)] | 21 | #[derive(Debug, Default, Clone)] |
23 | pub struct FileReferences { | 22 | pub struct FileReferences { |
24 | pub file_id: FileId, | 23 | pub references: FxHashMap<FileId, Vec<FileReference>>, |
25 | pub references: Vec<FileReference>, | ||
26 | } | 24 | } |
27 | 25 | ||
28 | impl FileReferences { | 26 | impl FileReferences { |
27 | pub fn is_empty(&self) -> bool { | ||
28 | self.references.is_empty() | ||
29 | } | ||
30 | |||
31 | pub fn len(&self) -> usize { | ||
32 | self.references.len() | ||
33 | } | ||
34 | |||
35 | pub fn iter(&self) -> impl Iterator<Item = (&FileId, &Vec<FileReference>)> + '_ { | ||
36 | self.references.iter() | ||
37 | } | ||
38 | |||
29 | pub fn file_ranges(&self) -> impl Iterator<Item = FileRange> + '_ { | 39 | pub fn file_ranges(&self) -> impl Iterator<Item = FileRange> + '_ { |
30 | self.references | 40 | self.references.iter().flat_map(|(&file_id, refs)| { |
31 | .iter() | 41 | refs.iter().map(move |&FileReference { range, .. }| FileRange { file_id, range }) |
32 | .map(move |&FileReference { range, .. }| FileRange { file_id: self.file_id, range }) | 42 | }) |
43 | } | ||
44 | } | ||
45 | |||
46 | impl IntoIterator for FileReferences { | ||
47 | type Item = (FileId, Vec<FileReference>); | ||
48 | type IntoIter = <FxHashMap<FileId, Vec<FileReference>> as IntoIterator>::IntoIter; | ||
49 | |||
50 | fn into_iter(self) -> Self::IntoIter { | ||
51 | self.references.into_iter() | ||
33 | } | 52 | } |
34 | } | 53 | } |
35 | 54 | ||
@@ -275,21 +294,12 @@ impl<'a> FindUsages<'a> { | |||
275 | } | 294 | } |
276 | 295 | ||
277 | /// The [`FileReferences`] returned always have unique [`FileId`]s. | 296 | /// The [`FileReferences`] returned always have unique [`FileId`]s. |
278 | pub fn all(self) -> Vec<FileReferences> { | 297 | pub fn all(self) -> FileReferences { |
279 | let mut res = <Vec<FileReferences>>::new(); | 298 | let mut res = FileReferences::default(); |
280 | self.search(&mut |file_id, reference| { | 299 | self.search(&mut |file_id, reference| { |
281 | match res.iter_mut().find(|it| it.file_id == file_id) { | 300 | res.references.entry(file_id).or_default().push(reference); |
282 | Some(file_refs) => file_refs.references.push(reference), | ||
283 | _ => res.push(FileReferences { file_id, references: vec![reference] }), | ||
284 | } | ||
285 | false | 301 | false |
286 | }); | 302 | }); |
287 | assert!(res | ||
288 | .iter() | ||
289 | .map(|refs| refs.file_id) | ||
290 | .sorted_unstable() | ||
291 | .tuple_windows::<(_, _)>() | ||
292 | .all(|(a, b)| a < b)); | ||
293 | res | 303 | res |
294 | } | 304 | } |
295 | 305 | ||