aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/import_map.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/import_map.rs')
-rw-r--r--crates/ra_hir_def/src/import_map.rs45
1 files changed, 20 insertions, 25 deletions
diff --git a/crates/ra_hir_def/src/import_map.rs b/crates/ra_hir_def/src/import_map.rs
index e9b2fe26e..f2e4ca2db 100644
--- a/crates/ra_hir_def/src/import_map.rs
+++ b/crates/ra_hir_def/src/import_map.rs
@@ -1,10 +1,8 @@
1//! A map of all publicly exported items in a crate. 1//! A map of all publicly exported items in a crate.
2 2
3use std::cmp::Ordering; 3use std::{cmp::Ordering, collections::hash_map::Entry, fmt, sync::Arc};
4use std::{collections::hash_map::Entry, fmt, sync::Arc};
5 4
6use fst::{self, Streamer}; 5use fst::{self, Streamer};
7use itertools::Itertools;
8use ra_db::CrateId; 6use ra_db::CrateId;
9use rustc_hash::FxHashMap; 7use rustc_hash::FxHashMap;
10 8
@@ -118,7 +116,7 @@ impl ImportMap {
118 let start = last_batch_start; 116 let start = last_batch_start;
119 last_batch_start = idx + 1; 117 last_batch_start = idx + 1;
120 118
121 let key: String = fst_path(&importables[start].1).collect(); 119 let key = fst_path(&importables[start].1);
122 120
123 builder.insert(key, start as u64).unwrap(); 121 builder.insert(key, start as u64).unwrap();
124 } 122 }
@@ -137,7 +135,8 @@ impl ImportMap {
137 135
138impl PartialEq for ImportMap { 136impl PartialEq for ImportMap {
139 fn eq(&self, other: &Self) -> bool { 137 fn eq(&self, other: &Self) -> bool {
140 self.importables == other.importables 138 // `fst` and `importables` are built from `map`, so we don't need to compare them.
139 self.map == other.map
141 } 140 }
142} 141}
143 142
@@ -163,18 +162,16 @@ impl fmt::Debug for ImportMap {
163 } 162 }
164} 163}
165 164
166fn fst_path(path: &ModPath) -> impl Iterator<Item = char> + '_ { 165fn fst_path(path: &ModPath) -> String {
167 path.segments 166 let mut s = path.to_string();
168 .iter() 167 s.make_ascii_lowercase();
169 .map(|name| name.as_text().unwrap()) 168 s
170 .intersperse("::")
171 .flat_map(|s| s.chars().map(|c| c.to_ascii_lowercase()))
172} 169}
173 170
174fn cmp((_, lhs): &(&ItemInNs, &ModPath), (_, rhs): &(&ItemInNs, &ModPath)) -> Ordering { 171fn cmp((_, lhs): &(&ItemInNs, &ModPath), (_, rhs): &(&ItemInNs, &ModPath)) -> Ordering {
175 let lhs_chars = fst_path(lhs); 172 let lhs_str = fst_path(lhs);
176 let rhs_chars = fst_path(rhs); 173 let rhs_str = fst_path(rhs);
177 lhs_chars.cmp(rhs_chars) 174 lhs_str.cmp(&rhs_str)
178} 175}
179 176
180#[derive(Debug)] 177#[derive(Debug)]
@@ -184,8 +181,8 @@ pub struct Query {
184} 181}
185 182
186impl Query { 183impl Query {
187 pub fn new(query: impl AsRef<str>) -> Self { 184 pub fn new(query: &str) -> Self {
188 Self { query: query.as_ref().to_lowercase(), anchor_end: false } 185 Self { query: query.to_lowercase(), anchor_end: false }
189 } 186 }
190 187
191 /// Only returns items whose paths end with the (case-insensitive) query string as their last 188 /// Only returns items whose paths end with the (case-insensitive) query string as their last
@@ -197,14 +194,13 @@ impl Query {
197 194
198/// Searches dependencies of `krate` for an importable path matching `query`. 195/// Searches dependencies of `krate` for an importable path matching `query`.
199/// 196///
200/// This returns all items that could be imported from within `krate`, excluding paths inside 197/// This returns a list of items that could be imported from dependencies of `krate`.
201/// `krate` itself.
202pub fn search_dependencies<'a>( 198pub fn search_dependencies<'a>(
203 db: &'a dyn DefDatabase, 199 db: &'a dyn DefDatabase,
204 krate: CrateId, 200 krate: CrateId,
205 query: Query, 201 query: Query,
206) -> Vec<ItemInNs> { 202) -> Vec<ItemInNs> {
207 let _p = ra_prof::profile("import_map::global_search").detail(|| format!("{:?}", query)); 203 let _p = ra_prof::profile("search_dependencies").detail(|| format!("{:?}", query));
208 204
209 let graph = db.crate_graph(); 205 let graph = db.crate_graph();
210 let import_maps: Vec<_> = 206 let import_maps: Vec<_> =
@@ -239,7 +235,7 @@ pub fn search_dependencies<'a>(
239 // `importables` whose paths match `path`. 235 // `importables` whose paths match `path`.
240 res.extend(importables.iter().copied().take_while(|item| { 236 res.extend(importables.iter().copied().take_while(|item| {
241 let item_path = &import_map.map[item]; 237 let item_path = &import_map.map[item];
242 fst_path(item_path).eq(fst_path(path)) 238 fst_path(item_path) == fst_path(path)
243 })); 239 }));
244 } 240 }
245 } 241 }
@@ -252,6 +248,7 @@ mod tests {
252 use super::*; 248 use super::*;
253 use crate::test_db::TestDB; 249 use crate::test_db::TestDB;
254 use insta::assert_snapshot; 250 use insta::assert_snapshot;
251 use itertools::Itertools;
255 use ra_db::fixture::WithFixture; 252 use ra_db::fixture::WithFixture;
256 use ra_db::{SourceDatabase, Upcast}; 253 use ra_db::{SourceDatabase, Upcast};
257 254
@@ -259,7 +256,7 @@ mod tests {
259 let db = TestDB::with_files(ra_fixture); 256 let db = TestDB::with_files(ra_fixture);
260 let crate_graph = db.crate_graph(); 257 let crate_graph = db.crate_graph();
261 258
262 let import_maps: Vec<_> = crate_graph 259 let s = crate_graph
263 .iter() 260 .iter()
264 .filter_map(|krate| { 261 .filter_map(|krate| {
265 let cdata = &crate_graph[krate]; 262 let cdata = &crate_graph[krate];
@@ -269,9 +266,8 @@ mod tests {
269 266
270 Some(format!("{}:\n{:?}", name, map)) 267 Some(format!("{}:\n{:?}", name, map))
271 }) 268 })
272 .collect(); 269 .join("\n");
273 270 s
274 import_maps.join("\n")
275 } 271 }
276 272
277 fn search_dependencies_of(ra_fixture: &str, krate_name: &str, query: Query) -> String { 273 fn search_dependencies_of(ra_fixture: &str, krate_name: &str, query: Query) -> String {
@@ -304,7 +300,6 @@ mod tests {
304 ) 300 )
305 }) 301 })
306 }) 302 })
307 .collect::<Vec<_>>()
308 .join("\n") 303 .join("\n")
309 } 304 }
310 305